IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32学习总结——UART -> 正文阅读

[嵌入式]STM32学习总结——UART

一、STM32 USART

USART的全称是universal synchronous asynchronous receiver and transmitte,中文名叫做通用同步异步收发器。USART是一种非常重要的通信协议,单片机和很多的外设的通信都是用的串口通信,这是一种全双工的异步通信,发送端称为TXD(Transmit Data),接收端称为RXD(Receive Data)。对于串口通信最重要的就是五个量,起始位、数据位,停止位,校验位以及波特率。
在这里插入图片描述
波特率是指每秒传输的数据位数,这是一个非常重要的参数,直接关系到能否正常进行串口通信。波特率是通信双方约定好的一个数值,我理解双方多久检测一下特殊的标志位,如果两边的波特率不同的话,就会出现各种各样的问题。

二、STM32串口通信设置

我们在STM32上使用串口通信时,要把起始位、数据位、校验位以及波特率设置好。话不多说,这就来通过代码来学习STM32的串口通信。

void MyUsart_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;//定义GPIO初始化结构体
	USART_InitTypeDef USART_InitStruct;
	NVIC_InitTypeDef NVIC_InitStruct;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//使能串口时钟和GPIO时钟
	USART_DeInit(USART1);//复位串口
	//
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_9;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIO9
	
	GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	GPIO_InitStruct.GPIO_Pin=GPIO_Pin_10;
	GPIO_InitStruct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);//初始化GPIO10
	//设置串口参数
	USART_InitStruct.USART_BaudRate=115200;
	USART_InitStruct.USART_WordLength=USART_WordLength_8b;//8位数据位
	USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//发送和接收模式
	USART_InitStruct.USART_Parity=USART_Parity_No;//没有校验位
	USART_InitStruct.USART_StopBits=USART_StopBits_1;//1位停止位
	USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	USART_Init(USART1,&USART_InitStruct);
	
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//设置串口接收中断
	USART_Cmd(USART1,ENABLE);//使能串口
	//设置中断
	NVIC_InitStruct.NVIC_IRQChannel=USART1_IRQn;
	NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
	NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
	NVIC_Init(&NVIC_InitStruct);
	//开启中断
}

在这段代码中,设置8位数据位,一位停止位,没有数据位,这是很常用的一种组合,然后把波特率设置成了115200。下面就来总结一下串口的设置方法。

  • 使能相应的串口时钟和GPIO时钟
  • 初始化串口的TXD和RXD所在的GPIO,发送端设置为复用推挽输出,接收端设置为浮空输入
  • 初始化串口,设置串口的数据位(USART_WordLength)、停止位(USART_StopBits)、校验位(USART_Parity)和波特率(USART_BaudRate)。
  • 使能串口
  • 串口中断分为发送中断和接收中断,如果设置了中断,还要设置相应的中断参数。
    串口的设置核心就是设置数据位,停止位,校验位以及波特率,通信双方的这四个参数一定要完全一样才能实现串口通信,双方通过导线交叉连接,TXD接RXD,RXD接TXD。
    虽然串口设置很简单,但是往往在使用串口通信时要通过上位机调试很多次才能排除一个个小错误,确保发送的数据可以被完好无损地收到。所以我觉得串口数据的发送和接收才是重点。

三、串口数据的发送

1.printf发送

在使用STM32标准库时,可以用printf函数来发送字符串,这是非常方便的,下面就来看看怎么通过这种方式发送数据吧
首先写重映射函数

//加入以下代码,支持printf函数,而不需要选择use MicroLIB	  
#if 1
#pragma import(__use_no_semihosting)             
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
void _sys_exit(int x) 
{ 
	x = x; 
} 
//重定义fputc函数 
int fputc(int ch, FILE *f)
{      
	while((USART1->SR&0X40)==0);//循环发送,直到发送完毕   
    USART1->DR = (u8) ch;      
	return ch;
}
#endif 

这一窜代码中选择了串口号,有了这一段代码,就可以直接使用printf(“qwer”)来通过串口发送字符串。

2.使用官方的标准库函数USART_SendData(串口号,数据);

官方的**USART_SendData(USART_TypeDef* USARTx, uint16_t Data);**串口发送函数每次只能发送一个字节,原理就是直接往TDR寄存器写入要发送的字节,如果要用这个发送一个字符串,就要写一个发送函数。

void Send_data(USART_TypeDef * USARTx,u8 *s)
{
 while(*s!='')
 { 
  while(USART_GetFlagStatus(USARTx,USART_FLAG_TC )==RESET); 
  USART_SendData(USARTx,*s);
  s++;
 }
}

这个发送函数是把字符串中的每个字符分开发送,直到字符串结束。

四、串口数据接收

有发送就会有接收,串口接收数据是一个字节一个字节地接收,如果设置了接收中断,那就是收到一个字节就进入一次中断。
下面就来看一个很经典的串口接收函数

void USART1_IRQHandler(void)                	//串口1中断服务程序
	{
	u8 Res;
#if SYSTEM_SUPPORT_OS 		//如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
	OSIntEnter();    
#endif
	if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
		{
		Res =USART_ReceiveData(USART1);	//读取接收到的数据
		
		if((USART_RX_STA&0x8000)==0)//接收未完成
			{
			if(USART_RX_STA&0x4000)//接收到了0x0d
				{
				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //还没收到0X0D
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;
				else
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
					USART_RX_STA++;
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 

在串口接收中断中处理接收到的数据,这段程序中规定发送的数据一定要以0x0a 0x0d结尾,如果是就把接收到的数据放在定义好的接收数组中,然后我们可以在主函数中对数组中接收到的数据进行处理。

五、UART和USART的区别

USART是指单片机的一个端口模块,可以根据需要配置成同步模式(SPI,I2C),也可以将其配置为异步模式,后者就是UART。所以说UART姑且可以称之为一个与SPI,I2C对等的“协议”,而USART则不是一个协议,而是更应该理解为一个实体。
(摘自https://blog.csdn.net/weixin_40774605/article/details/88398709)

总结

串口的设置是设置起始位、数据位、校验位、停止位和波特率,通信的双方要设置相同的参数,并且硬件硬件交叉连接。串口发送函数可以是printf函数,接收函数可以根据具体的数据格斯自行定义,但应该知道每接收到一个字节都可以通过USART_ReceiveData读出。关于串口的部分就先写到这里,后续会进行补充和完善,有错误的地方请指出。

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-08-19 19:22:29  更:2022-08-19 19:23:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 15:02:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码