串口USART和UART

article/2025/11/7 2:45:44

串口通信:

UART是通用串行数据总线,用于异步通信。该总线双向通信,可以实现全双工传输和接受。UART主要用于主机与辅助设备通信。

 

UART的功能计算器内部采用并行数据,不能直接把数据发到Modem,必须经过UART整理才能进行异步通信。也就是CPU把准备写入串行设备的数据放到UART的寄存器中,再通过FIFO(First Input First Output,先入先出队列)传到串行设备,提供了RS232数据终端设备接口。

UART的主要功能分为:

1、将计算机内部传送过来的并行数据转换为输出的串行数据流。可以将计算机外部来的串行数据转换为字节,供计算机内部并行数据的器件使用。并且可以加上奇偶校验位,启停标志位中断信号。

USART是UART的升级版,通用同步/异步串行接收/发送器USART是一个全双工通用同步/异步串行收发模块。

USART特点:

1、全双工操作(相互独立的接收数据和发送数据)

2、同步操作时,可以主机时钟同步,也可以从机时钟同步;

3、独立高精度波特率发生器,不占用定时定数器;

4、有奇偶校验位和启停位起始位、数据位;

5、数据溢出检测;

6、帧错误检测;

7、三个独立中断:TX发送完成、RX发送数据寄存器空、接收完成

8、常用串口寄存器:1、USART_SR状态寄存器 2、USART_DR数据状态寄存器 3、USART_BRR 波特率寄存器

9、波特率的计算方法:Tx/Rx波特率=f_PCLKx/(16*USARTDIV)

f_PCLKx是串口时钟,(PCLK1用于USART2345,PCLK2用于USART1)

USARTDIV是一个无符号定点数

串口的工作方式:

一般有两种方式:查询和中断。

(1)查询:串口程序不断地循环查询,看看当前有没有数据要它传送。如果有,就帮助传送(可以从PC到STM32板子,也可以从STM32板子到PC)。

(2)中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着要它帮助传输数据——它就马上进行数据的传送。同样,可以从 PC到STM3板子,也可以从STM32板子到PC。

编程的配置过程:

1、RCC配置:由于UART的TX和RX和AFIO都挂在APB2桥上,因此采用固件库函数RCC_APB2PeriphClockCmd()进行初始化。UARTx需要分情况讨论,如果是UART1,则挂在APB2桥上,因此采用RCC_APB2PeriphClockCmd()进行初始化,其余的UART2~5均挂在APB1上。

1)、串口时钟使能、GPIO时钟使能RCC_APB2PeriphClockCmd();

2)、串口复位USART_Init()

2、GPIO配置:GPIO的属性包含在结构体GPIO_InitTypeDef,其中对于TX引脚,GPIO_Mode字段设置为GPIO_Mode_AF_PP(复用推挽输出),GPIO_Speed切换速率设置为GPIO_Speed_50MHz;对于RX引脚,GPIO_Mode字段设置为GPIO_Mode_IN_FLOATING(浮空输入),不需要设置切换速率。最后通过GPIO_Init()使能IO口。

1)、GPIO端口模式设置。GPIO_Init();

3、USART配置:

STM32在只有一个中断的情况下,仍然需要配置优先级,其作用是使能某条中断的触发通道。STM32的中断有至多两个层次,分别是抢占优先级(主优先级)和子优先级(从优先级),而整个优先级设置参数的长度为4位,因此需要首先划分抢占优先级位数和子优先级位数,通过NVIC_PriorityGroupConfig()实现;

特定设备的中断优先级NVIC的属性包含在结构体NVIC_InitTypeDef中,其中字段NVIC_IRQChannel包含了设备的中断向量,保存在启动代码中;字段NVIC_IRQChannelPreemptionPriority为主优先级NVIC_IRQChannelSubPriority为从优先级,取值的范围应根据位数划分的情况而定;最后NVIC_IRQChannelCmd字段是是否使能,一般置为ENABLE。最后通过NVIC_Init()来使能这一中断向量。

1)、串口初始化 USART_Init();

USART_BaudRate:波特率(每秒能传输的数据位),缺省值为9600。USART_WordLength:字长USART_StopBits:停止位USART_Parity:校验方式(奇偶校验)USART_HardwareFlowControl:硬件流控制USART_Mode:单/双工,即收发状态

4、NVIC配置

5、开启中断并且初始化NVIC

NVIC_Init();

USART_ITConfig();//使能相关中断

6、使能串口:USART_Cmd()

7、编写中断处理函数 USARTx_IRQHander();

8、串口数据收发

void USART_SendData();//发送数据到串口

uint16_t USART_ReceiveData();//接收数据

9、串口传输状态获取

注意在对数据进行发送和接收的时候,要检查USART的状态,只有等到数据发送或接收完毕之后才能进行下一帧数据的发送或接收。采用USART_GetFlagStatus()函数

在发送数据的最开始,需要清除一下USART的标志位,否则,第1位数据会丢失。因为在硬件复位之后,USART的状态位TC是置位的。当包含有数据的一帧发送完成之后,由硬件将该位置位。只要当USART的状态位TC是置位的时候,就可以进行数据的发送。然后TC位的置零则是通过软件序列来清除的,具体的步骤是“先读USART_SR,然后写入USART_DR”,只有这样才能够清除标志位TC,但是在发送第一帧数据的时候,并没有进行读USART_SR的操作,而是直接进行写操作,因此TC标志位并没有清空,那么,当发送第一帧数据,然后用USART_GetFlagStatus()检测状态时返回的是已经发送完毕(因为TC位是置1的),所以程序会马上发送下一帧数据,那么这样,第一帧数据就被第二帧数据给覆盖了,所以看不到第一帧数据的发送。

建立模板USART.c

#include "usart.h"//使UASRT串口可用printf函数发送
//在usart.h文件里可更换使用printf函数的串口号	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE {int handle; 
}; 
FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
_sys_exit(int x){ x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f){      while((USART_n->SR&0X40)==0);//循环发送,直到发送完毕   USART_n->DR = (u8) ch;      return ch;
}
#endif /*
USART1串口相关程序
*/#if EN_USART1   //USART1使用与屏蔽选择
u8 USART1_RX_BUF[USART1_REC_LEN];     //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15,	接收完成标志
//bit14,	接收到0x0d
//bit13~0,	接收到的有效字节数目
u16 USART1_RX_STA=0;       //接收状态标记
/*
USART1专用的printf函数
当同时开启2个以上串口时,printf函数只能用于其中之一,其他串口要自创独立的printf函数
调用方法:USART1_printf("123"); //向USART2发送字符123
*/
void USART1_printf (char *fmt, ...){ char buffer[USART1_REC_LEN+1];  // 数据长度u8 i = 0;	va_list arg_ptr;va_start(arg_ptr, fmt);  vsnprintf(buffer, USART1_REC_LEN+1, fmt, arg_ptr);while ((i < USART1_REC_LEN) && (i < strlen(buffer))){USART_SendData(USART1, (u8) buffer[i++]);while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); }va_end(arg_ptr);
}	  
void USART1_Init(u32 bound){ //串口1初始化并启动//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟//USART1_TX   PA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);  //USART1_RX	  PA.10GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure); //Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器 //USART 初始化设置USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式USART_Init(USART1, &USART_InitStructure); //初始化串口USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启ENABLE/关闭DISABLE中断接收到数据时中断 读寄存器DR清零,也可软件手动清零USART_Cmd(USART1, ENABLE);                    //使能串口 
}void USART1_IRQHandler(void){ //串口1中断服务程序(固定的函数名不能修改)	u8 Res;//以下是字符串接收到USART1_RX_BUF[]的程序,(USART1_RX_STA&0x3FFF)是数据的长度(不包括回车)//当(USART1_RX_STA&0xC000)为真时表示数据接收完成,即超级终端里按下回车键。//在主函数里写判断if(USART1_RX_STA&0xC000),然后读USART1_RX_BUF[]数组,读到0x0d 0x0a即是结束。//注意在主函数处理完串口数据后,要将USART1_RX_STA清0if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){  //接收中断(接收到的数据必须是0x0d 0x0a结尾)		Res =USART_ReceiveData(USART1);//(USART1->DR);	//读取接收到的数据printf("%c",Res); //把收到的数据以 a符号变量 发送回电脑		if((USART1_RX_STA&0x8000)==0){//接收未完成			if(USART1_RX_STA&0x4000){//接收到了0x0d				if(Res!=0x0a)USART1_RX_STA=0;//接收错误,重新开始else USART1_RX_STA|=0x8000;	//接收完成了 }else{ //还没收到0X0D					if(Res==0x0d)USART1_RX_STA|=0x4000;else{USART1_RX_BUF[USART1_RX_STA&0X3FFF]=Res ; //将收到的数据放入数组USART1_RX_STA++;	//数据长度计数加1if(USART1_RX_STA>(USART1_REC_LEN-1))USART1_RX_STA=0;//接收数据错误,重新开始接收	  }		 }}   		 } 
} 
#endif

USART.h

#ifndef __USART_H
#define __USART_H
#include <string.h>
#include "stdio.h"	
#include "sys.h" 
#define USART_n		USART1  //定义使用printf函数的串口,其他串口要使用USART_printf专用函数发送#define USART1_REC_LEN  			200  	//定义USART1最大接收字节数
#define EN_USART1 			1		//使能(1)/禁止(0)串口1
extern u8  USART1_RX_BUF[USART1_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符  
extern u16 USART1_RX_STA;         		//接收状态标记	//函数声明
void USART1_Init(u32 bound);//串口1初始化并启动
void USART1_printf(char* fmt,...); //串口1的专用printf函数
#endif

main.c函数

#include "stm32f10x.h" //STM32头文件
#include "delay.h"
#include "usart.h"int main (void){//主程序//初始化程序RCC_Configuration(); //时钟设置USART1_Init(115200); //串口初始化(参数是波特率)//主循环while(1){printf("hello windows "); //纯字符串发送数据到串口delay_ms(1000); //延时}
}


http://chatgpt.dhexx.cn/article/rtkEwJSO.shtml

相关文章

【通信接口】UART、IIC、SPI

目录 一、预备知识 1、串行与并行 2、单工与双工 3、波特率 二、UART 三、IIC 四、SPI &#xff08;一对一、一对多&#xff09; 五、IIC、SPI异同点 参考文章&#xff1a;这些单片机接口&#xff0c;一定要熟悉&#xff1a;UART、I2C、SPI、TTL、RS232、RS422、RS485…

基于FPGA的UART接口设计

一、顶层设计思路&#xff1a; UART即通用异步收发传输接口&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;&#xff0c;简称串口&#xff0c;是一种常用的通信接口&#xff0c;其协议原理就不赘述了&#xff0c;不了解的可以自己查阅资料。&#xff08;…

单片机通信接口:UART、I2C、SPI、TTL、RS232、RS422、RS485、CAN、USB

参考资料&#xff1a; 这些单片机接口&#xff0c;一定要熟悉&#xff1a;UART、I2C、SPI、TTL、RS232、RS422、RS485、CAN、USB、SD卡 秒懂所有USB接口类型&#xff0c;USB接口大全 1. UART UART(通用异步收发器)指的是一种物理接口形式(硬件)。 UART是异步&#xff0c;全双…

通信接口:UART、I2C、SPI、TTL、RS232、RS422、RS485、CAN、USB

1. UART UART(通用异步收发器)指的是一种物理接口形式(硬件)。 UART是异步&#xff0c;全双工串口总线。它比同步串口复杂很多。有两根线&#xff0c;一根TXD用于发送&#xff0c;一根RXD用于接收。 UART的串行数据传输不需要使用时钟信号来同步传输&#xff0c;而是依赖于发送…

USB,串口(RS232、RS485),UART接口

USB转串口即实现计算机USB接口到通用串口之间的转换。为没有串口的计算机提供快速的通道&#xff0c;而且&#xff0c;使用USB转串口设备等于将传统的串口设备变成了即插即用的USB设备。作为应用最广泛的USB接口&#xff0c;每台电脑必不可少的通讯接口之一&#xff0c;它的最大…

Uart接口的详细解释

我面试的时候一般喜欢问应聘者一个问题&#xff1a;UART与RS232/RS485的区别与联系&#xff1f;很多人对于这个问题答得都不是很好。还有些人压根就没有想过这个问题&#xff0c;一直认为他们是同一个东西&#xff0c;就是咱们俗称的串口。 我刚入嵌入式的大门时&#xff0c;对…

UART接口说明

逼近年关事情多&#xff0c;少了更新。今天冒个泡。说下UART通信接口。 UART扫盲 前面做了SPI和I2C&#xff0c;前两者一个是摩托&#xff0c;一个是飞利浦背书&#xff0c;简单好理解。这个UART就相对复杂一点&#xff0c;全称universal Asynchronous Receiver/Transmitter …

UART接口详解

文章目录 简介硬件接线RS232RS485RS232和RS485比较 通信原理uart和usart的区别实例针对STM32的串口数据位特点&#xff0c;改成对应PC的串口数据校验当使用9600波特率的时候&#xff0c;通讯稳定&#xff0c;当使用115200波特率的时候&#xff0c;通讯变得不稳定。 简介 UART全…

UART接口介绍

0 Preface/Foreword UART是Universal Asynchronous Receiver and Transmitter简称&#xff0c;中文为 通用异步接收和发送器&#xff0c;是常用的串行通讯接口。 RS-232&#xff1a;RS-232标准接口&#xff08;aka. EIA RS-232&#xff09;是常用的串行通信接口标准之一&#…

一文理解UART通信

还记得当年的打印机&#xff0c;鼠标和调制解调器吗?他们都有巨大笨重的连接器和粗电缆&#xff0c;并且必须拧到你的电脑上。这些设备正是使用UART协议与计算机进行通信。虽然USB几乎完全取代了旧的电缆和连接器&#xff0c;但UART绝对没有过时。您会发现目前许多项目中使用U…

Ajax传json对象(jQuery)

Ajax传json对象 相信很多小伙伴想要通过Ajax传输json数据给后端&#xff0c;本来直接发送一个data: JSON.stringify(obj)就可以了&#xff0c;但是发现后端的请求参数中有一个参数需要int类型&#xff0c;这个时候就需要用到对象了。 封装对象 首先得到数据并封装对象 &…

十分钟搞懂JSON(JSON对象---JSON字符串---对象 之间的区别)

好记性不如烂笔头&#xff0c;相信我&#xff0c;看了之后你会彻底搞懂JSON 前言&#xff1a;前天被JSON对象&#xff0c;JSON字符串&#xff0c;JAVA对象搞混了&#xff0c;不知道各自代表的意思&#xff0c;我就查了资料&#xff0c;总结为一篇博文。 另外我想List<User&g…

【python】将json字符串转化为json对象

首先导入python自带的json模块 import json loads方法将json<key,value>字符串转化为dict形式 info {"name":"Lucy","age":22,"addr": "China"} print(type(info)) info_dict json.loads(info) print(info_dict)…

将js对象转化为json对象

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><script type"text/javascript">//编写 一个JavaScript对象&#xff0c;var user {name: "asdas",age…

Mysql JSON对象和JSON数组查询

文章目录 1. 函数说明2. JSON对象3. 字符串JSON数组3.1 AND关系3.2 OR关系 4. 对象数组5. 集成 Mybatis plus6. 模糊查询7. json_table7.1 分组计算总数7.2 对象去重 file_type可以是 varchar&#xff0c;也可以是 json类型 1. 函数说明 JSON_CONTAINS(json_doc, val[, path…

Json对象和Json字符串的区别

Json对象和Json字符串的区别 </h1><div class"clear"></div><div class"postBody"><div id"cnblogs_post_body" class"blogpost-body blogpost-body-html">1、Json概念 概念&#xff1a;JSON (JavaSc…

获取json对象的key

获取json对象的key值 我有一个json对象&#xff0c;我想获取每一个学生的信息&#xff0c;但是每次拿到的数据最外层的key值是随学生人数增加而变化的&#xff0c;并不是固定的。 所以我的思路为&#xff1a;先获取最外层的key&#xff0c;然后根据key获取value。 实现过程如下…

js操作json对象

工作中做了几款自动化测试工具都是跟日志读取相关&#xff0c;日志格式又大多数都是JSON&#xff0c;所以这里把常用的JS操作JSON的方法做了总结&#xff1a; 一、概念简介 JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式&#xff0c;采用完全独立于语言的文本格…

嵌套 JSON 对象中的数组

JSON 对象中数组可以包含另外一个数组&#xff0c;或者另外一个 JSON 对象&#xff1a; var myObj {"name":"网站","num":3,"sites": [{ "name":"Google", "info":[ "Android", "Googl…

Js 给JSON对象排序

众所周知&#xff0c;json对象是没有顺序的。只有数组才有排序功能。 但我们遇到的业务场景里面&#xff0c;不仅仅需要对数组排序&#xff0c;也有需要对对象排序的情况。 例如下面这种数据&#xff1a; let data {zhangsan: {age: 18, height: 189}, lisi: {age: 18, hei…