回答

收藏

GD32F450学习——RTC实验

GD32 GD32 6471 人阅读 | 0 人回复 | 2017-04-23

液晶屏成功驱动后,首先想到的是做一个闹钟。GD32F450自带RTC模块,详细如下:



       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. }
复制代码


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

GD32F450_Template.zip

352 KB, 下载次数: 41

分享到:
回复

使用道具 举报

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

本版积分规则

关闭

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