- /*---------------------------------------------------------------------------------------------------------*/
- /* */
- /* Copyright(c) 2011 Nuvoton Technology Corp. All rights reserved. */
- /* */
- /*---------------------------------------------------------------------------------------------------------*/
- #include "includes.h" //包含所需的头文件
- S_DRVRTC_TIME_DATA_T Curren_Time;
- int32_t AD_Value;
- /*************************************************************************************
- ** Function name: main
- ** Descriptions: 本函数实现:RTC功能及闹钟 (同时也包括:AD温度模块 按键模块 串口模块 定时器模块 GPIO模块 LED数码管显示模块)
- 相当一个大杂烩吧
- ** input parameters: 无
- ** output parameters: 无
- ** Returned value: 无
- *************************************************************************************/
- int main (void)
- {
- uint8_t i;
- Set_System(); //封装一些初始化模块
- printf("======RTC实验=====\n");
- while(1)
- {
- if(ID == 1)//查询是否去RTC时间
- {
- ID = 0;
- DrvRTC_Read(DRVRTC_CURRENT_TIME, &Curren_Time);
- DrvADC_StartConvert(); // 开启ADC转换
- while(DrvADC_IsConversionDone()==FALSE); // 判断ADC是否转换结束 并送串口显示
- AD_Value = DrvADC_GetConversionData(7);
- AD_Value = AD_Value*3300/4095- 730; // 将电压值转换成温度 经过校准后 确认0度为730mv左右
- AD_Value = AD_Value/-2;
- printf("当前日期为: %d年%d月%d日 星期%d\n",Curren_Time.u32Year,Curren_Time.u32cMonth,Curren_Time.u32cDay,Curren_Time.u32cDayOfWeek);
- printf("当前时间为: %d:%d:%d\n",Curren_Time.u32cHour,Curren_Time.u32cMinute,Curren_Time.u32cSecond);
- printf("当前温度为: %d度\n",AD_Value);
- }
- if(ID == 4)
- {
- ID = 0;
- for(i=0;i<14;i++)
- {
- Adjust = DATE;
- }
- RTC_Configuration();
- }
- if(ID == 5)
- {
- ID = 0;
- for(i=0;i<14;i++)
- {
- Alarm = DATE;
- }
- RTC_Configuration();
- }
- KeyCode = GetKey();
- switch(KeyCode)
- {
- case KEY1_DOWN_USER:
- {
- DrvGPIO_ClrBit(E_GPB,10); //关闭蜂鸣器
- }
- break;
- case KEY2_DOWN_USER:
- {
- DrvGPIO_SetBit(E_GPB,10); //开启蜂鸣器
- }
- break;
- default:break;
- }
- }
- }
hw_config函数- #include "includes.h" //包含所需的头文件
- /*************************************************************************************
- ** Function name: Set_System
- ** Descriptions: 封装一些初始化模块
- ** input parameters: count
- ** output parameters: 无
- ** Returned value: 无
- *************************************************************************************/
- void Set_System(void)
- {
- RCC_Configuration(); //配置系统时钟
- InitButtonVar(); //按键初始化
- GPIO_Configuration(); //配置GPIO
- USART_Configuration(); //配置USART
- ADC_Configuration(); //配置ADC
- TIMER_Configuration(); //配置TIMER
- RTC_Configuration(); //配置RTC
- }
- /*************************************************************************************
- ** Function name: RCC_Configuration
- ** Descriptions: 系统时钟源设置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void RCC_Configuration(void)
- {
- UNLOCKREG(); // 对写保护位操作时 需要一次向0x50000 0100写入 0x59,0x16,0x88,
- DrvSYS_SetOscCtrl(E_SYS_XTL12M, 1);// 与其 SYSCLK->WRCON.XTL12M_EN = 1; 等同
- // PWRCON寄存器(这些寄存器在上电复位到用户解锁定之前是锁定的)除了 BIT[6]位其他位都受写保护
- // 解除这些需要向 0x50000 0100写入 0x59,0x16,0x88,
- // 令PWRCON寄存器的BITP[0]为1(即设定12M外部晶振)
- delay_ms(100); // while (DrvSYS_GetChipClockSourceStatus(E_SYS_XTL12M) != 1);//等待外部12MHZ晶振就绪
- LOCKREG(); // 向“0x5000_0100”写入任何值,就可以重锁保护寄存器
- }
- /*************************************************************************************
- ** Function name: GPIO_Configuration
- ** Descriptions: GPIO配置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void GPIO_Configuration()
- {
- DrvGPIO_Open( E_GPB, 0, E_IO_INPUT ); //RX
- DrvGPIO_Open( E_GPB, 1, E_IO_OUTPUT ); //TX
- DrvGPIO_Open( E_GPB, 14, E_IO_INPUT ); //按键端口设置为输入
- DrvGPIO_Open( E_GPB, 15, E_IO_INPUT );
- DrvGPIO_Open( E_GPB, 10, E_IO_OUTPUT );//蜂鸣器引脚设置为输出
- DrvGPIO_ClrBit(E_GPB,10); //关闭蜂鸣器
- DrvGPIO_Open( E_GPA, 2, E_IO_OUTPUT );//数码管段选
- DrvGPIO_Open( E_GPA, 3, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 4, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 5, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 6, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 7, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 8, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPA, 9, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPC, 14, E_IO_OUTPUT );//数码管位选
- DrvGPIO_Open( E_GPC, 15, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPC, 6, E_IO_OUTPUT );
- DrvGPIO_Open( E_GPC, 7, E_IO_OUTPUT );
- }
- /*************************************************************************************
- ** Function name: USART_Configuration
- ** Descriptions: USART配置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void USART_Configuration()
- {
- STR_UART_T param;
- DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC, 0); //使用外设时注意必须设置该外设的时钟 设置USART的时钟源为外部12MHZ
- DrvGPIO_InitFunction(E_FUNC_UART0); // 复用功能引脚设置
- param.u32BaudRate = 9600; // 波特率 9600
- param.u8cDataBits = DRVUART_DATABITS_8; // 数据位
- param.u8cStopBits = DRVUART_STOPBITS_1; // 停止位
- param.u8cParity = DRVUART_PARITY_NONE; // 校验位
- param.u8cRxTriggerLevel = DRVUART_FIFO_1BYTES; // FIFO存储深度 1 字节
- param.u8TimeOut = 0; // FIFO超时设定
- DrvUART_Open(UART_PORT0, ¶m); // 串口usart0开启、结构体整体赋值
- DrvUART_EnableInt(UART_PORT0, DRVUART_RDAINT,UART_INT_HANDLE);// 使能串口1接收中断并建立一个中断回调函数
- }
- /*************************************************************************************
- ** Function name: UART_INT_HANDLE
- ** Descriptions: 串口接收中断
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void UART_INT_HANDLE (uint32_t u32IntStatus)
- {
- static uint8_t step = 0;
- uint8_t buffer[1]={0xFF};
- if(u32IntStatus & DRVUART_RDAINT) //如果是接收中断
- {
- if(UART0->ISR.RDA_IF==1) //如果是串口0接收中断
- {
- if(ID == 0)
- {
- DrvUART_Read(UART_PORT0,buffer,1);
- if(buffer[0] == 97) //输入'a'进行时间校准
- {
- ID = 2;
- printf("请输入要校准的日期及时间: \n");
- printf("请逐个输入两位年份:\n");
- step = 0;
- }
- else if(buffer[0] == 99) //输入'c'进行闹钟设置
- {
- ID = 3;
- printf("请输入闹钟需要设置的日期及时间: \n");
- printf("请逐个输入两位年份:\n");
- step = 0;
- }
- }
- else if(ID >= 2)
- {
- switch(step)
- {
- case 0:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[0] = buffer[0] - 0x30;
- step = 1;
- break;
- case 1:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[1] = buffer[0] - 0x30;
- printf("请逐个输入两位月:\n");
- step = 2;
- break;
- case 2:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[2] = buffer[0] - 0x30;
- step = 3;
- break;
- case 3:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[3] = buffer[0] - 0x30;
- printf("请逐个输入两位日:\n");
- step = 4;
- break;
- case 4:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[4] = buffer[0] - 0x30;
- step = 5;
- break;
- case 5:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[5] = buffer[0] - 0x30;
- printf("请逐个输入两位时:\n");
- step = 6;
- break;
- case 6:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[6] = buffer[0] - 0x30;
- step = 7;
- break;
- case 7:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[7] = buffer[0] - 0x30;
- printf("请逐个输入两位分:\n");
- step = 8;
- break;
- case 8:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[8] = buffer[0] - 0x30;
- step = 9;
- break;
- case 9:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[9] = buffer[0] - 0x30;
- printf("请逐个输入两位秒:\n");
- step = 10;
- break;
- case 10:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[10] = buffer[0] - 0x30;
- step = 11;
- break;
- case 11:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[11] = buffer[0] - 0x30;
- step = 12;
- printf("请输入星期:\n");
- //printf("请输入b结束:\n");
- break;
- case 12:
- DrvUART_Read(UART_PORT0,buffer,1);
- DATE[12] = buffer[0] - 0x30;
- step = 13;
- if(ID == 2)
- printf("请输入b结束时间校准:\n");
- else if(ID == 3)
- printf("请输入d结束闹钟设置:\n");
- break;
- case 13:
- DrvUART_Read(UART_PORT0,buffer,1);
- if(buffer[0] == 98)
- ID = 4;
- else if(buffer[0] == 100)
- ID = 5;
- break;
- case 14:
- break;
- case 15:
- break;
- case 16:
- break;
- case 17:
- break;
- default:break;
- }
- }
- }
- }
- }
- /*************************************************************************************
- ** Function name: ADC_Configuration
- ** Descriptions: 配置USART
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void ADC_Configuration()
- {
- DrvSYS_SelectIPClockSource(E_SYS_ADC_CLKSRC, 0); //使用外设时注意必须设置该外设的时钟 设置ADC的时钟源为外部12MHZ
- DrvADC_Open(ADC_SINGLE_END, ADC_SINGLE_OP, 0, EXTERNAL_12MHZ, 3); // ADC_SINGLE_END AD为单端输入模式
- // ADC_SINGLE_OP 单一转换
- // 1 GA0作为输入 模式输入通道使能
- // EXTERNAL_12MHZ ADC时钟为 外部12MHZ
- // 3 AD时钟频率 = ADC时钟/(3+1) = 3MHZ
- DrvADC_SetADCChannel(0x10,ADC_SINGLE_END); // 8 设置为模拟通道7
- // ADC_SINGLE_END AD为单端输入模式
- ADC->ADCR.DMOF = 0; //转化结果无符号
- ADC->ADCHER.PRESEL = 0x02; //内部温度传感器
- ADC->ADCHER.CHEN = 0x80; //模拟输入通道7使能
- SYS->TEMPCR = 0x01; //使能温度传感器
- }
- /*************************************************************************************
- ** Function name: TIMER_Configuration
- ** Descriptions: TIMER配置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void TIMER_Configuration()
- {
- DrvTIMER_Init(); //初始化定时器
- DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC,0); //使用外设时注意必须设置该外设的时钟 设置TIMER0的时钟源为外部12MHZ
- DrvTIMER_Open(E_TMR0,1000,E_PERIODIC_MODE); //设定定时器timer0的tick周期,并且启动定时器:定时器通道 TMR0 每秒1000次 周期模式
- DrvTIMER_SetTimerEvent(E_TMR0,5,(TIMER_CALLBACK) Timer0_Callback,0); //安装一个定时处理事件到 timer0通道
- DrvTIMER_EnableInt(E_TMR0); //使能定时器中断 //TIMER0->TCSR.IE = 1
- DrvTIMER_Start(E_TMR0); //定时器timer0开始计数 //TIMER0->TCSR.CEN = 1;
- }
- /*************************************************************************************
- ** Function name: Timer0_Callback
- ** Descriptions: 定时处理事件,LED动态扫描
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void Timer0_Callback (void)
- {
- static uint8_t count= 0;
- static uint8_t count1= 0;
- static uint8_t i,xx[4];
- uint32_t data;
- uint16_t ValueBuff ;
- ValueBuff = value;
- KeyPro(); //按键扫描 该函数在 button.c 中实现
- count++;
- count1++;
- if(count1>=100)
- {
- count1 = 0;
- if(ID == 0)
- ID = 1; //每500ms 将获取RTC时间的标志置一
- }
- if(count >= 5)
- count = 1;
- for(i=0;i<4;i++)
- {
- xx = ValueBuff%10;
- ValueBuff = ValueBuff/10;
- }
- switch(count)
- {
- case 1:
- DrvGPIO_SetBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,6);
- DrvGPIO_ClrBit(E_GPC,7);
- data = Table[xx[0]]<<2;
- GPIOA->DOUT = data;
- break;
- case 2:
- DrvGPIO_SetBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,6);
- DrvGPIO_ClrBit(E_GPC,7);
- data = Table[xx[1]]<<2;
- GPIOA->DOUT = data;
- break;
- case 3:
- DrvGPIO_SetBit(E_GPC,7);
- DrvGPIO_ClrBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,6);
- data = Table[xx[2]]<<2;
- GPIOA->DOUT = data;
- break;
- case 4:
- DrvGPIO_SetBit(E_GPC,6);
- DrvGPIO_ClrBit(E_GPC,14);
- DrvGPIO_ClrBit(E_GPC,15);
- DrvGPIO_ClrBit(E_GPC,7);
- data = Table[xx[3]]<<2;
- GPIOA->DOUT = data;
- //DrvGPIO_ClrBit(E_GPA,9); //显示小数点
- break;
- default:break;
- }
- }
- /*************************************************************************************
- ** Function name: RTC_Configuration
- ** Descriptions: RTC配置
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void RTC_Configuration()
- {
- UNLOCKREG();
- /* Step 1. Enable and Select RTC clock source */
- SYSCLK->WRCON.XTL32K_EN = 1;//Enable 32Khz for RTC clock source
- SYSCLK->APBCLK.RTC_EN =1;//Enable RTC clock source
- LOCKREG();
- /* Step 2. Initiate and unlock RTC module */
- START_RTC();
- /* Step 3. Initiate Time and Calendar setting */
- RTC->TSSR.HR24 =Adjust[13];//Set 24hour mode
- RTC->DWR.DWR =Adjust[12];//Set Sunday
- //Set time and calendar for loading register, Calendar: 11/9/18, Time: 12:58:00
- Set_CLR(Adjust[0],Adjust[1],Adjust[2],Adjust[3],Adjust[4],Adjust[5]);//设置日期载入寄存器CLR
- Set_TLR(Adjust[6],Adjust[7],Adjust[8],Adjust[9],Adjust[10],Adjust[11]);//设置时间载入寄存器TLR
- /* Step 4. Set alarm interrupt */
- //Set time and calendar for alarm register , Calendar: 11/9/18, Time: 13:10:00
- Set_CAR(Alarm[0],Alarm[1],Alarm[2],Alarm[3],Alarm[4],Alarm[5]);//设置日历闹钟寄存器CAR
- Set_TAR(Alarm[6],Alarm[7],Alarm[8],Alarm[9],Alarm[10],Alarm[11]);//设置时间闹钟寄存器TAR
- DrvRTC_EnableInt(DRVRTC_ALARM_INT, RTC_AlarmCallBackfn); //闹钟中断使能 并设置中断回调函数
- }
- /*************************************************************************************
- ** Function name: RTC_AlarmCallBackfn
- ** Descriptions: 闹钟中断函数
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void RTC_AlarmCallBackfn()
- {
- DrvGPIO_SetBit(E_GPB,10); //开启蜂鸣器
- }
- /*************************************************************************************
- ** Function name: START_RTC
- ** Descriptions: 启动RTC
- ** input parameters: none
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void START_RTC(void)
- {
- while(1)
- {
- RTC->INIR = 0xa5eb1357; //RTC初始化
- if(inpw(&RTC->INIR)==1)
- break;
- }
- while(1)
- {
- RTC->AER.AER = 0xA965; //RTC读/写使能
- if(inpw(&RTC->AER)&0x10000)// AER bit
- break;
- }
- }
- /*************************************************************************************
- ** Function name: Set_TLR
- ** Descriptions: 设置RTC的TLR寄存器
- ** input parameters: int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void Set_TLR (int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f)
- {
- outpw(&RTC->TLR, a<<20|b<<16|c<<12|d<<8|e<<4|f) ;
- }
- /*************************************************************************************
- ** Function name: Set_CLR
- ** Descriptions: 设置RTC的CLR寄存器
- ** input parameters: int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void Set_CLR (int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f)
- {
- outpw(&RTC->CLR, a<<20|b<<16|c<<12|d<<8|e<<4|f) ;
- }
- /*************************************************************************************
- ** Function name: Set_TAR
- ** Descriptions: 设置RTC的TAR寄存器
- ** input parameters: int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void Set_TAR(int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f)
- {
- outpw(&RTC->TAR, a<<20|b<<16|c<<12|d<<8|e<<4|f) ;
- }
- /*************************************************************************************
- ** Function name: Set_CAR
- ** Descriptions: 设置RTC的CAR寄存器
- ** input parameters: int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f
- ** output parameters: none
- ** Returned value: none
- *************************************************************************************/
- void Set_CAR (int32_t a,int32_t b,int32_t c,int32_t d,int32_t e,int32_t f)
- {
- outpw(&RTC->CAR, a<<20|b<<16|c<<12|d<<8|e<<4|f) ;
- }
- /*************************************************************************************
- ** Function name: delay_ms
- ** Descriptions: 1ms(晶振为12MHZ)延时子程序
- ** input parameters: count
- ** output parameters: 无
- ** Returned value: 无
- *************************************************************************************/
- void delay_ms(uint32_t count)
- {
- uint32_t i,j;
- for(i=count;i>0;i--)
- for(j=2395;j>0;j--);
- }
其他的就不传了
下面传两张图片
工程
注意:工程与半主机的略不同 就是 retarget.c函数
对了 如果校准完时间想要下次启动时为校准时间 只需将存放校准时间的数组更新一下即可