[研电赛技术支持] GD32 中的USART 通信原理及实现

[复制链接]
 楼主| renzheshengui 发表于 2025-7-10 15:43 | 显示全部楼层 |阅读模式
在嵌入式系统开发领域,USART(Universal Synchronous/Asynchronous Receiver/Transmitter,通用同步 / 异步收发器)作为一种重要的串行通信接口,被广泛应用于各类设备间的数据交互场景。该通信协议凭借其简洁高效的数据传输机制,为不同设备模块搭建起可靠的信息交互桥梁。兆易创新推出的 GD32 系列微控制器,以卓越的处理性能、低功耗设计以及丰富的外设资源,在嵌入式市场中占据重要地位。本文将系统阐述 USART 的工作原理,并结合 C 语言编程,详细介绍在 GD32 微控制器平台上实现 USART 通信功能的具体方法。

一、USART 通信原理​
1.1 基本概念​
USART 是一种全双工的串行通信协议,它允许设备在两根信号线上(发送线 TX 和接收线 RX)同时进行数据的发送和接收。与并行通信相比,USART 使用更少的引脚资源,适合长距离、低速的数据传输场景,在嵌入式设备间通信、设备与上位机通信等方面广泛应用。​

       19585686f5bc29086e.png             

1.2 物理层特性​
USART 通信的物理层主要涉及信号线和电平标准。一般情况下,使用 RX(接收)和 TX(发送)两根信号线实现数据传输。在 GD32 微控制器中,通常采用 TTL 电平标准,即低电平(0V)表示逻辑 “0”,高电平(3.3V)表示逻辑 “1” 。若要与采用 RS - 232 电平标准的设备通信,则需要借助电平转换芯片,如 MAX232,将 TTL 电平转换为 RS - 232 电平,反之亦然。​

1.3 数据传输格式​
USART 通信的数据帧格式由起始位、数据位、奇偶校验位和停止位组成。​

起始位:固定为低电平,占用 1 位,用于标识一帧数据的开始,接收端通过检测起始位来同步数据接收。​
数据位:可配置为 5 - 8 位,通常使用 8 位,用于传输实际的数据。数据位在传输时,低位先行。​
奇偶校验位:可选无校验、奇校验或偶校验,占用 1 位。奇偶校验是一种简单的错误检测方法,通过计算数据位中 “1” 的个数,使加上奇偶校验位后 “1” 的总数符合奇校验或偶校验的规则,接收端据此判断数据在传输过程中是否发生错误。​
停止位:可为 1 位、1.5 位或 2 位高电平,用于标识一帧数据的结束。停止位的长度可根据具体需求进行配置。​
1.4 时序控制​
USART 通信的时序由波特率决定,波特率表示每秒传输的二进制位数,单位为 bps(bits per second)。常见的波特率有 9600bps、19200bps、38400bps、57600bps、115200bps 等。发送端和接收端必须设置相同的波特率,才能确保数据正确传输。在 GD32 中,通过配置相关寄存器来设置波特率,其计算公式与具体的时钟源和分频系数有关 。​

二、GD32 中 USART 的 C 语言实现​
2.1 开发环境搭建​
在开始编写代码前,需要搭建好 GD32 的开发环境。一般使用 MDK(Keil MDK)或 IAR 等集成开发环境,并安装 GD32 对应的器件支持包,以便能正确识别 GD32 微控制器的外设和寄存器,进行代码编写、编译和调试。​

2.2 USART 初始化​
下面是 GD32 中 USART 初始化的 C 语言代码示例,以 USART0 为例,配置波特率为 115200bps,8 位数据位,无校验位,1 位停止位:

#include "gd32f4xx.h"

void usart0_init(void)
{
    // 使能GPIOA和USART0时钟
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_USART0);

    // 配置PA9为复用推挽输出(USART0_TX)
    gpio_mode_set(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_PIN_9);
    gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_9);

    // 配置PA10为浮空输入(USART0_RX)
    gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO_PIN_10);

    // USART0初始化配置
    usart_deinit(USART0);
    usart_baudrate_set(USART0, 115200U);
    usart_word_length_set(USART0, USART_WL_8BIT);
    usart_stop_bit_set(USART0, USART_STB_1BIT);
    usart_parity_config(USART0, USART_PM_NONE);
    usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);
    usart_mode_set(USART0, USART_MODE_TXRX);

    // 使能USART0
    usart_enable(USART0);
}



在上述代码中,首先通过rcu_periph_clock_enable函数使能 GPIOA 和 USART0 的时钟,确保后续对 GPIO 和 USART 寄存器的操作有效。接着,对 PA9 和 PA10 引脚进行配置,PA9 作为 USART0 的发送引脚,配置为复用推挽输出模式;PA10 作为接收引脚,配置为浮空输入模式。然后,使用usart_*系列函数对 USART0 的波特率、数据位、停止位、奇偶校验位、硬件流控制等参数进行配置,并设置为收发模式,最后使能 USART0。

2.3 数据发送​
实现 USART 数据发送的函数如下,该函数可发送一个字节的数据:

void usart_send_byte(uint8_t data)
{
    // 等待发送数据寄存器为空
    while (RESET == usart_flag_get(USART0, USART_FLAG_TBE));
    // 发送数据
    usart_data_transmit(USART0, data);
}


函数中,通过usart_flag_get函数不断查询 USART0 的发送数据缓冲区空标志位(USART_FLAG_TBE),当该标志位为 SET 时,表示发送数据寄存器为空,可以写入新的数据。然后,使用usart_data_transmit函数将数据写入发送数据寄存器,实现数据发送。​

如果要发送字符串,可以使用以下函数:

void usart_send_string(char *str)
{
    while (*str != '\0')
    {
        usart_send_byte(*str);
        str++;
    }
}


该函数遍历字符串,逐个调用usart_send_byte函数发送字符,直到遇到字符串结束符'\0'。

2.4 数据接收​
USART 数据接收可以采用轮询或中断的方式。下面是轮询方式接收一个字节数据的函数:

uint8_t usart_receive_byte(void)
{
    // 等待接收数据寄存器非空
    while (RESET == usart_flag_get(USART0, USART_FLAG_RBNE));
    // 读取接收数据寄存器
    return usart_data_receive(USART0);
}


函数通过查询 USART0 的接收数据缓冲区非空标志位(USART_FLAG_RBNE),当该标志位为 SET 时,表示接收数据寄存器中有数据可读,然后使用usart_data_receive函数读取数据并返回。​

若采用中断方式接收数据,首先需要配置 USART 的中断,以接收中断为例:

void usart0_nvic_config(void)
{
    nvic_irq_enable(USART0_IRQn, 0, 0);
    usart_interrupt_enable(USART0, USART_INT_RBNE);
}

void USART0_IRQHandler(void)
{
    if (SET == usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE))
    {
        uint8_t receive_data = usart_data_receive(USART0);
        // 处理接收到的数据,如存储到数组等
        // ......
        usart_interrupt_flag_clear(USART0, USART_INT_FLAG_RBNE);
    }
}



在usart0_nvic_config函数中,使用nvic_irq_enable函数使能 USART0 的中断,并设置中断优先级,然后通过usart_interrupt_enable函数使能接收中断。在USART0_IRQHandler中断服务函数中,当检测到接收数据缓冲区非空中断标志位(USART_INT_FLAG_RBNE)为 SET 时,读取接收数据寄存器中的数据,并进行相应处理,最后清除中断标志位。

三、总结​
本文详细介绍了 USART 通信原理,并基于 GD32 微控制器,通过 C 语言实现了 USART 的初始化、数据发送和接收功能,涵盖了轮询和中断两种数据接收方式。掌握 USART 通信在 GD32 中的应用,能为嵌入式系统的开发提供有力支持,无论是设备间的通信,还是与上位机的数据交互,都可以借助 USART 实现稳定的数据传输。后续还可以进一步探索 USART 在不同应用场景下的优化和扩展,如多机通信等功能。​
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/weixin_68532722/article/details/148901425

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

本版积分规则

109

主题

4307

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部