自己做的一个STM32实时时钟,给有需要的朋友拿去学习。
单片机源程序如下:
- //////////////////////////////////////////////////////////
- //本例程演示了RTC的设置与使用方法
- //////////////////////////////////////////////////////////
- #include
- #include "ASCII.h"
- #include "HZ_GB2312.h"
- #include "gui.h"
- #include "number.c"
- #define LED1_OFF GPIO_SetBits(GPIOC, GPIO_Pin_0)
- #define LED1_ON GPIO_ResetBits(GPIOC, GPIO_Pin_0)
- #define LED2_OFF GPIO_SetBits(GPIOC, GPIO_Pin_1)
- #define LED2_ON GPIO_ResetBits(GPIOC, GPIO_Pin_1)
- #define LED3_OFF GPIO_SetBits(GPIOC, GPIO_Pin_2)
- #define LED3_ON GPIO_ResetBits(GPIOC, GPIO_Pin_2)
- #define LED1_STATUS GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_0)
- #define LED2_STATUS GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_1)
- #define LED3_STATUS GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_2)
- //vu32 flag_display = 0;
- //配置LED对应端口
- void LED_Configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE );
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
- GPIO_Init(GPIOC, &GPIO_InitStructure);
- }
- //通用延时函数
- #define TIME_MS 12000 //@72M
- #define TIME_US 10 //@72M
- //长延时函数
- void Delay_ms(unsigned int n)
- {
- unsigned int i,j;
- for(i=n;i>0;i--)
- for(j=TIME_MS;j>0;j--);
- }
- //短延时函数
- void Delay_us(unsigned int n)
- {
- unsigned int i,j;
- for(i=n;i>0;i--)
- for(j=TIME_US;j>0;j--);
- }
- //系统中断管理
- void NVIC_Configuration(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- }
- void RTC_Configuration(void)
- {
- //后备域时钟使能
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
- //后备域访问使能
- PWR_BackupAccessCmd(ENABLE);
- //复位后备域
- BKP_DeInit();
- //低频外部时钟LSE使能
- RCC_LSEConfig(RCC_LSE_ON);
- //等待LSE就绪
- while(RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET);
- //选择LSE作为RTC时钟源
- RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
- //RTC时钟使能
- RCC_RTCCLKCmd(ENABLE);
- //等待RTC寄存器同步
- RTC_WaitForSynchro();
- //等待RTC寄存器最近一次写操作完成
- RTC_WaitForLastTask();
- //秒中断使能
- RTC_ITConfig(RTC_IT_SEC, ENABLE);
- //等待RTC寄存器最近一次写操作完成
- RTC_WaitForLastTask();
- //配置预分频系数为32767+1,当选择32.768kHz晶振时RTC计数频率为1Hz
- RTC_SetPrescaler(32767);
- //等待RTC寄存器最近一次写操作完成
- RTC_WaitForLastTask();
- }
- //配置系统时钟,使能各外设时钟
- void RCC_Configuration(void)
- {
- SystemInit();
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC |RCC_APB2Periph_ADC1
- |RCC_APB2Periph_GPIOD| RCC_APB2Periph_AFIO , ENABLE );
- }
- void RTC_Check()
- {
- if(BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5) //如果后备寄存器不为特定值,配置RTC
- {
- RTC_Configuration(); //RTC配置
- RTC_WaitForLastTask(); //等待RTC寄存器最后一次写操作完成
- RTC_SetCounter(0); //设置RTC计数器值
- RTC_WaitForLastTask(); //等待RTC寄存器最后一次写操作完成
- BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
- }
- else //如果后背寄存器为特定值,仅简单操作RTC
- {
- RTC_WaitForSynchro(); //等待RTC寄存器同步
- RTC_ITConfig(RTC_IT_SEC, ENABLE); //使能RTC秒中断
- RTC_WaitForLastTask(); //等待RTC寄存器最近一次写操作完成
- }
- RCC_ClearFlag(); //清除标志
- }
- //配置所有外设
- void Init_All_Periph(void)
- {
- SystemInit();
- LED_Configuration();
- NVIC_Configuration();
- LCD_Init(); //LCD彩屏初始化
- LCD_ClearScreen(WHITE); //清屏
- }
- u8 isIn;
- //主函数
- int main(void)
- {
- // char buf[25];
- u32 TimeVar;
- Init_All_Periph();
- RTC_Check(); //实时时钟检查
- GUI_Text(20,50,"Elapsed Time:",BLUE,WHITE);
- //先固定显示两个冒号的位置
- LCD_DrawPicture(100, 120, Colon_Image);
- LCD_DrawPicture(200, 120, Colon_Image);
- while(1)
- {
- if(isIn)
- {
- TimeVar = RTC_GetCounter();
- LCD_DrawPicture(20, 120, Num_Image[TimeVar/3600%24/10]); //时 十位
- LCD_DrawPicture(60, 120, Num_Image[TimeVar/3600%24%10]); //时 个位
- LCD_DrawPicture(120, 120, Num_Image[TimeVar/60%60/10]); //分 十位
- LCD_DrawPicture(160, 120, Num_Image[TimeVar/60%60%10]); //分 个位
- LCD_DrawPicture(220, 120, Num_Image[TimeVar%60/10]); //秒 十位
- LCD_DrawPicture(260, 120, Num_Image[TimeVar%60%10]); //秒 个位
- isIn = 0;
- }
- }
- }
- //RTC中断服务函数
- void RTC_IRQHandler()
- {
- if(RTC_GetITStatus(RTC_IT_SEC) != RESET) //判断是否为秒中断
- {
- isIn = 1;
- RTC_ClearITPendingBit(RTC_IT_SEC); //清除秒中断标志
- }
- }
所有资料51hei提供下载:
RTC实时时钟.rar
|