打印
[活动]

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

[复制链接]
417|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 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)中添加接收函数,接收到一个字节后再次进行接收。
void USART3_IRQHandler(void)
{
  /* USER CODE BEGIN USART3_IRQn 0 */

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


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

  /* Get the RTC current Time */
  HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN);
  /* Get the RTC current Date */
  HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN);
  /* Display time Format : hh:mm:ss */
  sprintf((char *)showtime, "%2d:%2d:%2d", stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds);
  /* Display date Format : mm-dd-yy */
  sprintf((char *)showdate, "%2d-%2d-%2d", sdatestructureget.Month, sdatestructureget.Date, 2000 + sdatestructureget.Year);
        
        dat[0] = stimestructureget.Hours;
        dat[1] = stimestructureget.Minutes;
        dat[2] = stimestructureget.Seconds;        
        dat[3] = sdatestructureget.Year;
        dat[4] = sdatestructureget.Month;
        dat[5] = sdatestructureget.Date;               
}

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

    /* USER CODE BEGIN 3 */
    RTC_CalendarShow(aShowTime, aShowDate);               
               
                if(recok)
                {
                        recok=0;
                        temp=Dat_trans(recbuf[1],recbuf[2]);
                        if(check_CRC()&&temp==MyAddr)
                        {
                                
                                switch(read_write_flag()&0x01)
                                {
                                        case Read:
                                                Read_byte1();
                                                break;
                                        case Write:
                                                Write_byte();
                                          break;
                                }
                        }
                }

  }
全部的Demo工程如下所示:
maoze.rar (29.36 MB)


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


使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

2698

主题

19150

帖子

103

粉丝