STM32F103ZET6 串口

【 STM32的串口通信接口 】

UART:通用异步收发器
USART:通用同步异步收发器
大容量STM32F10x系列芯片,包含3个USART和2个UART

1. UART

( 定义 )

通用异步收发器,是一种异步收发传输器,它将要传输的资料在串行通信与并行通信之间加以转换。作为把并行输入信号转成串行输出信号的芯片,UART通常被集成于其他通讯接口的连结上。UART是串口,但串口不一定是UART,它包含了UART。

( UART异步通信方式特点 )

  1. 全双工异步通信。
  2. 分数波特率发生器系统,提供精确的波特率。
    发送和接受共用的可编程波特率,最高可达4.5Mbits/s。
  3. 可编程的数据字长度(8位或者9位)。
  4. 可配置的停止位(支持1或者2位停止位)。
  5. 可配置的使用DMA多缓冲器通信。
  6. 单独的发送器和接收器使能位。
  7. 检测标志:① 接受缓冲器 ②发送缓冲器空 ③传输结束标志。
  8. 多个带标志的中断源,触发中断。
  9. 其他:校验控制,四个错误检测标志。

(UART异步通信方式引脚 )

( UART异步通信方式引脚连接方法 )

-RXD:数据输入引脚。数据接受。
-TXD:数据发送引脚。数据发送。
在这里插入图片描述
在这里插入图片描述

2. USART

(定义)

  1. 通用同步/异步串行接收/发送器 。
  2. USART是一个全双工通用同步/异步串行收发模块,该接口是一个高度灵活的串行通信设备。

(特点)

  1. 全双工操作(相互独立的接收数据和发送数据);
  2. 同步操作时,可主机时钟同步,也可从机时钟同步;
  3. 独立的高精度波特率发生器,不占用定时/计数器;
  4. 支持5、6、7、8和9位数据位,1或2位停止位的串行数据桢结构;
  5. 由硬件支持的奇偶校验位发生和检验;
  6. 数据溢出检测;
  7. 帧错误检测;
  8. 包括错误起始位的检测噪声滤波器和数字低通滤波器;
  9. 三个完全独立的中断,TX发送完成、TX发送数据寄存器空、RX接收完成;
  10. 10.支持多机通信模式;
  11. 11.支持倍速异步通信模式。

【STM32串口通信过程】

在这里插入图片描述

【STM32串口异步通信参数】

  1. 起始位
  2. 数据位(8位或者9位)
  3. 奇偶校验位(第9位)
  4. 停止位(1,15,2位)
  5. 波特率设置
    在这里插入图片描述

【 STM32串口内部结构 】

在这里插入图片描述

【 STM32串口常用寄存器 】

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

【 STM32波特率计算方法 】

在这里插入图片描述
在这里插入图片描述

【STM32串口常用库函数】

  1. void USART_Init(); //串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能

  2. void USART_Cmd();//使能串口

  3. void USART_ITConfig();//使能相关中断

  4. void USART_SendData();//发送数据到串口,DR

  5. uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据

  6. FlagStatus USART_GetFlagStatus();//获取状态标志位

  7. void USART_ClearFlag();//清除状态标志位

  8. ITStatus USART_GetITStatus();//获取中断状态标志位

  9. void USART_ClearITPendingBit();//清除中断状态标志位

【STM32串口函数格式】

  1. 使能串口时钟,使能GPIO时钟。
  2. 配置GPIO端口模式(查表得)。
  3. 串口参数初始化。
  4. 开启中断并且初始化NVIC。(如果需要开启中断才需要这个步骤)。
  5. 编写中断处理函数。(如果需要开启中断才需要这个步骤)。

【STM32串口标志位USART_RX_STA】

#define USART_REC_LEN 200 //定义最大接收字节数 200
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.末字节为换行符
u16 USART_RX_STA; //接收状态标记
程序要求,发送的字符是以回车换行结束(0x0D,0x0A)
在这里插入图片描述
标志位核心代码

	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;//接收错误,重新开始(0xod后应该是0x0a)
				else USART_RX_STA|=0x8000;	//接收完成了 
				}
			else //上一次接收到的数据不是0x0d
				{	
				if(Res==0x0d)USART_RX_STA|=0x4000;  //这次接收到0x0d,标志位bit14置1
				else   //这次没接收到0x0d,接收到数据位
					{
					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;  //存入缓冲区
					USART_RX_STA++;      //有效数据个数+1
					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误(大于缓冲区预定长度),重新开始接收	  
					}		 
				}
			}   		 
     } 

【 STM32串口代码范例 】

电脑发送字符到STM32,STM32接收并返回给电脑

#include "stm32f10x.h"
void myUSART_InitTypeDef(void)
{
	GPIO_InitTypeDef MyGPIOstruct; 
  USART_InitTypeDef MyUSARTstruct;	
	NVIC_InitTypeDef  MyNVICstruct;
	                                                                       /************①使能相应时钟***********/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);   //GPIO 时钟使能
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);  //串口时钟使能
                                                                        /*************②初始化IO口模式(查表得)*******/
	MyGPIOstruct.GPIO_Mode=GPIO_Mode_AF_PP;   //GPIO模式配置Pin9, TXD
	MyGPIOstruct.GPIO_Pin=GPIO_Pin_9;
	MyGPIOstruct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&MyGPIOstruct);
	
	MyGPIOstruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;   //GPIO模式配置Pin10,RXD
	MyGPIOstruct.GPIO_Pin=GPIO_Pin_10;
	MyGPIOstruct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&MyGPIOstruct);
	                                                                      /***********③初始化串口相关参数***************/
	MyUSARTstruct.USART_BaudRate=115200;  //波特率配置
	MyUSARTstruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;  //不适用硬件流
	MyUSARTstruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;    //发送和接收均使能
	MyUSARTstruct.USART_Parity=USART_Parity_No; //不使用奇偶校验位
	MyUSARTstruct.USART_StopBits=USART_StopBits_1;   //一个停止位
	MyUSARTstruct.USART_WordLength=USART_WordLength_8b; //8位字长
	USART_Init(USART1,&MyUSARTstruct);
	
	USART_Cmd(USART1,ENABLE); //使能串口1
	                                                                   /************④中断配置******************/
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);   //开启接收中断,接收数据后执行中断函数
	
	MyNVICstruct.NVIC_IRQChannel=USART1_IRQn; //串口1入口参数
	MyNVICstruct.NVIC_IRQChannelCmd=ENABLE;   //使能
	MyNVICstruct.NVIC_IRQChannelPreemptionPriority=1;      //设置抢占优先级 
	MyNVICstruct.NVIC_IRQChannelSubPriority=1;              //设置响应优先级
	NVIC_Init(&MyNVICstruct);   //设置相应中断响应优先级和抢占优先级
}

void USART1_IRQHandler(void)
{
	u8 res1;
	if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))  //第二个参数确定中断类型,即接收中断
	{
		res1=USART_ReceiveData(USART1);
	  USART_SendData(USART1,res1);
	}
}


 int main(void)
 {	
	 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //系统优先级分组2
	 myUSART_InitTypeDef();
	 
	 while(1);
 }
发布了19 篇原创文章 · 获赞 2 · 访问量 699

猜你喜欢

转载自blog.csdn.net/qq_44431690/article/details/104114808