STM32--USART详解

STM32–USART详解
1 串口的基本概念
在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互联网),智能卡协议和IrDA(红外数据组织)SIR ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。还可以使用DMA方式,实现高速数据通信。
USART通过3个引脚与其他设备连接在一起,任何USART双向通信至少需要2个引脚:接受数据输入(RX)和发送数据输出(TX)。

RX: 接受数据串行输入。通过过采样技术来区别数据和噪音,从而恢复数据。

TX: 发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处处于高电平。在单线和智能卡模式里,此I/O口被同时用于数据的发送和接收。
2 串口工作方式
一般有两种方式:查询与中断
(1)查询:串口程序不断地循环查询,看看当前有没有数据要它传送。如果有,就帮助传送(可以从PC到STM32板子,也可以从STM32板子到PC)。

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

在这里插入图片描述
芯片与芯片的连接方式

在这里插入图片描述
芯片与PC机的连接方式
4 串口配置一般步骤

在这里插入图片描述
(1)RCC配置:

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

(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口。

(3)USART配置:

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

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

(4)NVIC配置:

通过结构体USART_InitTypeDef来确定。UART模式下的字段如下:

USART_BaudRate:波特率(每秒能传输的数据位),缺省值为9600。

USART_WordLength:字长

USART_StopBits:停止位

USART_Parity:校验方式(奇偶校验)

USART_HardwareFlowControl:硬件流控制

USART_Mode:单/双工,即收发状态。

最后通过USART_Init()来设置。

(5) 发送/接收数据。

在RCC配置中,我们除了常规的时钟设置以外,要记得打开USART相对应的IO口时钟,USART时钟,还有管脚功能复用时钟。

在GPIO配置中,将发送端的管脚配置为复用推挽输出,将接收端的管脚配置为浮空输入。

在USART的配置中,通过USART_InitTypeDef结构体对USART进行初始化操作,按照自己所需的功能配置好就可以了。注意,在超级终端的设置中,需要和这个里面的配置相对应。由于我是采用中断接收数据的方式,所以记得在USART的配置中要打开串口的中断,同时最后还要打开串口。

在NVIC的配置中,主要是USART1_IRQChannel的配置。

全部配置好之后就可以开始发送/接收数据了。发送数据用USART_SendData()函数,接收数据用USART_ReceiveData()函数。具体的函数功能可以参考固件库的参考文件。根据USART的配置,在发送和接收时,都是采用的8bits一帧来进行的,因此,在发送的时候,先开辟一个缓存区,将需要发送的数据送入缓存区,然后再将缓存区中的数据发送出去,在接收的时候,同样也是先接收到缓存区中,然后再进行相应的操作。

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

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

按照上面的方法编程后,我们便可以在超级终端上查看串口通信的具体状态了。我的这个例程,在硬件复位以后,可以马上在超级终端上看见“Welcome to my STM32! Please press any key!”字样,然后如果在超级终端中通过PC机键盘按下相应的键,则这个键会发送到STM32中,并且马上返回到PC机的超级终端上,因此可以马上从超级终端的页面中看到按下的相应的键。
uart初始化代码如下:

在这里插入代void uart_init(u32 bound)
	{
  //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   GPIOA.9
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
   
  //USART1_RX	  GPIOA.10初始化
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

  //Usart1 NVIC 配置
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
  
   //USART 初始化设置

	USART_InitStructure.USART_BaudRate = bound;//串口波特率
	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); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}

uart1中断服务函数

在这里插入代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;//接收数据错误,重新开始接收	  
					}		 
				}
			}   		 
     } 

主函数的代码主要是通过电脑上的丁丁给单片机发送指令,然后通过串口1再发送到丁丁的一个过程。

if(USART_RX_STA&0x8000)
		{					   
			len=USART_RX_STA&0x3fff;//得到此次接收到的数据长度
			printf("\r\n您发送的消息为:\r\n\r\n");
			for(t=0;t<len;t++)
		{
				USART_SendData(USART1, USART_RX_BUF[t]);//向串口1发送数据
				while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
		}
			printf("\r\n\r\n");//插入换行
			USART_RX_STA=0;
		}else
		{
			times++;
			if(times%5000==0)
		{
				printf("\r\n战舰STM32开发板 串口实验\r\n");
			printf("正点原子@ALIENTEK\r\n\r\n");
			}
			if(times%200==0)
				printf("请输入数据,以回车键结束\n");  
			if(times%30==0)
				LED0=!LED0;//闪烁LED,提示系统正在运行.
			delay_ms(10);   
		}

通过以上的代码就可以实验单片机与PC机的通讯,从而达到数据传输的目的。

串口打印程序
Printf支持

            
//标准库需要的支持函数                 
struct __FILE 
{ 
	int handle; 

}; 

FILE __stdout;       
//定义_sys_exit()以避免使用半主机模式    
_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("\r\n您发送的消息为:\r\n\r\n");

通过以上的程序段就可以实现串口打印,该功能应用比较广泛,一般用于读取代码中的数据,然后进行调试。

5 串口通讯相关知识讲解
并行通信和串行通信
在这里插入图片描述
串行通信
在这里插入图片描述
URAT,SPI,IIC区别
在这里插入图片描述
STM32异步通信定义的参数
在这里插入图片描述
STM32串口通信过程
在这里插入图片描述
总结:这样我们就可以利用串口助手,来调控程序,知道程序的流程。从而调试程序。STM32串口的学习就到此为止。当然当PC向STM32发送数据时,直接用USART_ReceiveData函数即可,若要接受大量的数据,做成一个数组buff即可。当然这个过程在中断中实现比较好。

  • 54
    点赞
  • 416
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: USART_ITConfig函数是一个用于配置USART中断的函数。该函数的作用是使能或禁止USART的中断,并设置中断类型。 该函数的参数包括USARTx,中断类型和使能/禁止标志。其中,USARTx表示要配置的USART,中断类型包括接收中断、发送中断和空闲中断,使能/禁止标志用于控制中断的开关。 使用USART_ITConfig函数可以方便地配置USART的中断,从而实现USART的数据传输和处理。在使用该函数时,需要注意中断类型和使能/禁止标志的设置,以确保USART的正常工作。 ### 回答2: USART_ITConfig是一个USART库函数,它主要用于控制USART的中断使能或禁用。这个函数的定义如下: void USART_ITConfig(USART_TypeDef* USARTx, uint32_t USART_IT, FunctionalState NewState); 其中,USARTx是指向要配置的USART外设的指针,USART_IT是要配置的中断类型,NewState是中断状态,可以是ENABLE或DISABLE。 USART_IT参数可以是以下值之一: USART_IT_TXE:当USART的发送数据寄存器为空时会触发这个中断。 USART_IT_TC:当USART的发送数据寄存器为空并且发送完最后一个数据后会触发这个中断。 USART_IT_RXNE:当USART接收到一个数据后会触发这个中断。 USART_IT_IDLE:当USART接收到一帧数据后,在接收行为完成之前会出发这个中断。 USART_IT_LBD:当LIN Break检测到时会出发这个中断。 USART_IT_CTS:当CTS改变状态时会触发这个中断。 NewState参数可以是ENABLE,表示使能中断;或者是DISABLE,表示禁用中断。 在使用USART_ITConfig函数之前,我们需要先初始化USART外设,通过USART_Init函数来设置串口的波特率、数据位、校验位和停止位等参数。然后,通过USART_Cmd函数使能USART外设。接下来,在需要使用中断的地方,调用USART_ITConfig函数来使能中断。当外设产生需要中断的事件时,中断程序会被自动调用。 总之,USART_ITConfig函数通过控制USART外设的中断使能或者禁用来实现和管理USART的中断功能。这个函数在使用USART外设进行串口通信的时候非常重要,可以帮助我们及时处理收发数据时产生的中断事件,从而提高串口通信的稳定性和可靠性。 ### 回答3: USART_ITConfig函数是一个针对USART中断的函数,它包含了使能和禁用特定中断的功能。 USART_ITConfig函数有两个参数:USARTx和USART_IT。 USARTx参数指定了所要控制的串口模块,即USARTx可以是USART1、USART2、USART3或UART4中的任意一个。 USART_IT参数用于指定具体的中断源,它包括以下几个选项: USART_IT_TXE:表示当数据寄存器为空,且数据可以被发送时,触发此中断。 USART_IT_TC:表示当发送完成后,触发此中断。 USART_IT_RXNE:表示当数据寄存器非空,且有新的数据可用时,触发此中断。 USART_IT_IDLE:表示当检测到空闲线路时,触发此中断。 USART_IT_PE:表示当发生奇偶校验错误时,触发此中断。 USART_IT_ERR:表示当发生任一种错误时,触发此中断。 该函数的功能就是用于在USARTx串口模块中开启或关闭USART_IT选项指定的中断,以达到控制中断的目的。 例如:如果需要开启串口的接收中断,则可以使用代码USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE)来实现。该语句指定了使能USARTx串口模块的接收中断。 如果需要禁用某个中断,则可以用代码USART_ITConfig(USARTx, USART_IT_TXE, DISABLE)来关闭USARTx串口模块的数据寄存器为空中断。 在使用USART_ITConfig函数时,还需要注意中断服务程序(ISR)的编写。只有在将中断使能相应地开启或关闭后,中断控制器才会向中断向量表中对应的ISR跳转,否则ISR将不会被执行。 当USART_ITConfig函数成功地使能或关闭中断后,串口模块就可以在数据传输过程中及时响应特定事件,实现更为灵活的数据处理方式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值