MCU Limitations

简单记录一下工作中,遇到的MCU勘误。

GD32e230xx

使用单线串口实现485通讯 需要软件干预串口是处于发送还是接收状态

当前环境

  1. 使用USART0 PA9 端口
    原理图
  2. 串口初始化时配置为TX RX都使能;切换发送和接收时只切换485的DE RE引脚上的电平
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#define RXMODE()      gpio_bit_reset(GPIOA,GPIO_PIN_0)
#define TXMODE() gpio_bit_set(GPIOA,GPIO_PIN_0)
void serial_init(void)
{
USART_CTL0(USART0) &= ~USART_CTL0_WL;
USART_BAUD(USART0) = 0x271;
USART_CTL2(USART0) |= USART_CTL2_HDEN;
USART_CTL0(USART0) |= USART_CTL0_TEN | USART_CTL0_REN | USART_CTL0_UEN;
}

void uartSend(uint8_t *buf, uint8_t len)
{
for (uint8_t i = 0; i < len; i++)
{
USART_TDATA(USART0) = *buf++;
while (RESET == usart_flag_get(USART0, USART_FLAG_TC));
usart_flag_clear(USART0, USART_FLAG_TC);
}
}

void uartRecive(void)
{
while(1)
{
if (usart_flag_get(USART0, USART_FLAG_RBNE))
{
// recive uasrt data

// to do responed
TXMODE();
uartSend();
RXMODE();
}
}
}

遇到问题

  1. MCU回复主机命令后,可以看到,MCU又接收到了一个字节的数据(此时主机并没有发送数据),这个字节的数据和MCU自己发送的第一个字节相同
    异常数据

解惑

  1. 在GD32e23x用户手册中写明了:通讯冲突由软件处理
    问题出处
  2. 推理:MCU初始化串口时同时开启了TX 和 RX,在MCU回包时RX没有关闭,导致MCU把TX的数据认为时RX的数据,由于RX的缓冲区RDATA只有一个深度,仅在被MCU读出后才能接收新的数据,因此当MCU发送完所有数据后,MCU判断到有新的串口数据。

解决方案

  1. MCU串口初始化时进开启RX
  2. MCU在回包时打开TX,关闭RX
  3. MCU在回包结束后关闭TX,打开RX
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#define RXMODE()    \
do { \
gpio_bit_reset(GPIOA,GPIO_PIN_0); \
usart_transmit_config(USART0, USART_TRANSMIT_DISABLE); \
usart_receive_config(USART0, USART_RECEIVE_ENABLE); \
}while(0)
#define TXMODE() \
do { \
gpio_bit_set(GPIOA,GPIO_PIN_0); \
usart_receive_config(USART0, USART_RECEIVE_DISABLE); \
usart_transmit_config(USART0, USART_TRANSMIT_ENABLE); \
}while(0)

void serial_init(void)
{
USART_CTL0(USART0) &= ~USART_CTL0_WL;
USART_BAUD(USART0) = 0x271;
USART_CTL2(USART0) |= USART_CTL2_HDEN;
USART_CTL0(USART0) |= USART_CTL0_REN | USART_CTL0_UEN;
}