TA的每日心情 | 奋斗 2024-9-22 22:20 |
---|
签到天数: 944 天 连续签到: 1 天 [LV.10]以坛为家III
|
液晶屏成功驱动后,首先想到的是做一个闹钟。GD32F450自带RTC模块,详细如下:
RTC可以计时,也可以设置闹钟,这次没有设定键盘,所以不能调节时间,只能在代码里设置好,并设定一个闹钟,闹钟时间到时,可以出发中断去执行特定操作,这里是让程序点亮LED,如果接蜂鸣器,就是闹铃了。
下面部分是预设值函数,由于小红板没有外部32K晶振,只能选择内部时钟,所以需要提前声明RTC_CLOCK_SOURCE_IRC32K一下,这样初始化时会使用内部时钟,如果选用外部时钟是无法工作的。- void rtc_pre_config(void)
- {
- #if defined (RTC_CLOCK_SOURCE_IRC32K)
- rcu_osci_on(RCU_IRC32K);
- rcu_osci_stab_wait(RCU_IRC32K);
- rcu_rtc_clock_config(RCU_RTCSRC_IRC32K);
-
- prescaler_s = 0x13F;
- prescaler_a = 0x63;
- #elif defined (RTC_CLOCK_SOURCE_LXTAL)
- rcu_osci_on(RCU_LXTAL);
- rcu_osci_stab_wait(RCU_LXTAL);
- rcu_rtc_clock_config(RCU_RTCSRC_LXTAL);
-
- prescaler_s = 0xFF;
- prescaler_a = 0x7F;
- #else
- #error RTC clock source should be defined.
- #endif /* RTC_CLOCK_SOURCE_IRC32K */
- rcu_periph_clock_enable(RCU_RTC);
- rtc_register_sync_wait();
- }
复制代码 这部分是RTC设置函数,在里面进行了时间和日期的设置,并且设定了闹钟,(此处时间与真实时间不符)。- void rtc_setup(void)
- {
- /* setup RTC time value */
- uint32_t tmp_hh = 0xFF, tmp_mm = 0xFF, tmp_ss = 0xFF;
- rtc_initpara.factor_asyn = prescaler_a;
- rtc_initpara.factor_syn = prescaler_s;
- rtc_initpara.year = 0x16;
- rtc_initpara.day_of_week = RTC_SATURDAY;
- rtc_initpara.month = RTC_APR;
- rtc_initpara.date = 0x30;
- rtc_initpara.display_format = RTC_24HOUR;
- rtc_initpara.am_pm = RTC_AM;
- /* setup RTC alarm */
- tmp_hh = 0X19;
- tmp_mm = 0X40;
- tmp_ss = 0X20;
- rtc_initpara.hour = tmp_hh;
- rtc_initpara.minute = tmp_mm;
- rtc_initpara.second = tmp_ss;
- /* RTC current time configuration */
- if(ERROR == rtc_init(&rtc_initpara)){
- //GPIO_BOP(GPIOD) = GPIO_PIN_7;
- Gui_DrawFont_GBK16(30, 40, RED, GRAY0,"failed");
- }else{
- //GPIO_BC(GPIOD) = GPIO_PIN_7;
- Gui_DrawFont_GBK16(30, 40, RED, GRAY0,"ok");
- rtc_show_time();
- RTC_BKP0 = BKP_VALUE;
- }
- rtc_alarm_disable(RTC_ALARM0);
- rtc_alarm.alarm_mask = RTC_ALARM_DATE_MASK|RTC_ALARM_HOUR_MASK|RTC_ALARM_MINUTE_MASK;
- rtc_alarm.weekday_or_date = RTC_ALARM_DATE_SELECTED;
- rtc_alarm.alarm_day = 0x31;
- rtc_alarm.am_pm = RTC_AM;
- /* RTC alarm input */
- tmp_hh = 0x19;
- tmp_mm = 0X41;
- tmp_ss = 0x20;
- rtc_alarm.alarm_hour = tmp_hh;
- rtc_alarm.alarm_minute = tmp_mm;
- rtc_alarm.alarm_second = tmp_ss;
- /* RTC alarm configuration */
- rtc_alarm_config(RTC_ALARM0,&rtc_alarm);
- rtc_show_alarm();
- rtc_interrupt_enable(RTC_INT_ALARM0);
- rtc_alarm_enable(RTC_ALARM0);
- }
复制代码 这两个函数是显示闹钟和时间的函数,主要使用了sprintf函数,将得到的数据转换为字符格式送到显示屏上。- void rtc_show_time(void)
- {
- uint32_t time_subsecond = 0;
- uint8_t subsecond_ss = 0,subsecond_ts = 0,subsecond_hs = 0;
- rtc_current_time_get(&rtc_initpara);
- /* get the subsecond value of current time, and convert it into fractional format */
- time_subsecond = rtc_subsecond_get();
- subsecond_ss=(1000-(time_subsecond*1000+1000)/400)/100;
- subsecond_ts=(1000-(time_subsecond*1000+1000)/400)%100/10;
- subsecond_hs=(1000-(time_subsecond*1000+1000)/400)%10;
-
- sprintf((char *)buf,"%0.2x:%0.2x:%0.2x.%d%d%d \n\r", \
- rtc_initpara.hour, rtc_initpara.minute, rtc_initpara.second,\
- subsecond_ss, subsecond_ts, subsecond_hs);
-
- Gui_DrawFont_GBK16(0, 80, RED, GRAY0, buf);
- }
- void rtc_show_alarm(void)
- {
- rtc_alarm_get(RTC_ALARM0,&rtc_alarm);
- sprintf((char*)buf,"alarm:%0.2x:%0.2x:%0.2x \n\r", rtc_alarm.alarm_hour, rtc_alarm.alarm_minute,\
- rtc_alarm.alarm_second);
- Gui_DrawFont_GBK16(0, 60, RED, GRAY0, buf);
- }
复制代码 这一部分是主函数- int main(void)
- {
- u8 i=0;
- u16 color=0;
- systick_config();
- led_init();
- Lcd_Init(2);
- Lcd_Clear(GRAY0);
- /* enable PMU clock */
- rcu_periph_clock_enable(RCU_PMU);
- /* enable the access of the RTC registers */
- pmu_backup_write_enable();
- rtc_pre_config();
-
- if (BKP_VALUE != RTC_BKP0){
- rtc_setup();
- }else{
-
- if (RESET != rcu_flag_get(RCU_FLAG_PORRST)){
- // Gui_DrawFont_GBK16(30, 40, RED, GRAY0,"power on");
- }else if (RESET != rcu_flag_get(RCU_FLAG_EPRST)){
- // printf("external reset occurred....\n\r");
- }
- // printf("no need to configure RTC....\n\r");
-
- rtc_flag_clear(RTC_STAT_ALRM0F);
- exti_flag_clear(EXTI_17);
- rtc_show_time();
- rtc_show_alarm();
- }
-
- rcu_all_reset_flag_clear();
- /* RTC alarm interrupt configuration */
- exti_init(EXTI_17,EXTI_INTERRUPT,EXTI_TRIG_RISING);
- nvic_irq_enable(RTC_Alarm_IRQn,0,0);
-
- // Gui_DrawFont_GBK16(30, 40, RED, GRAY0, "eeboard");
- // Gui_DrawFont_GBK24(20, 60, BLUE, GRAY0, "GD32F450VE");
- // Gui_DrawFont_GBK24(30, 20, BLUE, GRAY0, "ID:9robot");
- while(1)
- {
- // Gui_DrawFont_Num32(20, 100, RED, GRAY0, i);
- GPIO_TG(GPIOB) = GPIO_PIN_3;
- delay_1ms(500);
- GPIO_TG(GPIOB) = GPIO_PIN_4;
- i++;
- if(i==10)i=0;
-
- rtc_show_time();
-
-
- }
- }
复制代码 这部分是RTC的闹钟中断函数,在该函数里面设置了点灯程序,当中断发生时,点亮由GPIOD下的PIN7引脚控制的LED。经过测试,当时间到达设定的闹钟时,LED可以点亮,即实验成功。- void RTC_Alarm_IRQHandler(void)
- {
- if(RESET != rtc_flag_get(RTC_STAT_ALRM0F)){
- rtc_flag_clear(RTC_STAT_ALRM0F);
- exti_flag_clear(EXTI_17);
- GPIO_BOP(GPIOD) = GPIO_PIN_7;
- }
- }
复制代码
在调试过程中,发现时间总是不能写到寄存器里,每次写入都会出现错误,后来给板子断电后,重新上电,就可以将时间写入寄存器内,这里应该是由于备份寄存器写保护了,还需要去查一下才可以确认
|
|