大数跨境
0
0

STM32F407基础教程——串口基本概念与库函数

STM32F407基础教程——串口基本概念与库函数 Easy单片机
2025-12-03
0
导读:串口通信基本概念与相关库函数

引言

串口通信,全称串行通信接口,是嵌入式系统中最基础、最常用的通信方式之一。如同人与人之间的对话需要共同的语言,设备间的数据交换也需要遵循特定的通信协议,而USART(Universal Synchronous Asynchronous Receiver/Transmitter,通用同步异步收发器)是一种广泛使用的串行通信接口。

USART能够灵活地与外部设备进行全双工数据交换,支持异步通信、同步单向通信和半双工单线通信、LIN(局域互联网络)、智能卡协议与IrDA(红外线数据协会)SIR ENDEC规范等等。这里只介绍USART最基本的功能,全双工串行异步通信。

一、串口通信相关概念

1.通信分类

  • 并行通信指使用多条数据线传输数据,数据字节的各位同时传送的通信方式。

  • 串行通信指使用一条数据线,数据字节的各位一位一位地依次传送的通信方式。

2.串行通信方式

1)按照数据的传递方式

  • 单工通信:数据只允许一个方向进行传送,即数据发送设备只能发送数据,数据接收设备只能接收数据。

  • 半双工通信:数据允许向两个方向进行传送,但传送数据的过程与接收数据的过程不能同时进行。

  • 全双工通信:数据允许向两个方向进行传送,并且发送数据的过程与接收数据的过程可以同时进行。

2)按照串行数据的时钟控制方式

  • 串行异步通信:一次通信传送一个字符帧。在发送字符时,发送的字符之间的时间间隔可以是任意的,接收端时刻做好接收的准备。

  • 串行同步通信:要求发送频率和接收频率要同步。由一个统一的时钟控制发送端的发送。

3.串行异步通信的数据传输形式和传输速率

1)数据传输形式是按照一定格式打包成帧,以帧为单位在物理链路上进行传输的。USART的数据格式由起始位、数据位、校验位、停止位和空闲位等构成。其中,起始位(1位-低电平)、数据位(8位/9位)、校验位(若有则以数据位最后一位作为校验位)和停止位(1位-高电平),构成了一个数据帧。见下图。

2)数据传输速率,可以用波特率(比特率)来表示。

波特率:数据的传送速率,在串行异步通信中,每秒钟传送的二进制的位数单位是比特/秒(bit/s),或波特(baud)。常用的波特率:2400、4800、7200、9600、19200、38400、···、115200等

二、USART功能说明

USART双向通信均需要至少两个引脚:接收数据输入引脚(RX)和发送数据引脚输出(TX)

USART内部结构有数据寄存器(USART_DR),该寄存器包含了发送数据寄存器(TDR--Transmitter Data Register)和接收数据寄存器(RDR-Receiver Data Rsgister);发送/接收移位寄存器;波特率寄存器(USART_BRR);时钟控制、发送控制、接收控制、中断控制等。USART结构见下图。

发送数据时,在USART_DR寄存器中写入要发送的数据,该操作将清零TXE位(状态寄存器USART_SR中的第7位),当TDR寄存器中的数据传输到发送移位寄存器时,TXE置1,并且发送移位寄存器中的数据在TX引脚输出。当数据发送完成,TC位(状态寄存器USART_SR中的第6位,0-发送未完成,1-发送完成)置1。向USART_DR写入最后一个数据时,必须等待至TC=1。TXE置1和TC置1都可通过设置对应的中断位产生中断。

接收数据时,数据通过RX引脚至接收移位寄存器,当接收移位寄存器中的数据传送到USART_DR时,RXNE位置1,表示已接收到并可读取数据。RXEN是状态寄存器USART_SR中的第5位,0-未接收到数据,1-已准备好读取接收到的数据。

三、USART常用库函数

1.串口初始化库函数
void USART_Init(USART_TypeDef* USARTx, USART_InitTypeDef*USART_InitStruct)

参数1:USARTx,x=1~8

参数2:结构体指针,见下。

typedef struct

{

uint32_t USART_BaudRate; //波特率

uint16_t USART_WordLength; //字长

uint16_t USART_StopBits;//停止位

uint16_t USART_Parity; //奇偶校验

uint16_t USART_Mode;//发送/接收使能

int16_t USART_HardwareFlowControl;//硬件流控制

}USART_InitTypeDef;

1)USART_BaudRate:波特率,可以设置为常用的波特率

2)USART_WordLength字长

USART_WordLength_8b8位数据

USART_WordLength_9b9位数据

3)USART_StopBits:停止位

USART_StopBits_1在帧结尾传输1个停止位

USART_StopBits_0.5在帧结尾传输0.5个停止位

USART_StopBits_1.5在帧结尾传输1.5个停止位

USART_StopBits_2在帧结尾传输2个停止位

(4)USART_Parity奇偶校验

USART_Parity_No:无奇偶

USART_Parity_Even偶模式

USART_Parity_Odd奇模式

5)USART_HardwareFlowControl硬件流控制

USART_HardwareFlowControl_None硬件流控制失能

USART_HardwareFlowControl_RTS发送请求RTS使能

USART_HardwareFlowControl_CTS清除发送CTS使能

USART_HardwareFlowControl_RTS_CTSRTS和CTS使能

6)USART_Mode发送、接收使能

USART_Mode_Tx发送使能

USART_Mode_Rx接收使能

使用方法:

USART_InitTypeDefUSART_InitStructure;//定义结构体

USART_InitStructure. USART_BaudRate = 9600;//设置波特率

USART_InitStructure. USART_WordLength = USART_WordLength_8b;//选择字长

USART_InitStructure. USART_StopBits = USART_StopBits_1;//选择停止位

USART_InitStructure. USART_Parity = USART_Parity_Odd;//选择奇偶

USART_InitStructure. USART_HardwareFlowControl = 

USART_HardwareFlowControl_None;//无硬件流

USART_InitStructure. USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //发送、接收使能

USART_Init(USART1,&USART_InitStructure);//完成初始化

2、函数原型

void USART_Cmd(USART_TypedDef *USARTx,FunctionalState NewState)

函数功能:使能或禁止指定USART。

使用方法:USART_Cmd(USART1,ENABLE);//使能串口

3、函数原型

void USART_SendData(USART_TypeDef * USARTx, u8 Data)

函数功能:通过USART发送单个字节数据

使用方法:USART_SendData(USART1,0x23);

4、函数原型

u8 USART_ReceiveData(USART_TypeDef * USARTx)

函数功能:返回指定USART最近接收到的单个字节数据。

使用方法:

u8 RxData;

RxData = USART_RexeiveData(USART1);

5、函数原型

void USART_ITConfig(USART_TypeDef * USARTx, u16 USART_IT, FunctionalState NewState)

函数功能:使能或禁止指定的USART中断。

USART_IT取值:

USART_IT_PE //奇偶错误中断

USART_IT_TXE //发送中断

USART_IT_TC //传输完成中断

USART_IT_RXEN //接收中断

例:USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//串口1接收中断使能

6、函数原型

void USART_ClearITPendingBit(USART_TypeDef* USARTx, USART_IT_RXNE)

函数功能:清除指定的中断标志位(USART_IT取值同上)

例:USART_ClearITPendingBit(USART1, uint16_t USART_IT) //清除接收中断标志位

7、函数原型

FlagStatus USART_GetFlagStatue(USART_TypeDef * USARTx, u16 USART_FLAG)

函数功能:查询指定USART的标志位状态。

USART_FLAG取值:

USART_FLAG_TXE //发送数据寄存器空标志位

USART_FLAG_TC //发送完成标志位

USART_FLAG_RXEN //接收数据寄存器非空标志位

例:FlagStatus Status;Status = USART_GetFlagStatue(USART1,USART_FLAG_TXE);//获取发送寄存器的状态

8、函数原型

void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)函数功能:清除状态标志位(USART_FLAG取值同上)

四、USART使用流程

USART最基本的功能就是发送和接收数据。该功能的实现需要串口工作方式配置、串口发送和串口接收三部分程序。

/*1-串口配置*/void Usart_Init(){/*1-定义结构体 GPIO、USART*/USART_InitTypeDef USART_InitStruct;GPIO_InitTypeDef GPIO_InitStruct;
 /*2-使能时钟 GPIO、USART时钟*/RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/*3-配置GPIO引脚*/GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;// PA9作为USART1_TX,PA10作为USART1_RXGPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;  // 复用功能GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; // 推挽输出GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;   // 上拉GPIO_Init(GPIOA, &GPIO_InitStruct);  
 /*4-引脚复用映射*/ GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);
/*5-配置串口*/USART_InitStruct.USART_BaudRate = 115200//波特率USART_InitStruct.USART_WordLength = USART_WordLength_8b;//8位字长USART_InitStruct.USART_StopBits = USART_StopBits_1;//停止位1位USART_InitStruct.USART_Parity = USART_Parity_No;//无奇偶校验USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//使能发送和接收模式USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件流USART_Init(USART1, &USART_InitStruct);//初始化
/*6-使能串口*/USART_Cmd(USART1, ENABLE);}
//发送与接收数据程序 ,包括printf重定向输出到串口 /*1-单个字符发送-查询方式*/ void USART_SendChar(uint8_t ch){    // 等待发送寄存器空    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);       // 发送数据    USART_SendData(USART1, ch);}
/*2-字符串发送-查询方式*/void USART_SendString(char *str){    while(*str)    {        USART_SendChar(*str++);    }}
/*3-重定向c库函数printf到串口包含#include<stdio.h> 在Keil中,还需勾选“Use MicroLIB”以使用此微库优化*/int fputc(int ch, FILE *f) {    USART_SendData(USART1, (uint8_t)ch); // 发送字符    while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); // 等待发送完成    return ch;}
/*4-接收单个字符-查询方式*/uint8_t USART_ReceiveChar(){    // 等待接收到数据    while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);       return USART_ReceiveData(USART1);}
//主函数测试 int main(void) {       u8 temp = 10;    Usart_Init();    while (1   {printf("Send a character:");        USART_SendChar('A');        delay_ms(1000);        USART_SendString("Easy Single Chip");        delay_ms(1000);        printf("Send a character %d :",temp);        delay_ms(1000);   }}
/*中断方式-中断配置函数*/void USART_IT_Config(){    NVIC_InitTypeDef NVIC_InitStruct;    // 使能接收中断    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);    // 配置NVIC    NVIC_InitStruct.NVIC_IRQChannel = USART1_IRQn; //中断通道    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0//抢占优先级    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;//子优先级    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;//中断使能    NVIC_Init(&NVIC_InitStruct);//初始化}// 中断服务函数void USART1_IRQHandler(void){    uint8_t received_data;    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)    {        // 读取接收到的数据        received_data = USART_ReceiveData(USART1);        // 处理数据(回传数据)        USART_SendData(USART1, received_data);        // 清除中断标志        USART_ClearITPendingBit(USART1, USART_IT_RXNE);    }}
效果如下,测试开发板上集成了USB转串口芯片CH340,如果没有需要借助USB转串口模块。

【声明】内容源于网络
0
0
Easy单片机
本公众号专注于单片机技术开发领域。用于记录和分享单片机开发相关技术知识,学习笔记,设计示例和基础教程。包括C/C++、51单片机、STM32单片机、PCB设计等。
内容 62
粉丝 0
Easy单片机 本公众号专注于单片机技术开发领域。用于记录和分享单片机开发相关技术知识,学习笔记,设计示例和基础教程。包括C/C++、51单片机、STM32单片机、PCB设计等。
总阅读3
粉丝0
内容62