文章目录[隐藏]
UART
UART全称“通用异步收发器(Universal Asynchronous Receiver/Transmitter)”,是一种串行异步全双工的通信协议,工作原理就是将传输数据的每一个字符一位接一位的传输。
UART的数据帧格式
起始位:先发出一个逻辑”0”的信号,表示传输字符的开始。
数据位:紧接着起始位之后。数据位的个数可以是4、5、6、7、8等,构成一个字符。通常采用ASCII码。
奇偶校验位:数据位加上这一位后,使得“1”的位数应为偶数(偶校验)或奇数(奇校验),以此来校验数据传送的正确性。
停止位:它是一个字符数据的结束标志。可以是1位、1.5位、2位的高电平。
空闲位:处于逻辑“1”状态,表示当前线路上没有数据传送。
波特率:是衡量数据传送速率的指标。表示每秒钟传送的符号数(symbol)。常用的波特率有9600和115200.
波特率与比特率的区别:一个符号代表的信息量(比特数)与符号的阶数有关。例如传输使用256阶符号,每8bit代表一个符号,资料传送速率为120字符/秒,则波特率就是120baud,比特率是120*8=960bit/s。这两者的概念很容易搞错
USART的硬件结构
输出缓冲寄存器:它接收CPU从数据总线上送来的并行数据,并加以保存。
输出移位寄存器:它接收从输出缓冲器送来的并行数据,以发送时钟的速率把数据逐位移出,即将并行数据转换为串行数据输出。
输入移位寄存器:它以接收时钟的速率把出现在串行数据输入线上的数据逐位移入,当数据装满后,并行送往输入缓冲寄存器,即将串行数据转换成并行数据。
输入缓冲寄存器,它从输入移位寄存器中接收并行数据,然后由CPU取走。
控制寄存器:它接收CPU送来的控制字,由控制字的内容,决定通信时的传输方式以及数据格式等。例如采用异步方式还是同步方式,数据字符的位数,有无奇偶校验,是奇校验还是偶校验,停止位的位数等参数。
状态寄存器:状态寄存器中存放着接口的各种状态信息,例如输出缓冲区是否空,输入字符是否准备好等。在通信过程中,当符合某种状态时,接口中的状态检测逻辑将状态寄存器的相应位置“1”,以便让CPU查询。
stm32串口配置步骤
1、初始化USART时钟
2、配置USRAT的引脚(TX:复用推挽输出;RX:浮空输入)
3、初始化USART结构体(设置波特率、模式、无硬件流控制、奇偶校验、停止位、字长)
4、使能USART
5、使能USART中断(设置中断优先级)
6、编写中断服务函数(判断中断类型,清中断标志位)
下面以stm32f103的USART1为例:
usart初始化函数:
void Usart1_Init(u32 baud)
{
GPIO_InitTypeDef GPIO_InitStruct;
//开启io时钟和usart1时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
//配置PA9
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //usart1_TX PA9
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//配置PA10
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; //usart1_RX PA10
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
//配置USART1
USART_InitTypeDef USART1_InitStruct;
USART1_InitStruct.USART_BaudRate = baud;
USART1_InitStruct.USART_Mode = USART_Mode_Tx|USART_Mode_Rx;
USART1_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART1_InitStruct.USART_Parity = USART_Parity_No;
USART1_InitStruct.USART_StopBits = USART_StopBits_1;
USART1_InitStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&USART1_InitStruct);
//使能USART1
USART_Cmd(USART1,ENABLE);
//配置USART1中断,接收非空中断 和 空闲中断
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
//设置中断分组,这个只用配置一次,以在主函数的while前执行,这里就注释了
// NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);
//设置中断优先级(抢占01,响应01)
NVIC_SetPriority(USART1_IRQn,4);
//开启中断
NVIC_EnableIRQ(USART1_IRQn);
}
中断服务函数:
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1,USART_IT_RXNE) == 1)
{
//清中断标志位
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
//将接收到的数据放到u1_buff数组中
u1_buff[u1_bufcnt++]= USART_ReceiveData(USART1);
}
if(USART_GetITStatus(USART1,USART_IT_IDLE) == 1)
{
USART1->DR;//清空闲中断标志比较特殊,需要读状态寄存器和数据寄存器来清
u1_r_flag = 1;//一次数据接收完成标志
u1_buff[u1_bufcnt] = '\0';
}
}
版权声明:本文为CSDN博主「ShallowGreen」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ShallowGreen/article/details/122557230
暂无评论