航顺HC32F103C8T6串口通信失败问题解决

本文讲述了在使用航顺HK32F103C8T6替换STM32 MCU后,遇到的串口通信失败问题。问题源于115200波特率下累积误差导致的数据接收错误。通过航顺官方应用笔记,发现调整波特率为116352可以解决该问题。文章强调了高速通信中波特率精确性的重要性,并建议制造商在规格书中明确这类潜在问题。
摘要由CSDN通过智能技术生成

STM的MCU价格一路缺货飙涨,为降低成本使用航顺的MCU替换。HC32F103C8T6与中移M5311串口通信,波特率为115200,8N1格式。通信时发现失败的几率非常大,简单的发个“AT\r\n”有时候都识别不了。一开始怀疑是串口波形问题,示波器检查后发现HC发送数据波形完全正常,接收数据波形顶部稍微有点斜坡。如下图所示:
在这里插入图片描述所以考虑可能是由于斜坡导致HC32接收数据失败。原来设计是采用的2个三极管在3.3V和1.8V之间进行电平转换,为了验证是否是这个问题,直接打了样板使用专门的电平转换芯片接在HC32F103C8T6和M5311之间,结果是涛声依旧。HC发送指令后,M5311回应正常,但是HC还是接收错误,表现为串口DMA根本收不到数据。
一个问题调试耽误了两三天时间,反复的查HC32F103的规格书,也没有发现任何异常。最后在看航顺官方发布的一个应用笔记里,发现了问题根源—累积误差。全名是《HK32F103应用笔记V1.0.32》。
在这里插入图片描述从官方的笔记里可以看出,第六个字节都已经接收错误了。官方给出3种解决方案:
在这里插入图片描述
直接采用第二种,把HC32F103C8T6的波特率从115200修改为116352,重新烧录测试发现HC接收数据正常,问题得到解决。

/* USART1 init function */

void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 116352;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
}

HC官方说 波特率偏差小于1%,这个对于低速率的通信来说估计还能匹配。速率高一点,由于时间累积产生的误差必然导致通信失败。也是因为这不到1%的误差,耽误硬件调试好几天功夫。建议HC在规格书里说清楚,不要放在应用笔记里,好像是羞羞答答不愿意直面自身缺陷似的。最后放一张测试的时间累计误差对比图。
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
stm32f103c8t6是一款常用的单片机,而HC-05是一款常见的蓝牙模块。在使用stm32f103c8t6与HC-05进行蓝牙通信时,需要编写相应的源码来实现通信功能。 以下是一个简单的示例代码,用于在stm32f103c8t6上使用HC-05进行蓝牙通信: ```c #include "stm32f10x.h" #include "stdio.h" void USART1_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置USART1的引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置USART1 USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); // 使能USART1 USART_Cmd(USART1, ENABLE); } void USART1_SendChar(char ch) { while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) ; USART_SendData(USART1, (uint8_t)ch); } int fputc(int ch, FILE *f) { USART1_SendChar(ch); return ch; } int main(void) { USART1_Init(); printf("Hello, Bluetooth!\n"); while (1) { // 接收蓝牙数据 if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) { char data = USART_ReceiveData(USART1); // 处理接收到的数据 // ... } } } ``` 这段代码实现了在stm32f103c8t6上初始化USART1串口,并通过printf函数向串口发送数据。同时,通过轮询的方式接收蓝牙模块发送的数据,并进行相应的处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydgd118

您的鼓励是我最大的动力!谢赏!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值