单片机 STM32F407开发板DMF407电机开发板平台keil V5.31HSE 为8MHZHSI为16MHZ主函数int main(void) { uint8_t hour, min, sec, ampm; uint8_t year, month, date, week; uint8_t tbuf[40]; uint8_t t 0; HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(115200); /* 串口初始化为115200 */ usmart_dev.init(84); /* 初始化USMART */ led_init(); /* 初始化LED */ lcd_init(); /* 初始化LCD */ rtc_init(); /* 初始化RTC */ rtc_set_wakeup(RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0); /* 配置WAKE UP中断, 1秒钟中断一次 */ lcd_show_string(30, 50, 200, 16, 16, STM32, RED); lcd_show_string(30, 70, 200, 16, 16, RTC TEST, RED); lcd_show_string(30, 90, 200, 16, 16, ATOMALIENTEK, RED); while (1) { t; if ((t % 10) 0) /* 每100ms更新一次显示数据 */ { rtc_get_time(hour, min, sec, ampm); sprintf((char *)tbuf, Time:%02d:%02d:%02d, hour, min, sec); lcd_show_string(30, 130, 210, 16, 16, (char*)tbuf, RED); rtc_get_date(year, month, date, week); sprintf((char *)tbuf, Date:20%02d-%02d-%02d, year, month, date); lcd_show_string(30, 150, 210, 16, 16, (char*)tbuf, RED); sprintf((char *)tbuf, Week:%d, week); lcd_show_string(30, 170, 210, 16, 16, (char*)tbuf, RED); } if ((t % 20) 0) { LED0_TOGGLE(); /* 每200ms,翻转一次LED0 */ } delay_ms(10); } }配置uint8_t rtc_init(void) { uint16_t bkpflag 0; g_rtc_handle.Instance RTC; g_rtc_handle.Init.HourFormat RTC_HOURFORMAT_24; /* RTC设置为24小时格式 */ g_rtc_handle.Init.AsynchPrediv 0x7F; /* RTC异步分频系数(1~0x7F) */ g_rtc_handle.Init.SynchPrediv 0xFF; /* RTC同步分频系数(0~0x7FFF) */ g_rtc_handle.Init.OutPut RTC_OUTPUT_DISABLE; g_rtc_handle.Init.OutPutPolarity RTC_OUTPUT_POLARITY_HIGH; g_rtc_handle.Init.OutPutType RTC_OUTPUT_TYPE_OPENDRAIN; /* 检查是不是第一次配置时钟 */ bkpflag rtc_read_bkr(RTC_BKP_DR0); /* 读取BKP0的值 */ if (HAL_RTC_Init(g_rtc_handle) ! HAL_OK) { return 1; } if ((bkpflag ! 0x5050) (bkpflag ! 0x5051)) /* 之前未初始化过, 重新配置 */ { rtc_set_time(23, 59, 56, RTC_HOURFORMAT12_AM); /* 设置时间, 根据实际时间修改 */ rtc_set_date(26, 5, 28, 17); /* 设置日期 */ } return 0; } void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) { uint16_t retry 200; RCC_OscInitTypeDef rcc_osc_init_handle; RCC_PeriphCLKInitTypeDef rcc_periphclk_init_handle; __HAL_RCC_RTC_ENABLE(); /* RTC使能 */ HAL_PWR_EnableBkUpAccess(); /* 取消备份区域写保护 */ __HAL_RCC_PWR_CLK_ENABLE(); /* 使能电源时钟PWR */ /* 使用寄存器的方式去检测LSE是否可以正常工作 */ RCC-BDCR | 1 0; /* 尝试开启LSE */ while (retry ((RCC-BDCR 0x02) 0)) /* 等待LSE准备好 */ { retry--; delay_ms(5); } if (retry 0) /* LSE起振失败 使用LSI */ { rcc_osc_init_handle.OscillatorType RCC_OSCILLATORTYPE_LSI; /* 选择要配置的振荡器 */ rcc_osc_init_handle.PLL.PLLState RCC_PLL_NONE; /* PLL不配置 */ rcc_osc_init_handle.LSIState RCC_LSI_ON; /* LSI状态:开启 */ HAL_RCC_OscConfig(rcc_osc_init_handle); /* 配置设置的rcc_oscinitstruct */ rcc_periphclk_init_handle.PeriphClockSelection RCC_PERIPHCLK_RTC; /* 选择要配置外设 RTC */ rcc_periphclk_init_handle.RTCClockSelection RCC_RTCCLKSOURCE_LSI; /* RTC时钟源选择LSI */ HAL_RCCEx_PeriphCLKConfig(rcc_periphclk_init_handle); /* 配置设置的rcc_periphclkinitstruct */ rtc_write_bkr(0, 0x5051); } else { rcc_osc_init_handle.OscillatorType RCC_OSCILLATORTYPE_LSE; /* 选择要配置的振荡器 */ rcc_osc_init_handle.PLL.PLLState RCC_PLL_NONE; /* PLL不配置 */ rcc_osc_init_handle.LSEState RCC_LSE_ON; /* LSE状态:开启 */ HAL_RCC_OscConfig(rcc_osc_init_handle); /* 配置设置的rcc_oscinitstruct */ rcc_periphclk_init_handle.PeriphClockSelection RCC_PERIPHCLK_RTC; /* 选择要配置外设RTC */ rcc_periphclk_init_handle.RTCClockSelection RCC_RTCCLKSOURCE_LSE; /* RTC时钟源选择LSE */ HAL_RCCEx_PeriphCLKConfig(rcc_periphclk_init_handle); /* 配置设置的rcc_periphclkinitstruct */ rtc_write_bkr(0, 0x5050); } __HAL_RCC_RTC_ENABLE(); /* RTC使能 */ } void rtc_set_wakeup(uint8_t wksel, uint16_t cnt) { __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(g_rtc_handle, RTC_FLAG_WUTF); /* 清除RTC WAKE UP的标志 */ HAL_RTCEx_SetWakeUpTimer_IT(g_rtc_handle, cnt, wksel); /* 设置重装载值和时钟 */ HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 2, 2); /* 抢占优先级2,子优先级2 */ HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn); } void RTC_WKUP_IRQHandler(void) { HAL_RTCEx_WakeUpTimerIRQHandler(g_rtc_handle); } void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) { LED1_TOGGLE(); } uint32_t rtc_read_bkr(uint32_t bkrx) { uint32_t temp 0; temp RTC_BASE 0x50 bkrx * 4; return (*(uint32_t *)temp); /* 返回读取到的值 */ } HAL_StatusTypeDef rtc_set_time(uint8_t hour, uint8_t min, uint8_t sec, uint8_t ampm) { RTC_TimeTypeDef rtc_time_handle; rtc_time_handle.Hours hour; rtc_time_handle.Minutes min; rtc_time_handle.Seconds sec; rtc_time_handle.TimeFormat ampm; rtc_time_handle.DayLightSaving RTC_DAYLIGHTSAVING_NONE; rtc_time_handle.StoreOperation RTC_STOREOPERATION_RESET; return HAL_RTC_SetTime(g_rtc_handle, rtc_time_handle, RTC_FORMAT_BIN); } HAL_StatusTypeDef rtc_set_date(uint8_t year, uint8_t month, uint8_t date, uint8_t week) { RTC_DateTypeDef rtc_date_handle; rtc_date_handle.Date date; rtc_date_handle.Month month; rtc_date_handle.WeekDay week; rtc_date_handle.Year year; return HAL_RTC_SetDate(g_rtc_handle, rtc_date_handle, RTC_FORMAT_BIN); }测试结果1s产生一次wakeup中断rtc_set_wakeup(RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 10); /* 配置WAKE UP中断, 10秒钟中断一次 */还可以利用RTC的入侵检测功能复用PC13或PI8防止产品被认为破坏。
单片机RTC实验
单片机 STM32F407开发板DMF407电机开发板平台keil V5.31HSE 为8MHZHSI为16MHZ主函数int main(void) { uint8_t hour, min, sec, ampm; uint8_t year, month, date, week; uint8_t tbuf[40]; uint8_t t 0; HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(115200); /* 串口初始化为115200 */ usmart_dev.init(84); /* 初始化USMART */ led_init(); /* 初始化LED */ lcd_init(); /* 初始化LCD */ rtc_init(); /* 初始化RTC */ rtc_set_wakeup(RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0); /* 配置WAKE UP中断, 1秒钟中断一次 */ lcd_show_string(30, 50, 200, 16, 16, STM32, RED); lcd_show_string(30, 70, 200, 16, 16, RTC TEST, RED); lcd_show_string(30, 90, 200, 16, 16, ATOMALIENTEK, RED); while (1) { t; if ((t % 10) 0) /* 每100ms更新一次显示数据 */ { rtc_get_time(hour, min, sec, ampm); sprintf((char *)tbuf, Time:%02d:%02d:%02d, hour, min, sec); lcd_show_string(30, 130, 210, 16, 16, (char*)tbuf, RED); rtc_get_date(year, month, date, week); sprintf((char *)tbuf, Date:20%02d-%02d-%02d, year, month, date); lcd_show_string(30, 150, 210, 16, 16, (char*)tbuf, RED); sprintf((char *)tbuf, Week:%d, week); lcd_show_string(30, 170, 210, 16, 16, (char*)tbuf, RED); } if ((t % 20) 0) { LED0_TOGGLE(); /* 每200ms,翻转一次LED0 */ } delay_ms(10); } }配置uint8_t rtc_init(void) { uint16_t bkpflag 0; g_rtc_handle.Instance RTC; g_rtc_handle.Init.HourFormat RTC_HOURFORMAT_24; /* RTC设置为24小时格式 */ g_rtc_handle.Init.AsynchPrediv 0x7F; /* RTC异步分频系数(1~0x7F) */ g_rtc_handle.Init.SynchPrediv 0xFF; /* RTC同步分频系数(0~0x7FFF) */ g_rtc_handle.Init.OutPut RTC_OUTPUT_DISABLE; g_rtc_handle.Init.OutPutPolarity RTC_OUTPUT_POLARITY_HIGH; g_rtc_handle.Init.OutPutType RTC_OUTPUT_TYPE_OPENDRAIN; /* 检查是不是第一次配置时钟 */ bkpflag rtc_read_bkr(RTC_BKP_DR0); /* 读取BKP0的值 */ if (HAL_RTC_Init(g_rtc_handle) ! HAL_OK) { return 1; } if ((bkpflag ! 0x5050) (bkpflag ! 0x5051)) /* 之前未初始化过, 重新配置 */ { rtc_set_time(23, 59, 56, RTC_HOURFORMAT12_AM); /* 设置时间, 根据实际时间修改 */ rtc_set_date(26, 5, 28, 17); /* 设置日期 */ } return 0; } void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc) { uint16_t retry 200; RCC_OscInitTypeDef rcc_osc_init_handle; RCC_PeriphCLKInitTypeDef rcc_periphclk_init_handle; __HAL_RCC_RTC_ENABLE(); /* RTC使能 */ HAL_PWR_EnableBkUpAccess(); /* 取消备份区域写保护 */ __HAL_RCC_PWR_CLK_ENABLE(); /* 使能电源时钟PWR */ /* 使用寄存器的方式去检测LSE是否可以正常工作 */ RCC-BDCR | 1 0; /* 尝试开启LSE */ while (retry ((RCC-BDCR 0x02) 0)) /* 等待LSE准备好 */ { retry--; delay_ms(5); } if (retry 0) /* LSE起振失败 使用LSI */ { rcc_osc_init_handle.OscillatorType RCC_OSCILLATORTYPE_LSI; /* 选择要配置的振荡器 */ rcc_osc_init_handle.PLL.PLLState RCC_PLL_NONE; /* PLL不配置 */ rcc_osc_init_handle.LSIState RCC_LSI_ON; /* LSI状态:开启 */ HAL_RCC_OscConfig(rcc_osc_init_handle); /* 配置设置的rcc_oscinitstruct */ rcc_periphclk_init_handle.PeriphClockSelection RCC_PERIPHCLK_RTC; /* 选择要配置外设 RTC */ rcc_periphclk_init_handle.RTCClockSelection RCC_RTCCLKSOURCE_LSI; /* RTC时钟源选择LSI */ HAL_RCCEx_PeriphCLKConfig(rcc_periphclk_init_handle); /* 配置设置的rcc_periphclkinitstruct */ rtc_write_bkr(0, 0x5051); } else { rcc_osc_init_handle.OscillatorType RCC_OSCILLATORTYPE_LSE; /* 选择要配置的振荡器 */ rcc_osc_init_handle.PLL.PLLState RCC_PLL_NONE; /* PLL不配置 */ rcc_osc_init_handle.LSEState RCC_LSE_ON; /* LSE状态:开启 */ HAL_RCC_OscConfig(rcc_osc_init_handle); /* 配置设置的rcc_oscinitstruct */ rcc_periphclk_init_handle.PeriphClockSelection RCC_PERIPHCLK_RTC; /* 选择要配置外设RTC */ rcc_periphclk_init_handle.RTCClockSelection RCC_RTCCLKSOURCE_LSE; /* RTC时钟源选择LSE */ HAL_RCCEx_PeriphCLKConfig(rcc_periphclk_init_handle); /* 配置设置的rcc_periphclkinitstruct */ rtc_write_bkr(0, 0x5050); } __HAL_RCC_RTC_ENABLE(); /* RTC使能 */ } void rtc_set_wakeup(uint8_t wksel, uint16_t cnt) { __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(g_rtc_handle, RTC_FLAG_WUTF); /* 清除RTC WAKE UP的标志 */ HAL_RTCEx_SetWakeUpTimer_IT(g_rtc_handle, cnt, wksel); /* 设置重装载值和时钟 */ HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 2, 2); /* 抢占优先级2,子优先级2 */ HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn); } void RTC_WKUP_IRQHandler(void) { HAL_RTCEx_WakeUpTimerIRQHandler(g_rtc_handle); } void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) { LED1_TOGGLE(); } uint32_t rtc_read_bkr(uint32_t bkrx) { uint32_t temp 0; temp RTC_BASE 0x50 bkrx * 4; return (*(uint32_t *)temp); /* 返回读取到的值 */ } HAL_StatusTypeDef rtc_set_time(uint8_t hour, uint8_t min, uint8_t sec, uint8_t ampm) { RTC_TimeTypeDef rtc_time_handle; rtc_time_handle.Hours hour; rtc_time_handle.Minutes min; rtc_time_handle.Seconds sec; rtc_time_handle.TimeFormat ampm; rtc_time_handle.DayLightSaving RTC_DAYLIGHTSAVING_NONE; rtc_time_handle.StoreOperation RTC_STOREOPERATION_RESET; return HAL_RTC_SetTime(g_rtc_handle, rtc_time_handle, RTC_FORMAT_BIN); } HAL_StatusTypeDef rtc_set_date(uint8_t year, uint8_t month, uint8_t date, uint8_t week) { RTC_DateTypeDef rtc_date_handle; rtc_date_handle.Date date; rtc_date_handle.Month month; rtc_date_handle.WeekDay week; rtc_date_handle.Year year; return HAL_RTC_SetDate(g_rtc_handle, rtc_date_handle, RTC_FORMAT_BIN); }测试结果1s产生一次wakeup中断rtc_set_wakeup(RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 10); /* 配置WAKE UP中断, 10秒钟中断一次 */还可以利用RTC的入侵检测功能复用PC13或PI8防止产品被认为破坏。