你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM8L151F3P6串口发送两字节只能收到1个0x3F的问题

[复制链接]
dybai 提问时间:2021-1-7 11:35 /
RT,使用串口发送一些数据,其中某些相邻的2个字节会变成1个字节的0x3F,不知道是什么原因,请问有遇到类似问题的大神吗?

比如通过串口发送数据:
C2 00 00 18 2E 00
用串口调试助手收到的数据是:
3F 00 18 2E 00

再比如通过串口发送数据:
80 D3 FF 2F
用串口调试助手收到的数据是:
80 3F 2F


情况并不是必现的,但是大部分情况都会发生,而且总是将两个字节变为 0x3F,很诡异。


初始化串口的代码:
  1. static void _usart_baudrate_config(uint32_t BaudRate)
  2. {
  3.     uint32_t BaudRate_Mantissa = 0;
  4.     uint32_t ClockFreq = bclk_get_sysclk_freq(); // 12MHz 时钟

  5.     BaudRate_Mantissa  = (uint32_t)(ClockFreq / BaudRate );
  6.     /* Set the fraction of USARTDIV */
  7.     USART1->BRR2 = (uint8_t)((BaudRate_Mantissa >> (uint8_t)8) & (uint8_t)0xF0);
  8.     /* Set the MSB mantissa of USARTDIV */
  9.     USART1->BRR2 |= (uint8_t)(BaudRate_Mantissa & (uint8_t)0x0F);
  10.     /* Set the LSB mantissa of USARTDIV */
  11.     USART1->BRR1 = (uint8_t)(BaudRate_Mantissa >> (uint8_t)4);
  12. }

  13. void init_433(void)
  14. {
  15.     // PC5/USART_TX --> RXD  推挽输出
  16.     GPIO_Init(GPIOC, GPIO_Pin_5, GPIO_Mode_Out_PP_High_Fast);
  17.     // PC6/USART_RX --> TXD  上拉输入
  18.     GPIO_Init(GPIOC, GPIO_Pin_6, GPIO_Mode_In_PU_No_IT);

  19.     // 配置串口时钟
  20.     CLK_PeripheralClockConfig(CLK_Peripheral_USART1, ENABLE);
  21.     SYSCFG_REMAPPinConfig(REMAP_Pin_USART1TxRxPortC, ENABLE);

  22.     // 初始化串口
  23.     USART_DeInit(USART1);
  24. //    GPIO_ExternalPullUpConfig(GPIOC, GPIO_Pin_5 | GPIO_Pin_6, ENABLE);
  25.     USART_Init(USART1, (uint32_t) 9600, USART_WordLength_8b, USART_StopBits_1, \
  26.         USART_Parity_No, USART_Mode_Tx | USART_Mode_Rx);
  27.     _usart_baudrate_config(9600); // 按照 12MHz 时钟重新配置波特率
  28.     // 使能串口
  29.     USART_Cmd(USART1, ENABLE);
  30. }
复制代码
串口发送数据代码:
  1. void send_byte_433(uint8_t data)
  2. {
  3.     USART_SendData8(USART1, data);
  4.     while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
  5.     USART_ClearFlag(USART1, USART_FLAG_TXE);
  6.     // bsp_delay(1000); // 加了延时也没用,还是会出现 0x3F
  7. }

  8. void send_data_433(const uint8_t *data, uint32_t len)
  9. {
  10.     uint32_t i = 0;

  11.     for (i = 0; i < len; i++)
  12.     {
  13.         send_byte_433(data[i]);
  14.     }
  15.     while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  16.     USART_ClearFlag(USART1, USART_FLAG_TC);
  17.     wait_send_433(len);
  18. }
复制代码





收藏 评论3 发布时间:2021-1-7 11:35

举报

3个回答
dybai 回答时间:2021-1-7 12:42:06
找到了一个复现问题的规律。
假设发送两个字节 a 和 b,满足以下条件时串口实际发送的数据就是 0x3F:
  1. ((a > 0x80) && (b < 80))  == 3F
复制代码


比如通过串口发送数据:
81 7F 81 80 80 7F 80 80
用串口调试助手收到的数据是:
3F 81 80 80 7F 80 80
80 3F 2F
刘东晨晨晨 回答时间:2021-1-9 16:22:00
不用中断发送呢
void send_byte_433(uint8_t data)
{
    USART_SendData8(USART1, data);
    while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
}

void send_data_433(const uint8_t *data, uint32_t len)
{
    uint32_t i = 0;

    for (i = 0; i < len; i++)
    {
        send_byte_433(data[i]);
    }
    wait_send_433(len);
}
butterflyspring 回答时间:2021-1-12 10:12:12
最好还是先用示波器看看实际发送的数据是否正确,尤其是波特率是否正确。 很多时候由于波特率的偏差,串口助手收到的数据未必正确。其次也可以看看两边的配置模式是否一致,尤其是串口助手的配置
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版