[活动] 我的硬件狂想作品2--B-G474E-DPOW1的RTC和USART的开发

[复制链接]
767|0
 楼主| xyz549040622 发表于 2020-11-16 06:15 | 显示全部楼层 |阅读模式
本帖最后由 xyz549040622 于 2020-11-28 10:06 编辑

首先感谢贸泽电子提供的这次试用机会,让我拿到了B-G474E-DPOW1这块开发板。
上一个帖子中提到了开发所需要的所有软件,这次准备用B-G474E-DPOW1自带的RTC外设做一个万年历时钟,考虑到诸如12864之类的显示已经被大家做烂了,而且显示不直观,界面维护要求高,所以我使用了国产的组态软件组态王和B-G474E-DPOW1通过st-link的虚拟串口进行数据的交互。

程序的开发直接使用STM32CubeMx软件进行配置。
直接使用开发板B-G474E-DPOW1的模板进行配置,导入模板后,属于该开发板的外设和时钟已经配置完毕。首先需要修改的是串口的配置。由于组态王的单片机协议最大只支持19200的速率,考虑到我电脑usb延长线比较长,这里设置波特率为9600,数据位设置为8位,无校验位即可。这里需要注意的是,STM32CubeMx配置USART的数据位时,该数据位是包含校验位在内的,和我们平常的认知是不一样的,这里的坑比较大。也就是说,当我们需要配置常规的8数据位,1校验位时,CubeMx配置的数据位应该是9。当我们需要配置常规的8数据位,无校验位时,CubeMx配置的数据位应该是8。配置截图如下所示,串口配置为发送和中断接收都需要中断。




然后是RTC的配置







然后选择生成代码即可,我这里选择的是MDK和V5的版本。


下面进行的是代码的修改和配置。

首先是串口接收中断的配置。
1.在main函数的大循环前使能串口接收中断,接收1个字节到缓存字节。
        HAL_UART_Receive_IT(&huart3, &aRxByte, 1);
2.在void USART3_IRQHandler(void)中添加接收函数,接收到一个字节后再次进行接收。
  1. void USART3_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN USART3_IRQn 0 */

  4.   /* USER CODE END USART3_IRQn 0 */
  5.   HAL_UART_IRQHandler(&huart3);
  6.   /* USER CODE BEGIN USART3_IRQn 1 */
  7.         HAL_UART_Receive_IT(&huart3, &aRxByte, 1);
  8.   /* USER CODE END USART3_IRQn 1 */
  9. }
3.然后是根据组态王单片机的驱动协议,进行接收callback函数的配置。根据接收到的帧头和帧尾进行判断是否是组态王发过来的指令,如果是,保存指令,然后进行解析。
  1. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
  2. {
  3.         //    HAL_GPIO_TogglePin(LD3_GPIO_Port, LD3_Pin);               
  4.         recok=0;
  5.         if(!flag)
  6.                 if(aRxByte==Start)         //检查接收的是否是字头
  7.                 flag=1;
  8.         if(flag==1)          //接收为字头
  9.         {
  10.                 recbuf[count]=aRxByte;
  11.                 count++;
  12.                 if(aRxByte==End)        //检查接收的为字尾
  13.                 {
  14.                         recok=1;
  15.                         count=0;
  16.                         flag=0;
  17.                 }
  18.         }        
  19. }
4.在main函数的while循环中进行指令的解析,并进行数据的回复和交互。详细的协议和解析代码具体见工程中。
  1.   if(recok)
  2.                 {
  3.                         recok=0;
  4.                         temp=Dat_trans(recbuf[1],recbuf[2]);
  5.                         if(check_CRC()&&temp==MyAddr)
  6.                         {
  7.                                 
  8.                                 switch(read_write_flag()&0x01)
  9.                                 {
  10.                                         case Read:
  11.                                                 Read_byte1();
  12.                                                 break;
  13.                                         case Write:
  14.                                                 Write_byte();
  15.                                           break;
  16.                                 }
  17.                         }
  18.                 }


然后我们进行RTC时钟的读取。增加RTC时钟和日期读取函数。
  1. /* USER CODE BEGIN 4 */
  2. static void RTC_CalendarShow(uint8_t *showtime, uint8_t *showdate)
  3. {
  4.   RTC_DateTypeDef sdatestructureget;
  5.   RTC_TimeTypeDef stimestructureget;

  6.   /* Get the RTC current Time */
  7.   HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
  8.   /* Get the RTC current Date */
  9.   HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
  10.   /* Display time Format : hh:mm:ss */
  11.   sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
  12.   /* Display date Format : mm-dd-yy */
  13.   sprintf((char *)showdate, "%2d-%2d-%2d", sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year);
  14.         
  15.         dat[0] = stimestructureget.Hours;
  16.         dat[1] = stimestructureget.Minutes;
  17.         dat[2] = stimestructureget.Seconds;        
  18.         dat[3] = sdatestructureget.Year;
  19.         dat[4] = sdatestructureget.Month;
  20.         dat[5] = sdatestructureget.Date;               
  21. }

通过上面的代码,我们把当前的时间和日期,赋值给了sdatestructuregheet和stimestructureget这两个结构体,访问他们的成员即可获取当前的时间和日期值。main函数中循环读取RTC_CalendarShow函数即可。
  1.   while (1)
  2.   {
  3.     /* USER CODE END WHILE */

  4.     /* USER CODE BEGIN 3 */
  5.     RTC_CalendarShow(aShowTime, aShowDate);               
  6.                
  7.                 if(recok)
  8.                 {
  9.                         recok=0;
  10.                         temp=Dat_trans(recbuf[1],recbuf[2]);
  11.                         if(check_CRC()&&temp==MyAddr)
  12.                         {
  13.                                 
  14.                                 switch(read_write_flag()&0x01)
  15.                                 {
  16.                                         case Read:
  17.                                                 Read_byte1();
  18.                                                 break;
  19.                                         case Write:
  20.                                                 Write_byte();
  21.                                           break;
  22.                                 }
  23.                         }
  24.                 }

  25.   }
全部的Demo工程如下所示:



未完待续,欢迎观看第一篇和第三篇
我的硬件狂想作品1--B-G474E-DPOW1开发准备
我的硬件狂想作品3--B-G474E-DPOW1和组态王的通讯


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

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

本版积分规则

个人签名:qq群: 嵌入式系统arm初学者 224636155←← +→→点击-->小 i 精品课全集,21ic公开课~~←←→→点击-->小 i 精品课全集,给你全方位的技能策划~~←←

2841

主题

19330

帖子

110

粉丝
快速回复 在线客服 返回列表 返回顶部