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/Synchronous/main.c


功能简介

本示例演示 USART 串口通信。串口是最基本的通信接口,几乎每个嵌入式项目都会用到。

硬件准备

  • 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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include "gd32f30x.h"
#include "gd32f307c_eval.h"
#include <stdio.h>
#define txbuffer_size1   (countof(txbuffer1) - 1)
#define txbuffer_size2   (countof(txbuffer2) - 1)
#define DYMMY_BYTE       0x00
#define countof(a)       (sizeof(a) / sizeof(*(a)))

void usart_config(void);
void spi_config(void);
void led_init(void);
ErrStatus memory_compare(uint8_t* src, uint8_t* dst, uint16_t length);

/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    /* initialize leds */
    led_init();
    /* turn off LED2~5 */
    gd_eval_led_off(LED2);
    gd_eval_led_off(LED3);
    gd_eval_led_off(LED4);
    gd_eval_led_off(LED5);

    /* configure USART */
    usart_config();

    /* configure SPI */
    spi_config();
    
    while(data_read2--){
        while(RESET == usart_flag_get(USART0, USART_FLAG_TBE)){
        }
        /* write one byte in the USART0 data register */
        usart_data_transmit(USART0, txbuffer1[tx_counter1++]);
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART0, USART_FLAG_TC)){
        }
        /* wait the byte is entirely received by SPI0 */  
        while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_RBNE)){
        }
        /* store the received byte in the rxbuffer2 */
        rxbuffer2[rx_counter2++] = spi_i2s_data_receive(SPI0);
    }

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

    while(data_read1--){
        /* wait until end of transmit */
        while(RESET == spi_i2s_flag_get(SPI0, SPI_FLAG_TBE)){
        }
        /* write one byte in the SPI0 transmit data register */
        spi_i2s_data_transmit(SPI0, txbuffer2[tx_counter2++]);

        /* send a dummy byte to generate clock to slave */ 
        usart_data_transmit(USART0, DYMMY_BYTE);
        /* wait until end of transmit */
        while(RESET == usart_flag_get(USART0, USART_FLAG_TC)){
        }
        /* wait the byte is entirely received by USART0 */
        while(RESET == usart_flag_get(USART0, USART_FLAG_RBNE)){
        }
        /* store the received byte in the rxbuffer1 */
        rxbuffer1[rx_counter1++] = usart_data_receive(USART0);
    }
  
    /* check the received data with the send ones */
    state1 = memory_compare(txbuffer1, rxbuffer2, txbuffer_size1);
    state2 = memory_compare(txbuffer2, rxbuffer1, txbuffer_size2);
    
    if(SUCCESS == state1){
        /* if the data transmitted from USART0 and received by SPI0 are the same */
        gd_eval_led_on(LED2);
        gd_eval_led_on(LED4);
    }else{
        /* if the data transmitted from USART0 and received by SPI0 are not the same */
        gd_eval_led_off(LED2);
        gd_eval_led_off(LED4);
    }
    if(SUCCESS == state2){
        /* if the data transmitted from SPI0 and received by USART0 are the same */
        gd_eval_led_on(LED3);
        gd_eval_led_on(LED5);
    }else{
        /* if the data transmitted from SPI0 and received by USART0 are not the same */
        gd_eval_led_off(LED3);
        gd_eval_led_off(LED5);
    }
    while(1){
    }
}

void usart_config(void)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);
    rcu_periph_clock_enable(RCU_AF);
    /* configure USART Tx as alternate function push-pull */
    gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9|GPIO_PIN_8);
    gpio_init(GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_10);
    /* configure USART synchronous mode */
    usart_synchronous_clock_enable(USART0);
    usart_synchronous_clock_config(USART0, USART_CLEN_EN, USART_CPH_2CK, USART_CPL_HIGH);
    
    usart_baudrate_set(USART0, 115200);
    /* configure USART transmitter */
    usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);
    /* configure USART receiver */
    usart_receive_config(USART0, USART_RECEIVE_ENABLE);
    /* enable USART */
    usart_enable(USART0);
}

void spi_config(void)
{
    spi_parameter_struct spi_init_parameter;
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_SPI0);
    rcu_periph_clock_enable(RCU_AF);
    
    spi_i2s_deinit(SPI0);
    
    gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_10MHZ, GPIO_PIN_5 | GPIO_PIN_6);
    gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_10MHZ, GPIO_PIN_7);
    /* configure SPI0 */
    spi_init_parameter.device_mode = SPI_SLAVE;
    spi_init_parameter.trans_mode = SPI_TRANSMODE_FULLDUPLEX;
    spi_init_parameter.frame_size = SPI_FRAMESIZE_8BIT;
    spi_init_parameter.nss = SPI_NSS_SOFT;
    spi_init_parameter.endian = SPI_ENDIAN_LSB;
    spi_init_parameter.clock_polarity_phase = SPI_CK_PL_HIGH_PH_2EDGE;
    spi_init_parameter.prescale = SPI_PSC_32;
    spi_init(SPI0, &spi_init_parameter);

    /* SPI0 enable */
    spi_enable(SPI0);
}

void led_init(void)
{
    gd_eval_led_init(LED2);
    gd_eval_led_init(LED3);
    gd_eval_led_init(LED4);
    gd_eval_led_init(LED5);
}

代码讲解

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

SPI 配置:设置主/从模式、时钟极性(CPOL)、时钟相位(CPHA)、分频系数。主机和从机的 CPOL/CPHA 必须一致。

实验现象

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

注意事项

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