STM32串口通信基本原理

通信方式

并行通信

传输原理:数据各个位同时传输

优点:速度快(一个引脚传输一个位)

缺点:占用引脚资源多

串行通信

传输原理:数据按位顺序传输

优点:占用引脚资源少(一个引脚都可以)

缺点:速度相对较慢

串行通信

按照数据传送方向,分为

单工:数据传输只支持数据在一个方向上传输

半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信

全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力

串口通信三种传送方式

串行通信的通信方式

同步通信:带时钟同步信号传输。-SPI,IIC通信接口

异步通信:不带时钟同步信号。-UART(通用异步收发器),单总线

在同步通信中,收发设备上方会使用一根信号线传输信号,在时钟信号的驱动下双方进行协调,同步数据。例如,通讯中通常双方会统一规定在时钟信号的上升沿或者下降沿对数据线进行采样。

在异步通信中不使用时钟信号进行数据同步,它们直接在数据信号中穿插一些用于同步的信号位,或者将主题数据进行打包,以数据帧的格式传输数据。通讯中还需要双方规约好数据的传输速率(也就是波特率)等,以便更好地同步。常用的波特率有4800bps、9600bps、115200bps等。

在同步通讯中,数据信号所传输的内容绝大部分是有效数据,而异步通讯中会则会包含数据帧的各种标识符,所以同步通讯效率高,但是同步通讯双方的时钟允许误差小,稍稍时钟出错就可能导致数据错乱,异步通讯双方的时钟允许误差较大。

常见的串行通信接口

STM32的串口通信接口

UART:通用异步收发器

USART:通用同步异步收发器

UART异步通信方式引脚连接方式

RXD:数据输入引脚。数据接收

TXD:数据发送引脚。数据发送

UART异步通信方式特点

全双工异步通信

分数波特率发生器系统,提供精确的波特率。发送和接受共用的可编程波特率,最高可达4.5Mbits/s

可编程的数据子长度(8位或者9位)

可配置的停止位(支持1或者2位停止位)

可配置的使用DMA多缓冲器通信

单独的发送器和接收器使能位

检测标志:1,接受缓冲器  2,发送缓冲器空  3,传输结束标志

多个带标志的中断源。触发中断

其他:检验控制,四个错误检测标志

串口通信过程

STM32串口异步通信需要定义的参数

起始位

数据位(8位或者9位)

奇偶校验位(第9位)

停止位(4,15,2位)

波特率设置

常用的串口相关寄存器

USART_SR状态寄存器

USART_DR数据寄存器

USART_BRR波特率寄存器

波特率计算方法

串口操作相关库函数

voidUSART_Init;//串口初始化:波特率,数据字长,奇偶检验位,硬件流控以及收发使能voidUSART_Cmd;//使能串口voidUSART_ITConfig;//使能相关中断voidUSART_SendData;//发送数据到串口,DRuint16_USART_ReceiveData;//接受数据,从DR读取接受到的数据FlagStatusUSART_GetFlagStatus;//获取状态标志位voidUSART_ClearFlag;//清除状态标志位ITStatusUSART_GetITStatus;//获取中断状态标志位voidUSART_ClearTPendingBit;//清除中断状态标志位

USART_InitTypeDef

typedefstruct{//设置波特率uint32_tUSART_BaudRate;/*!USART_BaudRate)))-FractionalDivider=((IntegerDivider-((u32)IntegerDivider))*16)+0.5*///设置字长度uint16_tUSART_WordLength;/*!<='' p=''>

串口配置的一般步骤

STM32串口配置的一般步骤(库函数)

串口时钟使能:RCC_APBxPeriphClockCmd;

GPIO时钟使能:RCC_AHBxPeriphClockCmd;

引脚复用映射:GPIO_PinAFConfig;

GPIO端口模式配置:GPIO_Init;模式配置为GPIO_Mode_AF_PP

串口参数初始化:USART_Init;

开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)

NVIC_Init;

USART_ITConfig;

使能串口:USART_Cmd;

编写中断处理函数:USARTx_IRQHandler;

串口数据收发:

voidUSART_SendData;//发送数据到串口,DR

uint16_tUSART_ReceiveData;//接收数据,从DR读取接收的数据

串口传输状态获取:

FlagStatusUSART_GetFlagStatus;

voidUSART_ClearITPendingBit;

例子配置

voiduart_init(u32bound){GPIO_InitTypeDefGPIO_InitStructure;//GPIO端口设置USART_InitTypeDefUSART_InitStructure;//USART端口设置NVIC_InitTypeDefNVIC_InitStructure;//NVIC中断设置RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);//开启USART1和GPIOA的时钟,使能//USART1_TXGPIOA.9GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//PA.9GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//速度50MHzGPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//复用推挽输出GPIO_Init(GPIOA,&GPIO_InitStructure);//根据指定参数初始化GPIOA//USART1_RXGPIOA.10GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA,&GPIO_InitStructure);//根据指定参数初始化GPIOA.10//Usart1NVIC配置NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//抢占优先级为3NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//子优先级为3NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IRQ通道使能NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化NVIC//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);//根据指定参数初始化串口1USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//开启串口接受中断(USART1_IRQHandler)USART_Cmd(USART1,ENABLE);//使能串口1}voidUSART1_IRQHandler(void)//串口1中断服务程序{u8Res;//8位无标志字符#ifSYSTEM_SUPPORT_OS//如果SYSTEM_SUPPORT_OS为真,则需要支持OSOSIntEnter;#endifif(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//接受中断(接收到的数据必须是0x0d0x0a结尾){Res=USART_ReceiveData(USART1);//读取接收到的数据if((USART_RX_STA&0x8000)==0)//接收未完成{if(USART_RX_STA&0x4000)//接收到了0x0d{if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始elseUSART_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;//接收数据错误,重新开始接收}}}}#ifSYSTEM_SUPPORT_OS//如果SYSTEM_SUPPORT_OS为真,则需要支持OSOSIntExit;#endif}

(0)

相关推荐