查看: 4086|回复: 0

GD32F450学习——RTC实验

[复制链接]
  • TA的每日心情
    奋斗
    2023-6-27 14:09
  • 签到天数: 943 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2017-4-23 14:17:04 | 显示全部楼层 |阅读模式
    分享到:
    液晶屏成功驱动后,首先想到的是做一个闹钟。GD32F450自带RTC模块,详细如下:
    1.PNG

    2.PNG


           RTC可以计时,也可以设置闹钟,这次没有设定键盘,所以不能调节时间,只能在代码里设置好,并设定一个闹钟,闹钟时间到时,可以出发中断去执行特定操作,这里是让程序点亮LED,如果接蜂鸣器,就是闹铃了。
    下面部分是预设值函数,由于小红板没有外部32K晶振,只能选择内部时钟,所以需要提前声明RTC_CLOCK_SOURCE_IRC32K一下,这样初始化时会使用内部时钟,如果选用外部时钟是无法工作的。
    1. void rtc_pre_config(void)
    2. {
    3.     #if defined (RTC_CLOCK_SOURCE_IRC32K)
    4.           rcu_osci_on(RCU_IRC32K);
    5.           rcu_osci_stab_wait(RCU_IRC32K);
    6.           rcu_rtc_clock_config(RCU_RTCSRC_IRC32K);
    7.   
    8.           prescaler_s = 0x13F;
    9.           prescaler_a = 0x63;
    10.     #elif defined (RTC_CLOCK_SOURCE_LXTAL)
    11.           rcu_osci_on(RCU_LXTAL);
    12.           rcu_osci_stab_wait(RCU_LXTAL);
    13.           rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
    14.    
    15.           prescaler_s = 0xFF;
    16.           prescaler_a = 0x7F;
    17.     #else
    18.     #error RTC clock source should be defined.
    19.     #endif /* RTC_CLOCK_SOURCE_IRC32K */

    20.     rcu_periph_clock_enable(RCU_RTC);
    21.     rtc_register_sync_wait();
    22. }
    复制代码
    这部分是RTC设置函数,在里面进行了时间和日期的设置,并且设定了闹钟,(此处时间与真实时间不符)。
    1. void rtc_setup(void)
    2. {
    3.     /* setup RTC time value */
    4.     uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF;

    5.     rtc_initpara.factor_asyn = prescaler_a;
    6.     rtc_initpara.factor_syn = prescaler_s;
    7.     rtc_initpara.year = 0x16;
    8.     rtc_initpara.day_of_week = RTC_SATURDAY;
    9.     rtc_initpara.month = RTC_APR;
    10.     rtc_initpara.date = 0x30;
    11.     rtc_initpara.display_format = RTC_24HOUR;
    12.     rtc_initpara.am_pm = RTC_AM;

    13.             /* setup RTC alarm */
    14.     tmp_hh = 0X19;
    15.     tmp_mm = 0X40;
    16.     tmp_ss = 0X20;
    17.     rtc_initpara.hour = tmp_hh;
    18.     rtc_initpara.minute = tmp_mm;
    19.     rtc_initpara.second = tmp_ss;

    20. /* RTC current time configuration */
    21.     if(ERROR == rtc_init(&rtc_initpara)){   
    22.         //GPIO_BOP(GPIOD) = GPIO_PIN_7;
    23.                         Gui_DrawFont_GBK16(30, 40, RED, GRAY0,"failed");
    24.     }else{
    25.         //GPIO_BC(GPIOD) = GPIO_PIN_7;
    26.                         Gui_DrawFont_GBK16(30, 40, RED, GRAY0,"ok");
    27.         rtc_show_time();
    28.         RTC_BKP0 = BKP_VALUE;
    29.     }

    30.     rtc_alarm_disable(RTC_ALARM0);
    31.     rtc_alarm.alarm_mask = RTC_ALARM_DATE_MASK|RTC_ALARM_HOUR_MASK|RTC_ALARM_MINUTE_MASK;
    32.     rtc_alarm.weekday_or_date = RTC_ALARM_DATE_SELECTED;
    33.     rtc_alarm.alarm_day = 0x31;
    34.     rtc_alarm.am_pm = RTC_AM;

    35.     /* RTC alarm input */
    36.     tmp_hh = 0x19;
    37.     tmp_mm = 0X41;
    38.     tmp_ss = 0x20;
    39.     rtc_alarm.alarm_hour = tmp_hh;
    40.     rtc_alarm.alarm_minute = tmp_mm;
    41.     rtc_alarm.alarm_second = tmp_ss;

    42.     /* RTC alarm configuration */
    43.     rtc_alarm_config(RTC_ALARM0,&rtc_alarm);
    44.     rtc_show_alarm();
    45.     rtc_interrupt_enable(RTC_INT_ALARM0);  
    46.     rtc_alarm_enable(RTC_ALARM0);   
    47. }
    复制代码
    这两个函数是显示闹钟和时间的函数,主要使用了sprintf函数,将得到的数据转换为字符格式送到显示屏上。
    1. void rtc_show_time(void)
    2. {
    3.     uint32_t time_subsecond = 0;
    4.     uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0;

    5.     rtc_current_time_get(&rtc_initpara);  

    6.     /* get the subsecond value of current time, and convert it into fractional format */
    7.     time_subsecond = rtc_subsecond_get();
    8.     subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100;
    9.     subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10;
    10.     subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10;
    11.        
    12.     sprintf((char *)buf,"%0.2x:%0.2x:%0.2x.%d%d%d \n\r", \
    13.           rtc_initpara.hour, rtc_initpara.minute, rtc_initpara.second,\
    14.           subsecond_ss, subsecond_ts, subsecond_hs);
    15.        
    16.           Gui_DrawFont_GBK16(0, 80, RED, GRAY0, buf);
    17. }


    18. void rtc_show_alarm(void)
    19. {
    20.     rtc_alarm_get(RTC_ALARM0,&rtc_alarm);
    21.     sprintf((char*)buf,"alarm:%0.2x:%0.2x:%0.2x \n\r", rtc_alarm.alarm_hour, rtc_alarm.alarm_minute,\
    22.            rtc_alarm.alarm_second);
    23.                 Gui_DrawFont_GBK16(0, 60, RED, GRAY0, buf);
    24. }
    复制代码
    这一部分是主函数
    1. int main(void)
    2. {
    3.           u8 i=0;
    4.           u16 color=0;
    5.     systick_config();
    6.     led_init();
    7.           Lcd_Init(2);
    8.           Lcd_Clear(GRAY0);

    9.           /* enable PMU clock */
    10.     rcu_periph_clock_enable(RCU_PMU);
    11.     /* enable the access of the RTC registers */
    12.     pmu_backup_write_enable();
    13.     rtc_pre_config();

    14.     if (BKP_VALUE != RTC_BKP0){   
    15.         rtc_setup();
    16.                 }else{
    17.                        
    18.                         if (RESET != rcu_flag_get(RCU_FLAG_PORRST)){
    19. //            Gui_DrawFont_GBK16(30, 40, RED, GRAY0,"power on");
    20.         }else if (RESET != rcu_flag_get(RCU_FLAG_EPRST)){
    21.            // printf("external reset occurred....\n\r");
    22.         }
    23.        // printf("no need to configure RTC....\n\r");
    24.                                
    25.         rtc_flag_clear(RTC_STAT_ALRM0F);
    26.         exti_flag_clear(EXTI_17);

    27.         rtc_show_time();
    28.         rtc_show_alarm();
    29.     }
    30.                
    31.     rcu_all_reset_flag_clear();
    32.                 /* RTC alarm interrupt configuration */
    33.     exti_init(EXTI_17,EXTI_INTERRUPT,EXTI_TRIG_RISING);
    34.     nvic_irq_enable(RTC_Alarm_IRQn,0,0);
    35.                
    36. //                Gui_DrawFont_GBK16(30, 40, RED, GRAY0, "eeboard");
    37. //          Gui_DrawFont_GBK24(20, 60, BLUE, GRAY0, "GD32F450VE");
    38. //          Gui_DrawFont_GBK24(30, 20, BLUE, GRAY0, "ID:9robot");
    39.   while(1)
    40.   {     
    41. //                Gui_DrawFont_Num32(20, 100, RED, GRAY0, i);
    42.                 GPIO_TG(GPIOB) = GPIO_PIN_3;
    43.                 delay_1ms(500);
    44.                 GPIO_TG(GPIOB) = GPIO_PIN_4;
    45.                 i++;
    46.                 if(i==10)i=0;
    47.                
    48.                 rtc_show_time();
    49.                
    50.                
    51.    }

    52. }
    复制代码
    这部分是RTC的闹钟中断函数,在该函数里面设置了点灯程序,当中断发生时,点亮由GPIOD下的PIN7引脚控制的LED。经过测试,当时间到达设定的闹钟时,LED可以点亮,即实验成功。
    1. void RTC_Alarm_IRQHandler(void)
    2. {
    3.     if(RESET != rtc_flag_get(RTC_STAT_ALRM0F)){
    4.         rtc_flag_clear(RTC_STAT_ALRM0F);
    5.         exti_flag_clear(EXTI_17);
    6.         GPIO_BOP(GPIOD) = GPIO_PIN_7;
    7.     }
    8. }
    复制代码
    IMG_20170423_141301.jpg


    在调试过程中,发现时间总是不能写到寄存器里,每次写入都会出现错误,后来给板子断电后,重新上电,就可以将时间写入寄存器内,这里应该是由于备份寄存器写保护了,还需要去查一下才可以确认

    GD32F450_Template.zip

    352 KB, 下载次数: 31

    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-5-20 06:24 , Processed in 0.110480 second(s), 16 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.