STM32的USART1与USART2模块支持多种功能,包括IrDA红外、Smart Card(IC卡)等。本文就其串行数据通讯功能进行讲解。
USART功能图:
一般情况串口都采用异步方式通讯,因此本文只讲解异步通讯方式(UART)。异步模式下串口采用Tx、Rx两线,其数据模式如图:
上图为数据长度为8位(包括1位校验)的情形。位数据的意义:
总线空闲 :空闲时线上为高电平。
起始位 :一位逻辑0信号帧,代表传输开始。
数据位 :可以为7位或8位数据。低位开始传输
校验位: 若启用,使得逻辑1的位数应为偶数(偶校验)或奇数(奇校验)。若不启用,该位由一位数据帧替代(多一位数据)。
停止位: 一位或两位逻辑1,标志一个数据字符传输完成。
※一般情况下个人推荐①数据长度为9位(有效数据8位+一位校验)或②数据8位(无校验);并尽量采用ascii或16进制编码方式。
UART配置结构体LL_USART_InitTypeDef
typedef struct
{
uint32_t BaudRate;/*
配置波特率;通过LL_USART_SetBaudRate()函数实现
@param BaudRate=115200,9600.etc
*/
uint32_t DataWidth;/*
配置数据帧数;通过LL_USART_SetDataWidth()函数实现
@param DataWidth = LL_USART_DATAWIDTH_8B
LL_USART_DATAWIDTH_9B
*/
uint32_t StopBits;/*
设置停止位数;通过LL_USART_SetStopBitsLength()实现
@param StopBits = LL_USART_STOPBITS_0_5 0.5stop bit
LL_USART_STOPBITS_1 1 stop bit
LL_USART_STOPBITS_1_5 1.5stop bits
LL_USART_STOPBITS_2 2stop bits
*/
uint32_t Parity;/*
设置校验位;通过LL_USART_SetParity()实现
@param Parity = LL_USART_PARITY_NONE
LL_USART_PARITY_EVEN 偶校验
LL_USART_PARITY_ODD 奇校验
*/
uint32_t TransferDirection;/*
设置数据收发模式;通过LL_USART_SetTransferDirection()实现
@param TransferDirection = LL_USART_DIRECTION_NONE 双向禁用
LL_USART_DIRECTION_RX 单接收
LL_USART_DIRECTION_TX 单发送
LL_USART_DIRECTION_TX_RX 发送&接收
*/
uint32_t HardwareFlowControl; /*
用于RS232的其他硬件引脚配置(CTS、RTS);通过LL_USART_SetHWFlowCtrl()实现
@param HardwareFlowControl = LL_USART_HWCONTROL_NONE 无
LL_USART_HWCONTROL_RTS RTS
LL_USART_HWCONTROL_CTS CTS
LL_USART_HWCONTROL_RTS_CTS CTS&RTS
*/
uint32_t OverSampling;/*
设置过采样。通过LL_USART_SetOverSampling()实现。※不要更改
@param OverSampling = LL_USART_OVERSAMPLING_16
LL_USART_OVERSAMPLING_8
*/
} LL_USART_InitTypeDef;
__STATIC_INLINE void LL_USART_Enable(USART_TypeDef *USARTx);/*
启用USART模块;生成的初始化代码中已调用。
@param USARTx= USART1
USART2 .etc
*/
__STATIC_INLINE void LL_USART_Disable(USART_TypeDef *USARTx);/*
关闭USART模块
*/
__STATIC_INLINE uint32_t LL_USART_IsEnabled(USART_TypeDef *USARTx);/*
检测USART模块是否已开启。
@retval = 0 !0
*/
※
ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct);/*
USART初始化函数; @retval = SUCCESS ERROR
*/
以下函数与状态寄存器有关(相关函数只用于指示状态,可以不使用):
请在reset时先将使用到的位清零
※但若使能中断,则中断处理完全必须清零状态位方能产生下一次interrupt
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_PE(USART_TypeDef *USARTx);/*
接收使能时,判断是否发生奇偶性校验错误(检测PE位,当错误时置位,通过软件清零)
※当CubeMx设置了奇偶校验时有效
@retval = 1 发生过错误
*/
__STATIC_INLINE void LL_USART_ClearFlag_PE(USART_TypeDef *USARTx);/*
清零PE位。
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_FE(USART_TypeDef *USARTx);/*
判断是否发生帧错误(噪声、断开符)。(检测FE位,当错误时置位,通过软件清零)
@retval = 1 发生过错误
*/
__STATIC_INLINE void LL_USART_ClearFlag_FE(USART_TypeDef *USARTx);/*
清零FE位
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_NE(USART_TypeDef *USARTx);/*
检测噪声错误。(检测NE位,当错误时置位,通过软件清零)
*/
__STATIC_INLINE void LL_USART_ClearFlag_NE(USART_TypeDef *USARTx);/*
清零NE位
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_ORE(USART_TypeDef *USARTx);/*
检测过载错误。(读取寄存器中数据尚未被读取时收到新数据)(ORE位)
*/
__STATIC_INLINE void LL_USART_ClearFlag_ORE(USART_TypeDef *USARTx);/*
清零ORE位
*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_IDLE(USART_TypeDef *USARTx);/*
检测总线空闲;(IDLE位)
*/
__STATIC_INLINE void LL_USART_ClearFlag_IDLE(USART_TypeDef *USARTx);/*
清零IDLE位
*/
以下为使用频繁的状态寄存器相关函数:
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_RXNE(USART_TypeDef *USARTx);/*
读数据非空 ;检测读取数据寄存器RDR状态。
※读取数据寄存器RDR 完全 完成一次数据接收时,该位被置位。@retval =1
※对读取数据寄存器RDR的读取操作可以硬件清零 该位。
不推荐软件清零
*/
__STATIC_INLINE void LL_USART_ClearFlag_RXNE(USART_TypeDef *USARTx);/*慎用*/
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TC(USART_TypeDef *USARTx);/*
发送完成 ;读TC
当发送完一帧,且发送数据寄存器空时@retval = 1
需要通过软件清零
*/
__STATIC_INLINE void LL_USART_ClearFlag_TC(USART_TypeDef *USARTx);
__STATIC_INLINE uint32_t LL_USART_IsActiveFlag_TXE(USART_TypeDef *USARTx);/*
发送数据寄存器空 ; 检测发送数据寄存器TDR状态
※当发送数据寄存器TDR数据被送出时,该位被置位。 @retval = 1
※对发送数据寄存器TDR的写入操作可以硬件清零该位。
不推荐软件清零
*/
__STATIC_INLINE void LL_USART_ClearFlag_TXE(USART_TypeDef *USARTx);/*慎用*/
相关寄存器:
串口中断的使用
关于中断源:
IDLE中断:总线空闲中断
RXNE中断:接收缓冲区非空中断※常用
TC中断:发送完成中断
TXE中断:发送缓冲区空中断
PE中断:校验失败中断※常用
※以上中断发生将同时调用同一中断函数void USARTx_IRQHandler(void)。可在函数内判断具体的中断源。
配置中断使能:
__STATIC_INLINE void LL_USART_EnableIT_IDLE(USART_TypeDef USARTx);/
使能总线空闲中断
*/
__STATIC_INLINE void LL_USART_EnableIT_RXNE(USART_TypeDef USARTx);/
使能RXNE中断
*/
__STATIC_INLINE void LL_USART_EnableIT_TC(USART_TypeDef USARTx);/
使能TC中断
*/
__STATIC_INLINE void LL_USART_EnableIT_TXE(USART_TypeDef USARTx);/
使能TXE中断
*/
__STATIC_INLINE void LL_USART_EnableIT_PE(USART_TypeDef USARTx);/
使能PE中断
*/
**禁用中断 **
函数模板为LL_USART_DisableIT_xxx(USART_TypeDef *USARTx);
中断程序编写
使能串口中断后,中断调用函数为void USART▢_IRQHandler(void)
若启用了多个对应的中断源,则应该在中断函数中
判断中断源,再进行对应操作。
判断原理:
初始化时启用相应中断并软件清零用到的状态位。
当触发相应的事件时,中断源的状态位被置位,其余状态位仍处于初始化后0态。此时跳转执行中断函数void USART▢_IRQHandler(void)
在中断函数中进行用到的状态位的判断,若状态位为1则为中断源
执行完后,将相应状态位清零以使能下一次中断
示例程序:以接收中断为例
在 usart.c中:
void MX_USART1_UART_Init(void)
{
·
·
LL_USART_ClearFlag_RXNE(USART1);//强制清零状态位
LL_USART_EnableIT_RXNE(USART1); //使能RXNE中断
·
}
在it.c中
void USART1_IRQHandler(void)
{
if (LL_USART_IsActiveFlag_RXNE(USART1))//判断中断源
{
LL_USART_TransmitData8(USART1, LL_USART_ReceiveData8(USART1));/*读接收寄存器(8bit)并发送,
*读操作自动清零状态位*/
//LL_USART_ClearFlag_RXNE(USART1);//强制清零状态位,不推荐使用
}
}
相关文章