GD32 USART — 半双工收发

GD32 GD32F30x_Firmware_Library V3.0.3 USART 半双工收发 示例教学

USART — 半双工收发

固件库: GD32F30x_Firmware_Library V3.0.3
芯片: GD32
源文件: GD32F30x_Firmware_Library_V3.0.3/Examples/USART/Half_duplex_transmitter&receiver/main.c


功能简介

本示例演示串口半双工通信。同一根线上交替收发数据,节省一根线。常见于 RS485 总线。

硬件准备

  • USB 转串口模块(如 CH340、CP2102)
  • 连接:开发板 TX → 模块 RX,开发板 RX → 模块 TX,共地
  • 电脑端打开串口助手(如 SSCOM、XCOM),波特率与代码一致

完整代码

  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
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
#include "gd32f30x.h"
#include "gd32f307c_eval.h"
#define ARRAYNUM(arr_nanme)      (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))
#define TRANSMIT_SIZE0           (ARRAYNUM(transmitter_buffer0) - 1)
#define TRANSMIT_SIZE1           (ARRAYNUM(transmitter_buffer1) - 1)

int main(void)
{
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);
    
    /* enable USART and GPIOA clock */
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_USART1);

    /* configure USART0 Tx as alternate function open-drain */
    gpio_init(GPIOA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_9);
    /* configure USART1 Tx as alternate function open-drain */
    gpio_init(GPIOA, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
    
    /* USART0 and USART1 baudrate configuration */
    usart_baudrate_set(USART0, 115200);
    usart_baudrate_set(USART1, 115200);

    /* enable USART0 half duplex mode*/
    usart_halfduplex_enable(USART0);
    /* enable USART1 half duplex mode*/
    usart_halfduplex_enable(USART1);

    /* configure USART transmitter */
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_DISABLE);

    /* configure USART receiver */
    usart_receive_config(USART0, USART_RECEIVE_DISABLE);
    usart_receive_config(USART1, USART_RECEIVE_ENABLE);

    /* enable USART */
    usart_enable(USART0);
    usart_enable(USART1);

    /* clear the USART1 data register */
    usart_data_receive(USART1);

    /* USART0 transmit and USART1 receive */
    while(transfersize0--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART0, transmitter_buffer0[txcount0++]);
 
        while(RESET == usart_flag_get(USART1, USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer1 */
        receiver_buffer1[rxcount0++] = usart_data_receive(USART1);
    }

    /* configure USART transmitter */
    usart_transmit_config(USART0, USART_TRANSMIT_DISABLE);
    usart_transmit_config(USART1, USART_TRANSMIT_ENABLE);

    /* configure USART receiver */
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    usart_receive_config(USART1, USART_RECEIVE_DISABLE);

    /* clear the USART0 data register */
    usart_data_receive(USART0);

    /* USART1 transmit and USART0 receive */
    while(transfersize1--) {
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART1, USART_FLAG_TBE)) {
        }
        usart_data_transmit(USART1, transmitter_buffer1[txcount1++]);

        while(RESET == usart_flag_get(USART0,USART_FLAG_RBNE)) {
        }
        /* store the received byte in the receiver_buffer0 */
        receiver_buffer0[rxcount1++] = usart_data_receive(USART0);
    }

    /* compare the received data with the send ones */
    state1 = memory_compare(transmitter_buffer0, receiver_buffer1, TRANSMIT_SIZE0);
    state2 = memory_compare(transmitter_buffer1, receiver_buffer0, TRANSMIT_SIZE1);
    if(SUCCESS == state1) {
        /* if the data transmitted from USART0 and received by USART1 are the same */
        gd_eval_led_on(LED2);
    }else {
        /* if the data transmitted from USART0 and received by USART1 are not the same */
        gd_eval_led_off(LED2);
    }
    if(SUCCESS == state2) {
        /* if the data transmitted from USART1 and received by USART0 are the same */
        gd_eval_led_on(LED3);
    }else {
        /* if the data transmitted from USART1 and received by USART0 are not the same */
        gd_eval_led_off(LED3);
    }
    while(1) {
    }
}

代码讲解

GPIO 配置:设置引脚为输出/输入模式,选择推挽/开漏输出,配置上拉/下拉。

实验现象

  • 串口助手收到开发板发送的数据
  • 发送数据后开发板原样返回(回显)

注意事项

  • 串口助手波特率必须与代码一致
  • 检查 TX/RX 是否交叉连接
  • 共地是必须的
世界是你们
使用 Hugo 构建
主题 StackJimmy 设计