找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6338|回复: 11
收起左侧

stm32超强日历源码(含24节气和闰平年)

  [复制链接]
ID:342296 发表于 2018-6-1 09:38 | 显示全部楼层 |阅读模式
本历程使用STM32F103VET6编写的电子日历,除了常有的日期和星期外,领加了24节气;

单片机源程序如下:
  1. /******************** (C) COPYRIGHT 2011 野火嵌入式开发工作室 ********************
  2. * 文件名  :main.c
  3. * 描述    :超强的日历,支持农历,24节气几乎所有日历的功能 日历时间以1970年为元年,
  4. *           用32bit的时间寄存器可以运行到2100年左右。         
  5. * 实验平台:野火STM32开发板
  6. * 库版本  :ST3.0.0
  7. **********************************************************************************/
  8. #include "stm32f10x.h"
  9. #include "stdio.h"
  10. #include "calendar.h"
  11. #include "date.h"

  12. __IO uint32_t TimeDisplay = 0;

  13. void RCC_Configuration(void);
  14. void NVIC_Configuration(void);
  15. void GPIO_Configuration(void);
  16. void USART_Configuration(void);
  17. int fputc(int ch, FILE *f);
  18. void RTC_Configuration(void);
  19. //u32 Time_Regulate(void);
  20. void Time_Regulate(struct rtc_time *tm);
  21. void Time_Adjust(void);
  22. void Time_Display(uint32_t TimeVar);
  23. void Time_Show(void);
  24. u8 USART_Scanf(u32 value);


  25. #define  RTCClockSource_LSE        


  26. u8 const *WEEK_STR[] = {"日", "一", "二", "三", "四", "五", "六"};
  27. u8 const *zodiac_sign[] = {"猪", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗"};

  28. struct rtc_time systmtime;

  29. int main()
  30. {
  31.           /* System Clocks Configuration */
  32.           RCC_Configuration();
  33.         
  34.           /* NVIC configuration */
  35.           NVIC_Configuration();
  36.         
  37.           GPIO_Configuration();
  38.         
  39.           USART_Configuration();
  40.         
  41.           /*在启动时检查备份寄存器BKP_DR1,如果内容不是0xA5A5,则需重新配置时间并询问用户调整时间*/
  42.         if (BKP_ReadBackupRegister(BKP_DR1) != 0xA5A5)
  43.         {
  44.             printf("\r\n\n RTC not yet configured....");
  45.                
  46.             /* RTC Configuration */
  47.             RTC_Configuration();
  48.                 printf("\r\n RTC configured....");
  49.                
  50.                 /* Adjust time by users typed on the hyperterminal */
  51.             Time_Adjust();
  52.                
  53.                 BKP_WriteBackupRegister(BKP_DR1, 0xA5A5);
  54.         }
  55.         else
  56.         {
  57.             /*启动无需设置新时钟*/
  58.                 /*检查是否掉电重启*/
  59.                 if (RCC_GetFlagStatus(RCC_FLAG_PORRST) != RESET)
  60.                 {
  61.                     printf("\r\n\n Power On Reset occurred....");
  62.                 }
  63.                 /*检查是否Reset复位*/
  64.                 else if (RCC_GetFlagStatus(RCC_FLAG_PINRST) != RESET)
  65.             {
  66.               printf("\r\n\n External Reset occurred....");
  67.             }
  68.                
  69.                 printf("\r\n No need to configure RTC....");
  70.                
  71.                 /*等待寄存器同步*/
  72.                 RTC_WaitForSynchro();
  73.                
  74.                 /*允许RTC秒中断*/
  75.                 RTC_ITConfig(RTC_IT_SEC, ENABLE);
  76.                
  77.                 /*等待上次RTC寄存器写操作完成*/
  78.                 RTC_WaitForLastTask();
  79.         }

  80.         #ifdef RTCClockOutput_Enable
  81.           /* Enable PWR and BKP clocks */
  82.           RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  83.         
  84.           /* Allow access to BKP Domain */
  85.           PWR_BackupAccessCmd(ENABLE);
  86.         
  87.           /* Disable the Tamper Pin */
  88.           BKP_TamperPinCmd(DISABLE); /* To output RTCCLK/64 on Tamper pin, the tamper
  89.                                          functionality must be disabled */
  90.         
  91.           /* Enable RTC Clock Output on Tamper Pin */
  92.           BKP_RTCOutputConfig(BKP_RTCOutputSource_CalibClock);
  93.         #endif
  94.         
  95.           /* Clear reset flags */
  96.           RCC_ClearFlag();
  97.         
  98.           /* Display time in infinite loop */
  99.           Time_Show();
  100. }

  101. void RCC_Configuration()
  102. {
  103.                 SystemInit();
  104.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
  105. }

  106. void NVIC_Configuration()
  107. {
  108.           NVIC_InitTypeDef NVIC_InitStructure;
  109.         
  110.           /* Configure one bit for preemption priority */
  111.           NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  112.         
  113.           /* Enable the RTC Interrupt */
  114.           NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
  115.           NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  116.           NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  117.           NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  118.           NVIC_Init(&NVIC_InitStructure);
  119. }

  120. void GPIO_Configuration()
  121. {
  122.           GPIO_InitTypeDef GPIO_InitStructure;
  123.         
  124.            /* Configure USART1 Tx (PA.09) as alternate function push-pull */
  125.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  126.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  127.           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  128.           GPIO_Init(GPIOA, &GPIO_InitStructure);
  129.             
  130.           /* Configure USART1 Rx (PA.10) as input floating */
  131.           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  132.           GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  133.           GPIO_Init(GPIOA, &GPIO_InitStructure);

  134. }

  135. /*******************************************************************************
  136. * Function Name  : USART_Configuration
  137. * Description    : Configures the USART1.
  138. * Input          : None
  139. * Output         : None
  140. * Return         : None
  141. *******************************************************************************/
  142. void USART_Configuration()
  143. {
  144.             USART_InitTypeDef USART_InitStructure;
  145.         
  146.                 USART_InitStructure.USART_BaudRate = 115200;
  147.                 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  148.                 USART_InitStructure.USART_StopBits = USART_StopBits_1;
  149.                 USART_InitStructure.USART_Parity = USART_Parity_No ;
  150.                 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  151.             USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  152.         
  153.                 USART_Init(USART1, &USART_InitStructure);
  154.             USART_Cmd(USART1, ENABLE);
  155. }

  156. /*******************************************************************************
  157. * Function Name  : fputc
  158. * Description    : Retargets the C library printf function to the USART or ITM Viewer.
  159. * Input          : None
  160. * Output         : None
  161. * Return         : None
  162. *******************************************************************************/
  163. int fputc(int ch, FILE *f)
  164. {
  165.           /* 将Printf内容发往串口 */
  166.           USART_SendData(USART1, (unsigned char) ch);

  167.           while (!(USART1->SR & USART_FLAG_TXE));
  168.          
  169.           return (ch);
  170. }

  171. /***********************************************************************
  172. *函数名:RTC_Configuration
  173. *描述:配置RTC
  174. *输入:无
  175. *输出:无
  176. *返回:无
  177. ************************************************************************/
  178. void RTC_Configuration()
  179. {
  180.      /*允许PWR和BKP时钟*/
  181.          RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);
  182.          
  183.          /*允许访问BKP域*/
  184.          PWR_BackupAccessCmd(ENABLE);
  185.          
  186.          /*复位备份域*/
  187.          BKP_DeInit();
  188.          
  189.          #ifdef RTCClockSource_LSI
  190.          
  191.          /*允许LSI*/
  192.          RCC_LSICmd(ENABLE);
  193.          
  194.          /*等待LSI准备好*/
  195.          while(RCC_GetFlagStatus(RCC_FLAG_LSIRDY)==RESET)
  196.          {
  197.          }
  198.          
  199.          /*选择LSI作为RTC时钟源*/
  200.          RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
  201.          
  202.          #elif defined  RTCClockSource_LSE
  203.          
  204.          /*允许LSE*/
  205.          RCC_LSEConfig(RCC_LSE_ON);
  206.          
  207.          /*等待LSE准备好*/
  208.          while(RCC_GetFlagStatus(RCC_FLAG_LSERDY)==RESET)
  209.          {
  210.          }
  211.          
  212.          /*选择LSE作为RTC时钟源*/
  213.          RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
  214.          #endif
  215.          
  216.          /* Enable RTC Clock */
  217.      RCC_RTCCLKCmd(ENABLE);
  218.          
  219.          #ifdef RTCClockOutput_Enable
  220.          /*禁止Tamper引脚*/
  221.          BKP_TamperPinCmd(DISABLE);/*为了将RTCCLK/64在Tamper引脚输出,Tamper功能必须被禁止*/
  222.          
  223.          /*允许RTC时钟在Tamper引脚上输出*/
  224.          BKP_RTCCalibrationClockOutputCmd(ENABLE);
  225.          #endif
  226.          
  227.          /*等待寄存器同步*/
  228.          RTC_WaitForSynchro();
  229.          
  230.          /*等待上次RTC寄存器写操作完成*/
  231.          RTC_WaitForLastTask();
  232.          
  233.          /*允许RTC秒中断*/
  234.          RTC_ITConfig(RTC_IT_SEC, ENABLE);
  235.          
  236.          /*等待上次RTC寄存器写操作完成*/
  237.          RTC_WaitForLastTask();
  238.          
  239.          #ifdef RTCClockSource_LSI
  240.          /*设置分频系数*/
  241.          RTC_SetPrescaler(31999); /*RTC周期=RTCCLK/RTC_PR=(32.000kHz/(31999+1))*/
  242.          
  243.          #elif defined  RTCClockSource_LSE
  244.          RTC_SetPrescaler(32767); /*RTC周期=RTCCLK/RTC_PR=(32.768kHz/(31767+1))*/
  245.          #endif
  246.          
  247.          /*等待上次RTC寄存器写操作完成*/
  248.          RTC_WaitForLastTask();
  249.         
  250. }

  251. /*******************************************************************************
  252. * Function Name  : Time_Regulate
  253. * Description    : Returns the time entered by user, using Hyperterminal.
  254. * Input          : None
  255. * Output         : None
  256. * Return         : Current time RTC counter value
  257. *******************************************************************************/
  258. //u32 Time_Regulate()
  259. //{
  260. //          u32 Tmp_HH = 0xFF, Tmp_MM = 0xFF, Tmp_SS = 0xFF;
  261. //        
  262. //          printf("\r\n==============Time Settings=====================================");
  263. //          printf("\r\n  Please Set Hours");
  264. //        
  265. //          while (Tmp_HH == 0xFF)
  266. //          {
  267. //            Tmp_HH = USART_Scanf(23);
  268. //          }
  269. //          printf(":  %d", Tmp_HH);
  270. //          printf("\r\n  Please Set Minutes");
  271. //          while (Tmp_MM == 0xFF)
  272. //          {
  273. //            Tmp_MM = USART_Scanf(59);
  274. //          }
  275. //          printf(":  %d", Tmp_MM);
  276. //          printf("\r\n  Please Set Seconds");
  277. //          while (Tmp_SS == 0xFF)
  278. //          {
  279. //            Tmp_SS = USART_Scanf(59);
  280. //          }
  281. //          printf(":  %d", Tmp_SS);
  282. //        
  283. //          /* 返回用户输入值,以便存入RTC计数寄存器 */
  284. //          return((Tmp_HH*3600 + Tmp_MM*60 + Tmp_SS));
  285. //}

  286. void Time_Regulate(struct rtc_time *tm)
  287. {
  288.           u32 Tmp_YY = 0xFF, Tmp_MM = 0xFF, Tmp_DD = 0xFF, Tmp_HH = 0xFF, Tmp_MI = 0xFF, Tmp_SS = 0xFF;
  289.         
  290.           printf("\r\n=========================Time Settings==================");
  291.         
  292.           printf("\r\n  请输入年份(Please Set Years):  20");

  293.           while (Tmp_YY == 0xFF)
  294.           {
  295.             Tmp_YY = USART_Scanf(99);
  296.           }

  297.           printf("\n\r  年份被设置为:  20%0.2d\n\r", Tmp_YY);

  298.           tm->tm_year = Tmp_YY+2000;
  299.         
  300.           Tmp_MM = 0xFF;

  301.           printf("\r\n  请输入月份(Please Set Months):  ");

  302.           while (Tmp_MM == 0xFF)
  303.           {
  304.             Tmp_MM = USART_Scanf(12);
  305.           }

  306.           printf("\n\r  月份被设置为:  %d\n\r", Tmp_MM);

  307.           tm->tm_mon= Tmp_MM;
  308.         
  309.           Tmp_DD = 0xFF;

  310.           printf("\r\n  请输入日期(Please Set Dates):  ");

  311.           while (Tmp_DD == 0xFF)
  312.           {
  313.             Tmp_DD = USART_Scanf(31);
  314.           }

  315.           printf("\n\r  日期被设置为:  %d\n\r", Tmp_DD);

  316.           tm->tm_mday= Tmp_DD;
  317.         
  318.           Tmp_HH  = 0xFF;

  319.           printf("\r\n  请输入时钟(Please Set Hours):  ");

  320.           while (Tmp_HH == 0xFF)
  321.           {
  322.             Tmp_HH = USART_Scanf(23);
  323.           }

  324.           printf("\n\r  时钟被设置为:  %d\n\r", Tmp_HH );

  325.           tm->tm_hour= Tmp_HH;
  326.             
  327.           Tmp_MI = 0xFF;

  328.           printf("\r\n  请输入分钟(Please Set Minutes):  ");

  329.           while (Tmp_MI == 0xFF)
  330.           {
  331.             Tmp_MI = USART_Scanf(59);
  332.           }

  333.           printf("\n\r  分钟被设置为:  %d\n\r", Tmp_MI);

  334.           tm->tm_min= Tmp_MI;
  335.          
  336.           Tmp_SS = 0xFF;

  337.           printf("\r\n  请输入秒钟(Please Set Seconds):  ");

  338.           while (Tmp_SS == 0xFF)
  339.           {
  340.             Tmp_SS = USART_Scanf(59);
  341.           }

  342.           printf("\n\r  秒钟被设置为:  %d\n\r", Tmp_SS);

  343.           tm->tm_sec= Tmp_SS;
  344. }

  345. /*******************************************************************************
  346. * Function Name  : Time_Adjust
  347. * Description    : Adjusts time.
  348. * Input          : None
  349. * Output         : None
  350. * Return         : None
  351. *******************************************************************************/
  352. //void Time_Adjust()
  353. //{
  354. //          /* Wait until last write operation on RTC registers has finished */
  355. //          RTC_WaitForLastTask();
  356. //         
  357. //          /* 修改当前RTC计数寄存器内容 */
  358. //          RTC_SetCounter(Time_Regulate());
  359. //         
  360. //          /* Wait until last write operation on RTC registers has finished */
  361. //          RTC_WaitForLastTask();
  362. //}

  363. void Time_Adjust()
  364. {
  365.           /* Wait until last write operation on RTC registers has finished */
  366.           RTC_WaitForLastTask();
  367.         
  368.           /* Get time entred by the user on the hyperterminal */
  369.           Time_Regulate(&systmtime);
  370.          
  371.           /* Get wday */
  372.           GregorianDay(&systmtime);

  373.           /* 修改当前RTC计数寄存器内容 */
  374.           RTC_SetCounter(mktimev(&systmtime));

  375.           /* Wait until last write operation on RTC registers has finished */
  376.           RTC_WaitForLastTask();
  377. }

  378. /*******************************************************************************
  379. * Function Name  : Time_Display
  380. * Description    : Displays the current time.
  381. * Input          : - TimeVar: RTC counter value.
  382. * Output         : None
  383. * Return         : None
  384. *******************************************************************************/
  385. //void Time_Display(u32 TimeVar)
  386. //{
  387. //          u32 THH = 0, TMM = 0, TSS = 0;
  388. //        
  389. //          /* Compute  hours */
  390. //          THH = TimeVar / 3600;
  391. //          /* Compute minutes */
  392. //          TMM = (TimeVar % 3600) / 60;
  393. //          /* Compute seconds */
  394. //          TSS = (TimeVar % 3600) % 60;
  395. //        
  396. //          printf("Time: %0.2d:%0.2d:%0.2d\r", THH, TMM, TSS);
  397. //}

  398. void Time_Display(uint32_t TimeVar)
  399. {
  400.            static uint32_t FirstDisplay = 1;
  401.            u8 str[15]; // 字符串暂存
  402.            
  403.            to_tm(TimeVar, &systmtime);
  404.         
  405.           if((!systmtime.tm_hour && !systmtime.tm_min && !systmtime.tm_sec)  || (FirstDisplay))
  406.           {
  407.               
  408.               GetChinaCalendar((u16)systmtime.tm_year, (u8)systmtime.tm_mon, (u8)systmtime.tm_mday, str);
  409.         
  410.               printf("\n\r\n\r  今天农历:%0.2d%0.2d,%0.2d,%0.2d", str[0], str[1], str[2],  str[3]);
  411.         
  412.               GetChinaCalendarStr((u16)systmtime.tm_year,(u8)systmtime.tm_mon,(u8)systmtime.tm_mday,str);
  413.               printf("  %s", str);
  414.         
  415.              if(GetJieQiStr((u16)systmtime.tm_year, (u8)systmtime.tm_mon, (u8)systmtime.tm_mday, str))
  416.                   printf("  %s\n\r", str);
  417.         
  418.               FirstDisplay = 0;
  419.           }

  420.          

  421.           /* 输出公历时间 */
  422.           printf("\r   当前时间为: %d年(%s年) %d月 %d日 (星期%s)  %0.2d:%0.2d:%0.2d",
  423.                             systmtime.tm_year, zodiac_sign[(systmtime.tm_year-3)%12], systmtime.tm_mon, systmtime.tm_mday,
  424.                             WEEK_STR[systmtime.tm_wday], systmtime.tm_hour,
  425.                             systmtime.tm_min, systmtime.tm_sec);

  426. }

  427. /*******************************************************************************
  428. * Function Name  : Time_Show
  429. * Description    : Shows the current time (HH:MM:SS) on the Hyperterminal.
  430. * Input          : None
  431. * Output         : None
  432. * Return         : None
  433. ******************************************************************************/
  434. void Time_Show()
  435. {
  436.           printf("\n\r");
  437.         
  438.           /* Infinite loop */
  439.           while (1)
  440.           {
  441.             /* 每过1s */
  442. ……………………

  443. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:

超强日历(含24节气和闰平年).rar (255.87 KB, 下载次数: 241)
回复

使用道具 举报

ID:389200 发表于 2019-3-23 17:59 | 显示全部楼层
很想要这资源
回复

使用道具 举报

ID:78947 发表于 2019-11-15 13:50 | 显示全部楼层
赞,跑得很6,感谢楼主分享,,,之前在论坛下载别人的f103cb_FreeRTOS跑到硬件故障中断了
回复

使用道具 举报

ID:443840 发表于 2019-11-30 10:53 | 显示全部楼层
想要这程序可黑币还差一颗星,我筹齐了过来哈
回复

使用道具 举报

ID:638375 发表于 2019-11-30 23:32 | 显示全部楼层
收藏学习了,谢谢分享!!
回复

使用道具 举报

ID:300101 发表于 2019-12-4 23:44 | 显示全部楼层
可算找到了,收藏学习,谢谢分享!
回复

使用道具 举报

ID:574789 发表于 2019-12-23 07:55 | 显示全部楼层
战舰的板子能跑吗
回复

使用道具 举报

ID:268151 发表于 2020-2-26 14:30 | 显示全部楼层
收藏学习了,谢谢分享
回复

使用道具 举报

ID:91165 发表于 2020-2-26 18:44 | 显示全部楼层
下载了,楼主辛苦了
回复

使用道具 举报

ID:793756 发表于 2020-12-7 16:47 | 显示全部楼层
MiniSTM32开发板能跑吗?
回复

使用道具 举报

ID:866625 发表于 2021-6-26 21:38 | 显示全部楼层
proteus谁有能分享学习一下吗?
回复

使用道具 举报

ID:216265 发表于 2021-6-28 11:04 | 显示全部楼层
我也开发了一个呢,还修正了天之地干表
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表