历史上的今天
今天是:2024年09月24日(星期二)
2019年09月24日 | 关于STM32的USART_GetFlagStatus和USART_GetITStatus解析
2019-09-24 来源:eefocus
前言
STM32固件库中提供了串口收发的标志位函数,包括USART_GetFlagStatus(…,…);和USART_GetITStatus(…,…);,两者容易混淆,重点区别就在于:前者返回值是中断标志位状态(读SR寄存器),后者返回值是中断发生与否的判断(读CR寄存器),以下主要对这两个函数进行分析。
一、USART_GETFlagStatus(…,…)
/**
* @brief Checks whether the specified USART flag is set or not.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param USART_FLAG: specifies the flag to check.
* This parameter can be one of the following values:
* @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5)
* @arg USART_FLAG_LBD: LIN Break detection flag
* @arg USART_FLAG_TXE: Transmit data register empty flag
* @arg USART_FLAG_TC: Transmission Complete flag
* @arg USART_FLAG_RXNE: Receive data register not empty flag
* @arg USART_FLAG_IDLE: Idle Line detection flag
* @arg USART_FLAG_ORE: OverRun Error flag
* @arg USART_FLAG_NE: Noise Error flag
* @arg USART_FLAG_FE: Framing Error flag
* @arg USART_FLAG_PE: Parity Error flag
* @retval The new state of USART_FLAG (SET or RESET).
*/
FlagStatus USART_GetFlagStatus(USART_TypeDef* USARTx, uint16_t USART_FLAG)
{
FlagStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_FLAG(USART_FLAG));
/* The CTS flag is not available for UART4 and UART5 */
if (USART_FLAG == USART_FLAG_CTS)
{
assert_param(IS_USART_123_PERIPH(USARTx));
}
if ((USARTx->SR & USART_FLAG) != (uint16_t)RESET)
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
1.代码解析
该函数用于检测串口中断标志位的状态。
其中,24、25、29三行用于检测所用参数是否符合该函数的范围。该函数的第一个形参只能是USART1,USART2,USART3,UART4,UART5,第二个形参只能是以下内容:
从32行开始,检测SR寄存器的状态,在SET和RESET中进行比较。
2.函数使用
函数返回值为SET或RESET,即可直接用于判断。
在没有使能相应的中断函数时,通常使用该函数来判断标志位是否置位。
但串口触发中断后,需要清除标志位,由文章后部分描述。
二、USART_GetITStatus(…,…)
/**
* @brief Checks whether the specified USART interrupt has occurred or not.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param USART_IT: specifies the USART interrupt source to check.
* This parameter can be one of the following values:
* @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
* @arg USART_IT_LBD: LIN Break detection interrupt
* @arg USART_IT_TXE: Tansmit Data Register empty interrupt
* @arg USART_IT_TC: Transmission complete interrupt
* @arg USART_IT_RXNE: Receive Data register not empty interrupt
* @arg USART_IT_IDLE: Idle line detection interrupt
* @arg USART_IT_ORE: OverRun Error interrupt
* @arg USART_IT_NE: Noise Error interrupt
* @arg USART_IT_FE: Framing Error interrupt
* @arg USART_IT_PE: Parity Error interrupt
* @retval The new state of USART_IT (SET or RESET).
*/
ITStatus USART_GetITStatus(USART_TypeDef* USARTx, uint16_t USART_IT)
{
uint32_t bitpos = 0x00, itmask = 0x00, usartreg = 0x00;
ITStatus bitstatus = RESET;
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_GET_IT(USART_IT));
/* The CTS interrupt is not available for UART4 and UART5 */
if (USART_IT == USART_IT_CTS)
{
assert_param(IS_USART_123_PERIPH(USARTx));
}
/* Get the USART register index */
usartreg = (((uint8_t)USART_IT) >> 0x05);
/* Get the interrupt position */
itmask = USART_IT & IT_Mask;
itmask = (uint32_t)0x01 << itmask;
if (usartreg == 0x01) /* The IT is in CR1 register */
{
itmask &= USARTx->CR1;
}
else if (usartreg == 0x02) /* The IT is in CR2 register */
{
itmask &= USARTx->CR2;
}
else /* The IT is in CR3 register */
{
itmask &= USARTx->CR3;
}
bitpos = USART_IT >> 0x08;
bitpos = (uint32_t)0x01 << bitpos;
bitpos &= USARTx->SR;
if ((itmask != (uint16_t)RESET)&&(bitpos != (uint16_t)RESET))
{
bitstatus = SET;
}
else
{
bitstatus = RESET;
}
return bitstatus;
}
1.代码解析
代码中分别读取串口控制寄存器CR1,CR2,CR3的状态,获取中断发生的动作,返回SET或RESET。

2.函数使用
函数返回值为SET或RESET,即可直接用于判断。
除了可以判断中断标志位外,还能判断是否发生了中断。
但串口触发中断后,需要清除标志位,由文章后部分描述。
三、 USART_ClearFlag(…,…);
/**
* @brief Clears the USARTx's pending flags.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param USART_FLAG: specifies the flag to clear.
* This parameter can be any combination of the following values:
* @arg USART_FLAG_CTS: CTS Change flag (not available for UART4 and UART5).
* @arg USART_FLAG_LBD: LIN Break detection flag.
* @arg USART_FLAG_TC: Transmission Complete flag.
* @arg USART_FLAG_RXNE: Receive data register not empty flag.
*
* @note
* - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
* error) and IDLE (Idle line detected) flags are cleared by software
* sequence: a read operation to USART_SR register (USART_GetFlagStatus())
* followed by a read operation to USART_DR register (USART_ReceiveData()).
* - RXNE flag can be also cleared by a read to the USART_DR register
* (USART_ReceiveData()).
* - TC flag can be also cleared by software sequence: a read operation to
* USART_SR register (USART_GetFlagStatus()) followed by a write operation
* to USART_DR register (USART_SendData()).
* - TXE flag is cleared only by a write to the USART_DR register
* (USART_SendData()).
* @retval None
*/
void USART_ClearFlag(USART_TypeDef* USARTx, uint16_t USART_FLAG)
{
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_CLEAR_FLAG(USART_FLAG));
/* The CTS flag is not available for UART4 and UART5 */
if ((USART_FLAG & USART_FLAG_CTS) == USART_FLAG_CTS)
{
assert_param(IS_USART_123_PERIPH(USARTx));
}
USARTx->SR = (uint16_t)~USART_FLAG;
}
1.代码解析
该函数用于软件清除标志位。
例如,常用的参数为USART_FLAG_RXNE,库中定义的参数为0x0020,取反后为0xFFDF,恰好可以使SR寄存器的RXNE位置零(根据参考手册)。同时根据函数note,USART_FLAG_RXNE也可以通过读DR寄存器进行清位,即调用函数USART_ReceiveData();。
2.函数使用
可以用在中断处理函数中对标志位进行清除操作。
四、USART_ClearITPendingBit(…,…);
/**
* @brief Clears the USARTx's interrupt pending bits.
* @param USARTx: Select the USART or the UART peripheral.
* This parameter can be one of the following values:
* USART1, USART2, USART3, UART4 or UART5.
* @param USART_IT: specifies the interrupt pending bit to clear.
* This parameter can be one of the following values:
* @arg USART_IT_CTS: CTS change interrupt (not available for UART4 and UART5)
* @arg USART_IT_LBD: LIN Break detection interrupt
* @arg USART_IT_TC: Transmission complete interrupt.
* @arg USART_IT_RXNE: Receive Data register not empty interrupt.
*
* @note
* - PE (Parity error), FE (Framing error), NE (Noise error), ORE (OverRun
* error) and IDLE (Idle line detected) pending bits are cleared by
* software sequence: a read operation to USART_SR register
* (USART_GetITStatus()) followed by a read operation to USART_DR register
* (USART_ReceiveData()).
* - RXNE pending bit can be also cleared by a read to the USART_DR register
* (USART_ReceiveData()).
* - TC pending bit can be also cleared by software sequence: a read
* operation to USART_SR register (USART_GetITStatus()) followed by a write
* operation to USART_DR register (USART_SendData()).
* - TXE pending bit is cleared only by a write to the USART_DR register
* (USART_SendData()).
* @retval None
*/
void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT)
{
uint16_t bitpos = 0x00, itmask = 0x00;
/* Check the parameters */
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_CLEAR_IT(USART_IT));
/* The CTS interrupt is not available for UART4 and UART5 */
上一篇:USART里面TXE和TC的用法
史海拾趣
|
我按照图1的电路接法,然后根据DS18B20的数据手册时序图编写代码,但总是85℃。。。请遇到过这种情况的电子爱好者指导一下: /***********ds18b20子程序*************************/ /******************************ds1820程序****************** ...… 查看全部问答> |
|
板子(数字)上电始会有一个大的过冲,大概有0.60A(12V上电,通过电源芯片转为3.3V输出供电),而且持续几秒,才会降到0.09A。 板上差不多只有一些SRAM,SDRAM,68013还是RS232电平转换芯片,电源块测过没问题,但是一旦连上后端电路,再上电就会 ...… 查看全部问答> |
|
一般来说,下面几类人,容易被HR快速拒绝。 开口言钱者不要 报酬不是不可以问,但得讲究时机和氛围。如果刚一交谈,就开门见山、直奔主题地问起薪酬待遇,会让企业感到很不舒服。 纠缠不休者不要。 招聘都遵循一定的流程,说几时给消息就几时给 ...… 查看全部问答> |
|
请教大家一个问题: 我在wince下的edit控件中输入汉字、数字、字母,并保存在临时文件中。当我再次打开对话框,把临时文件中的东东全部放回edit控件时,数字和字母能正确显示,但是汉字只显示问号“?”!请问这是什么原因? 下面是代码 当edit ...… 查看全部问答> |
|
时间:2007年03月31日下午1:00-5:00 地点:上海电力学院平凉路校区小礼堂(暂定) 路线:上海市杨浦区平凉路2103号 近隆昌路 专题1 基于ARM的嵌入式开发(13:30-14:30) 专题2 Windows CE揭秘(14:40-15:40) 专题3 嵌入式Linux系统平台构建 ...… 查看全部问答> |
|
过年了,为庆祝在eeworld上的总技术分突破3000分,特散300分,先200分,往后加100分 过年了,为庆祝在eeworld上的总技术分突破3000分,特散300分,先200分,往后加100分… 查看全部问答> |
|
最easy的一个问题,VxWorks下怎么控制评估板上的LED ? VxWorks + ARM7 4510 的评估板, 在ADS下裸机编程调试通过了的一个LED闪灯程序。 把它加入到一个在VxWorks下已经可以运行的程序里面去后。(当然相应的头文件都加上了的) 编译下载,不能闪灯 ...… 查看全部问答> |
|
路由设备NLME_GetCoordShortAddr() 获取的父地址与实际不一致 路由设备NLME_GetCoordShortAddr() 获取的父地址与实际不一致! 刚组网的时候NLME_GetCoordShortAddr() 获取的父地址与实际是一致的, 运行过程中,动态组网,父地址改变,NLME_GetCoordShortAddr() 获取的父地址就与实际不一致了。 有什么途 ...… 查看全部问答> |
|
本帖最后由 guaiguaidou 于 2015-7-27 10:48 编辑 最近学习特权同学的《深入浅出玩转FPGA》一书,想对里面的一个实验进行功能仿真(在书的p60) 但一直都得不到理想情况,请问这个是什么原因? 这是verilog代码: module handshack ( ...… 查看全部问答> |




