搜索
查看: 848|回复: 3

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

[复制链接]

该用户从未签到

1

主题

2

帖子

0

蝴蝶豆

新手上路

最后登录
2021-1-11
发表于 2021-1-7 11:35:52 | 显示全部楼层 |阅读模式
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. }
复制代码





回复

使用道具 举报

该用户从未签到

1

主题

2

帖子

0

蝴蝶豆

新手上路

最后登录
2021-1-11
 楼主| 发表于 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
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

6

帖子

0

蝴蝶豆

新手上路

最后登录
2021-3-19
发表于 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);
}
回复 支持 反对

使用道具 举报

该用户从未签到

3

主题

1306

帖子

929

蝴蝶豆

版主

最后登录
2021-3-31
发表于 2021-1-12 10:12:12 | 显示全部楼层
最好还是先用示波器看看实际发送的数据是否正确,尤其是波特率是否正确。 很多时候由于波特率的偏差,串口助手收到的数据未必正确。其次也可以看看两边的配置模式是否一致,尤其是串口助手的配置
回复 支持 反对

使用道具 举报

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

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|论坛-意法半导体STM32/STM8技术社区

GMT+8, 2024-4-26 18:06 , Processed in 0.146461 second(s), 32 queries .

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表