本帖最后由 damiaa 于 2024-3-13 23:59 编辑
【ST NUCLEO-U5A5ZJ-Q开发板测评】8 串口打印和时钟
时钟始终是嵌入式设备里面比较重要的外设,很多与人打交道的设备都要用到时钟,比如闹钟,手表,手机,等等。所以熟悉 时钟的外设处理也是非常必要的。
下面我们开始这方面的实验。
一、打开stm32cubeide,配置时钟
RCC配置HSE和LSE 外部晶体
RTC选择Activate Clock Source(时钟源)和 Activate Calendar(日历)
再去检查时钟配置(Clock Config) 选LSE
这里有时钟和日历,可以在这里配置,也可以在运行时设置
如果加入闹钟,下面就会出现闹钟的一些参数,可以在这里配置,也可以在运行时设置。
并且有闹钟的中断可以选择:
这样32.768的外部时钟就连接到RTC了。时钟日历也配置好了。
二、生成代码介绍
选择后保存产生代码。
main.c中就有了
Rtc结构句柄的定义
有RTC初始化程序
stm32u5xx_it.c有了报警中断的添加
RTC初始化程序中有时钟日历设置和报警闹钟的设置代码,可以拷贝过去直接使用。
三、加入代码
因为选择了报警中断A,如果要处理这个中断主程序中就要添加这个回调函数(选择了其他中断就要加入其他中断的回调函数)。
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
}
如果选择了报警B或其他中断也是和这类似的处理。
关于回调函数,ST还提供了一个HAL_RTC_RegisterCallback来注册自己的回调函数,但还要配置USE_HAL_RTC_REGISTER_CALLBACKS 为1 .这个麻烦。还不如使用同名的回调函数省事。其实其他中断也有这操作 比如串口什么的。
关于时间和日历的设置,初始化里面有了,可以搬来照抄。
如何读出时间和日历,这个我们在stm32u5xx_hal_rtc.c里面都可以找到它们的原型。
最后在主程序中加代码
- 初始化中就设置了时间,日期,报警等等,这里就先不管这个。
- 做一个串口读的命令解析:
getDT +0x0d(回车)
- 然后读出日期,时间和周
- 回调函数中加入读命令解析程序,如果有读命令,做个标记。
- 主程序中发现有读标记就读取时间,日期,和周,并发送到串口。
- 同时搞个灯绿色提示一下
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)中加入解析命令
if((rx1_b[0] == 'g')&&(rx1_b[1] == 'e')&&(rx1_b[2] == 't')&&(rx1_b[3] == 'D')&&(rx1_b[4] == 'T')&&(rx1_b_index >=6))
{
setRTCflag=0x11;
}
主程序中处理:
switch(setRTCflag)
{
case 0x03:
//setT 12 30 09
//setD 2 2 11 2024
//setA 23 32 00 00
if (HAL_RTC_SetTime(&hrtc, &sTime2, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
break;
case 0x05:
if (HAL_RTC_SetDate(&hrtc, &sDate2, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
break;
/** Enable the Alarm A*/
case 0x09:
if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm2, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
break;
case 0x11:
if(HAL_RTC_GetTime(&hrtc, &sTime2, RTC_FORMAT_BIN) == HAL_OK)
{
char uart_buf[100]={0};
HAL_RTC_GetDate(&hrtc, &sDate2, RTC_FORMAT_BIN);
char str[25]={0};
switch(sDate2.WeekDay)
{
case 1:
sprintf(str,"WeekDay is MONDAY\n");
break;
case 2:
sprintf(str,"WeekDay is TUESDAY\n");
break;
case 3:
sprintf(str,"WeekDay is WEDNESDAY\n");
break;
case 4:
sprintf(str,"WeekDay is THURSDAY\n");
break;
case 5:
sprintf(str,"WeekDay is FRIDAY\n");
break;
case 6:
sprintf(str,"WeekDay is SATURDAY\n");
break;
case 7:
sprintf(str,"WeekDay is SUNDAY\n");
break;
}
sprintf(uart_buf,"Date is 20%2d-%02d-%02d \n Time is %02d : %02d : %02d \n %s\n ",sDate2.Year,sDate2.Month,sDate2.Date,sTime2.Hours,sTime2.Minutes,sTime2.Seconds,str);
HAL_UART_Transmit_IT(&huart1,(const uint8_t*)&uart_buf[0], 100);
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_SET);
HAL_Delay(100);
HAL_GPIO_WritePin(LED_GREEN_GPIO_Port, LED_GREEN_Pin, GPIO_PIN_RESET);
}
break;
default:break;
}
setRTCflag =0;
编译下载调试,实验验证:
设置时间部分初始化代码里面有,这里就不介绍了。先汇报到这里。谢谢