USART介绍
通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互连网),智能卡协议和IrDA(红外数据组织)SIRENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。使用多缓冲器配置的DMA方式,可以实现高速数据通信。
USART主要特性
全双工的,异步通信
NRZ标准格式
分数波特率发生器系统
—发送和接收共用的可编程波特率,最高达4.5Mbits/s
可编程数据字长度(8位或9位)
可配置的停止位-支持1或2个停止位
LIN主发送同步断开符的能力以及LIN从检测断开符的能力
—当USART硬件配置成LIN时,生成13位断开符;检测10/11位断开符
发送方为同步传输提供时钟
IRDA SIR编码器解码器
—在正常模式下支持3/16位的持续时间
模拟智能卡功能
—智能卡接口支持ISO7816-3标准里定义的异步智能卡协议
—智能卡用到的0.5和1.5个停止位
单线半双工通信
可配置的使用DMA的多缓冲器通信
—在SRAM里利用集中式DMA缓冲接收/发送字节
单独的发送器和接收器使能位
检测标志
—接收缓冲器满
—发送缓冲器空
—传输结束标志
校验控制
—发送校验位
—对接收数据进行校验
四个错误检测标
—溢出错误
—噪音错误
—帧错误
—校验错误
10个带标志的中断源
—CTS改变
—LIN断开符检测
—发送数据寄存器空
—发送完成
—接收数据寄存器满
—检测到总线为空闲
—溢出错误
—帧错误
—噪音错误
—校验错误
多处理器通信--如果地址不匹配,则进入静默模式
从静默模式中唤醒(通过空闲总线检测或地址标志检测)
两种唤醒接收器的方式:地址位(MSB,第9位),总线空闲
USART功能概述
任何USART双向通信至少需要两个脚:接收数据输入(RX)和发送数据输出(TX)。RX:接收数据串行输。通过过采样技术来区别数据和噪音,从而恢复数据。
TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处于高电平。
1、字符发送
在USART发送期间,在TX引脚上首先移出数据的最低有效位。在此模式里,USART_DR寄存器包含了一个内部总线和发送移位寄存器之间的缓冲器。
每个字符之前都有一个低电平的起始位;之后跟着的停止位,其数目可配置。USART支持多种停止位的配置:0.5、1、1.5和2个停止位。
配置步骤:
通过在USART_CR1寄存器上置位UE位来激活USART
编程USART_CR1的M位来定义字长。
在USART_CR2中编程停止位的位数。
如果采用多缓冲器通信,配置USART_CR3中的DMA使能位(DMAT)。按多缓冲器通信中的描述配置DMA寄存器。
利用USART_BRR寄存器选择要求的波特率。
设置USART_CR1中的TE位,发送一个空闲帧作为第一次数据发送。
把要发送的数据写进USART_DR寄存器(此动作清除TXE位)。在只有一个缓冲器的情况下,对每个待发送的数据重复步骤7。
在USART_DR寄存器中写入最后一个数据字后,要等待TC=1,它表示最后一个数据帧的传输结束。当需要关闭USART或需要进入停机模式之前,需要确认传输结束,避免破坏最后一次传输。
2、字符接收
在USART接收期间,数据的最低有效位首先从RX脚移进。在此模式里,USART_DR寄存器包含的缓冲器位于内部总线和接收移位寄存器之间。
配置步骤:
将USART_CR1寄存器的UE置1来激活USART。
编程USART_CR1的M位定义字长
在USART_CR2中编写停止位的个数
如果需多缓冲器通信,选择USART_CR3中的DMA使能位(DMAR)。按多缓冲器通信所要求的配置DMA寄存器。
利用波特率寄存器USART_BRR选择希望的波特率。
设置USART_CR1的RE位。激活接收器,使它开始寻找起始位。
当一字符被接收到时
RXNE位被置位。它表明移位寄存器的内容被转移到RDR。换句话说,数据已经被接收并且可以被读出(包括与之有关的错误标志);
如果RXNEIE位被设置,产生中断;
在接收期间如果检测到帧错误,噪音或溢出错误,错误标志将被置起;
在多缓冲器通信时,RXNE在每个字节接收后被置起,并由DMA对数据寄存器的读操作而清零;
在单缓冲器模式里,由软件读USART_DR寄存器完成对RXNE位清除。RXNE标志也可以通过对它写0来清除。RXNE位必须在下一字符接收结束前被清零,以避免溢出错误。
USART程序编写
开启GPIO、USART1时钟;
对USART引脚进行配置,PA9映射TX,PA10映射RX;
对USART参数进行配置、开启USART的RXNE中断;
对中断参数进行配置;
/*******************************************************************************
* Function Name : USART_Configuration
* Description : Configure USART1
* Input : None
* Output : None
* Return : None
* Attention : None
*******************************************************************************/
void CKS_USART_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
/*USART1_TX -> PA9 , USART1_RX -> PA10*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* USART configuration ------------------------------------------------------*/
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
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);
/* Enable USART RXNE interrupt */
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_Cmd(USART1, ENABLE);
/* NVIC configuration ------------------------------------------------------*/
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
5. 编写USART1_IRQHandler函数;
我们利用USART的IDLE状态位进行不定长度数据接收,当USART被RXNE中断触发后,程序将在该中断函数中轮询,直至串口空闲后IDLE状态位被置位。
/*******************************************************************************
* Function Name : USART1_IRQHandler
* Description : This function handles USART1 global interrupt request.
* Input : None
* Output : None
* Return : None
*******************************************************************************/
void USART1_IRQHandler(void)
{
uint8_t i = 0;
uint8_t j = 0;
if(USART_GetFlagStatus(USART1, USART_IT_RXNE) != RESET)
{
/* get usart data until IDLE flag is set */
while(!USART_GetFlagStatus(USART1, USART_FLAG_IDLE))
{
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) != RESET)
{
CKS_Uart_Buff[i++] = USART_ReceiveData(USART1);
}
}
/* clear uart IDLE flag */
j = USART1->SR;
j = USART1->DR;
/* clear uart RXNE flag */
USART_ClearFlag(USART1, USART_IT_RXNE);
}
}
全部0条评论
快来发表一下你的评论吧 !