文章目录
- 一.概要
- 二.USART串口基本介绍
- 三.GD32单片机USART内部结构图
- 四.USART内部信号流向
- 五.USART示波器信号解析
- 六.485通讯基本概念
- 七.配置一个USART数据收发例程进行485通讯实验
- 八.工程源代码下载
- 九.小结
一.概要
USART(Universal Synchronous/Asynchronous Receiver/Transmitter)是通用同步/异步收发器,它是嵌入式领域中使用十分广泛的一种串口通信协议,大部分MCU都具备USART硬件接口。
USART串口通信的主要特点:
双向串口通信有两根通信线(发送端TX和接收端RX)。
发送的TX和接收的RX要交叉连接。
当只需单向的数据传输时,可以只接一根通信线。
两个设备之间当电平标准不一致时,比如3.3V系统和5V系统通讯最好加电平转换芯片或者隔离芯片。
两个设备之间的GND一定要接在一起,VCC可以各自供电。
本文介绍了GD32 USART串口的基本概念,内部结构,波形时序,以及用串口进行数据通讯的例程。
本文介绍了GD32的USART串口的基本特点,用一个485通讯实验加深对串口通讯的理解。
二.USART串口基本介绍
基本数据帧组成
1)波特率
USART波特率是指每秒钟传输的位数,它决定了数据传输的速率和精确度。
波特率是USART通信中的一个关键参数,它表征了串口的传输速度,即单位时间内传输的码元个数。对于USART而言,码元通常是二进制的,通过高低电平传输,因此波特率和比特率在数值上是相等的。例如,当波特率为115200时,意味着UART串口每秒传输115200个bit的数据量。常见的UART串口波特率包括300、600、1200、4800、9600、19200、38400、57600、115200等,这些标准波特率广泛应用于各种设备和通信接口中。例如:数据传送速率为120字符/秒,而每一个字符为10位,则传送的波特率为10×120=1200位/秒=1200波特
2)停止位
每个字发送后,紧跟停止位,停止位可以选择“1、2、0.5、1.5”bit(0.5实际代表停止位高电平持续半个周期的时间)。
不过F1的USART做通信时,停止位只支持1或2个,一般情况下,停止位选择1。
3)校验位
UART传送的每个字节都可以选择是否增加1bit的奇偶校验位,而且奇校验或偶校验都可以选择。
4)字长度
传送一个字的位数,一般情况下都会选择8bit字节,这也和国际标准单位的字节宽度相对应。
5)起始位
起始位是必须的,由硬件产生,无需软件配置。STM32单片机的起始位就是在发送每个字的第一个有效位之前,先发送1周期的低电平,表示发送开始。
嵌入式应用中, 包括STM32F1的应用,最常见的配置是:8位字节,1个停止位,无校验,波特率9600/115200。
三.GD32单片机USART内部结构图
USART内部结构图如下
我们一般串口通讯使用串口的TX,RX引脚就可以了。
四.USART内部信号流向
串口发送:
在配置串口的各个参数时,可以选择发送数据帧的数据位的大小,可选8位。串口发送数据实际上就是对发送数据寄存器USART_DATA进行写操作。
1.当串口发送数据时,会检测发送移位寄存器是不是有数据正在移位,如果没有移位,那么这个数据就会立刻转移到发送移位寄存器里,准备发送。
2.当数据移动到移位寄存器时,会产生一个TXE发送寄存器空标志位,该位描述如下。当TXE被置1,那么就可以在USART_DATA写入下一个数据了,即发送下一个数据。
3.发送移位寄存器在发送器控制的控制下,向右移位,一位一位的把数据传输到TX引脚。
4.数据移位完成后,新的数据就会再次从USART_DATA转移到发送移位寄存器里来,依次重复1-3的过程。通过读取TXE标志位来判断是否发送下一个数据。
串口接收:
1.数据从RX引脚通向接收移位寄存器,在接收控制的控制下,一位一位的读取RX的电平,把第一位放在最高位,然后右移,移位8次之后就可以接收一个字节了。
2.当一个字节数据移位完成之后,这一个字节的数据就会整体的移到接收数据寄存器USART_DATA里来。在转移时会置RXNE接收标志位,即USART_DATA寄存器非空,就说明数据可以被读出。
串口数据收发程序相关:
串口发送一般以下操作:
写入数据:使用GD32提供的函数(如usart_data_transmit)将数据写入串口的发送数据寄存器。通过检查发送完成标志(如USART_INT_FLAG_TBE)来确认数据是否已经成功发送。
串口接收一般以下操作:
1.轮询方式:通过不断查询接收标志位(如USART_INT_FLAG_RBNE)来判断数据是否到达接收缓冲区,这个效率比较低。
2.中断方式:通过配置收到1字节数据单片机串口产生一次中断,在中断服务例程中处理接收到的数据。有时候会遇到接收的数据长度不固定,GD32单片机串口提供了一个更好用的功能,就是空闲中断(IDLEF)功能。也就是说当一帧数据接收结束后,就会产生一个空闲中断。这样就可以利用这个空闲中断来判断一帧数据接收是否完成。
五.USART示波器信号解析
用串口调试器软件发送0x12数据,9600波特率,8位数据,无校验,1位停止位,用示波器采集波形如下图所示。
根据下图分析,数据是低位在前,高位在后,二进制就是00010010。转换成十六进制就是0x12,分析的波形数据内容跟电脑串口调试器发送的内容一致。
六.485通讯基本概念
RS485通讯采用的是差分信号负逻辑控制模式,即2~6V表示“0”,-6~-2V表示“1”。RS485通讯一般采用两线制接线方式(端口A,端口B)。两线制接线方式是目前采用较多的为总线式拓朴结构,属于半双工传输方式,也就是说收发是不同步的。
485通讯一般就是单片机的串口加RS485芯片实现。
七.配置一个USART数据收发例程进行485通讯实验
485转TTL模块插开发板子上(板子PB6接模块TX,板子PB7接模块RX,板子3.3V接模块VCC,板子GND接模块GND),USB转485模块插电脑,把两个485模块通过杜邦线连接,A跟A连,B跟B连。
添加代码
uint8_t transmitter_buffer[] = "HELLOWORLD";//定义发送数组
uint8_t receiver_buffer[10];//定义接收数组
#define ARRAYNUM(arr_nanme) (uint32_t)(sizeof(arr_nanme) / sizeof(*(arr_nanme)))
#define TRANSMIT_SIZE (ARRAYNUM(transmitter_buffer) - 1)//计算大小
uint8_t transfersize = TRANSMIT_SIZE;
uint8_t receivesize = 10;
__IO uint8_t txcount = 0;
__IO uint16_t rxcount = 0;
//USART0初始化,使用PB6(TX),PB7(RX)脚,9600波特率,无校验,8位数据,1位停止
void gd_eval_com_init(void)
{
/* enable GPIO clock */
rcu_periph_clock_enable(RCU_GPIOB);//使能GPIOB时钟
/* enable USART clock */
rcu_periph_clock_enable(RCU_USART0);//使能USART0时钟
gpio_pin_remap_config(GPIO_USART0_REMAP, ENABLE);//PB6,PB7需要重映射
gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ,GPIO_PIN_6);//PB6输出
/* configure USART Rx as alternate function push-pull */
gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ,GPIO_PIN_7);//PB7输入
/* USART configure */
usart_deinit(USART0);
usart_baudrate_set(USART0,9600);
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_transmit_config(USART0, USART_TRANSMIT_ENABLE);
usart_receive_config(USART0, USART_RECEIVE_ENABLE);
usart_enable(USART0);//使能USART0
}
int main(void)
{
rcu_ahb_clock_config(RCU_AHB_CKSYS_DIV1);//AHB主频是1分频
systick_config();//系统主频108MHZ,采用外部晶振,由两个宏决定(__SYSTEM_CLOCK_108M_PLL_HXTAL与HXTAL_VALUE)
rcu_periph_clock_enable(RCU_AF); //管脚复用时钟alternate function clock使能
delay_1ms(1000);
//USART相关配置
gd_eval_com_init();
nvic_irq_enable(USART0_IRQn, 0, 0);//使能USART0中断
usart_interrupt_enable(USART0, USART_INT_RBNE);//接收中断打开
while(1)
{
if(rxcount >= receivesize)//接收满10个字节,在USART0_IRQHandler函数中计数
{
rxcount=0;
txcount=0;
usart_interrupt_enable(USART0, USART_INT_TBE);//发送中断打开
while(txcount < transfersize);//等待发送完成,在USART0_IRQHandler函数中计数
while (RESET == usart_flag_get(USART0, USART_FLAG_TC));//发送完成判断
usart_interrupt_enable(USART0, USART_INT_RBNE);//接收中断打开
}
}
}
void USART0_IRQHandler(void)
{
if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_RBNE)){
/* receive data */
receiver_buffer[rxcount++] = usart_data_receive(USART0);
if(rxcount == receivesize){
usart_interrupt_disable(USART0, USART_INT_RBNE);
}
}
if(RESET != usart_interrupt_flag_get(USART0, USART_INT_FLAG_TBE)){
/* transmit data */
usart_data_transmit(USART0, transmitter_buffer[txcount++]);
if(txcount == transfersize){
usart_interrupt_disable(USART0, USART_INT_TBE);
}
}
}
实验效果
串口调试器发HELLOWORLD板子会回HELLOWORLD。
八.工程源代码下载
通过网盘分享的文件:7.485通讯.zip
链接: https://pan.baidu.com/s/1AGEdmMzm1LmTNOKDYGckdg 提取码: ywm1
如果链接失效,可以联系博主给最新链接
程序下载下来之后解压就行
CSDN代码
九.小结
GD32的串口(USART)主要用于与其他设备进行数据通信和调试。GD32的串口还支持多种通信协议,如LIN、IrDA等,这使得它能够与各种类型的设备进行通信。串口通信在软件开发中也是一个重要的调试手段,通过串口可以输出调试信息,帮助开发者了解程序的运行状态。