void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)

函数参数列表中,USART的有效范围为:

#define IS_USART_ALL_PERIPH(PERIPH) (((PERIPH) == USART1) || \((PERIPH) == USART2) || \((PERIPH) == USART3) || \((PERIPH) == UART4) || \((PERIPH) == UART5))

USART_IT的有效范围为:

#define IS_USART_CONFIG_IT(IT) (((IT) == USART_IT_PE) || ((IT) == USART_IT_TXE) || \((IT) == USART_IT_TC) || ((IT) == USART_IT_RXNE) || \((IT) == USART_IT_IDLE) || ((IT) == USART_IT_LBD) || \((IT) == USART_IT_CTS) || ((IT) == USART_IT_ERR))

STATE用于表征寄存器的使能状态,只有两种有效值,DISABLE(0)和ENABLE (1)

#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))

下面的判断语句用于判断中断源是否为 CTS,因为只有在USART1-3中才存在CTS中断,所以这里要对USART进行参数有效性判断!

 if (USART_IT == USART_IT_CTS){assert_param(IS_USART_123_PERIPH(USARTx));}   

将对应的USART串口的基地址赋值给usartbase变量:

  usartxbase = (uint32_t)USARTx;

找到对应串口中的寄存器编号:

 usartreg = (((uint8_t)USART_IT) >> 0x05);

为什么要将USART_IT的低八位右移五位呢?这是STM32那些编程大聪明想到的骚操作,注意USART_IT中各参数的宏定义:

#define USART_IT_PE                          ((uint16_t)0x0028)
#define USART_IT_TXE                         ((uint16_t)0x0727)
#define USART_IT_TC                          ((uint16_t)0x0626)
#define USART_IT_RXNE                        ((uint16_t)0x0525)
#define USART_IT_IDLE                        ((uint16_t)0x0424)
#define USART_IT_LBD                         ((uint16_t)0x0846)
#define USART_IT_CTS                         ((uint16_t)0x096A)
#define USART_IT_ERR                         ((uint16_t)0x0060)
#define USART_IT_ORE                         ((uint16_t)0x0360)
#define USART_IT_NE                          ((uint16_t)0x0260)
#define USART_IT_FE                          ((uint16_t)0x0160)

再取(uint8)强制类型转换以后,注意PE、TXE、TC、RXNE、IDLE中断都是0010 XXXX

而且他们都存在于CR1寄存器中:

PE、TXE、TC、RXNE、IDLE在右移五位以后,结果均为0x01,所以就用0x01用于表征CR1寄存器。

同样推理(uint8)LBD右移五位以后为0x02,所以是否用0x02表征CR2寄存器呢?查看一下LBD是否在CR2寄存器中就知道了~

事实证明没毛病嗷老铁~

再看CTS、ORE、ERR、NE、FE在(uint8)并右移五位以后为0x03,用于表征CR3寄存器。注意在CR3寄存器中,ORE(过载错误)、NE(噪声错误)、FE(帧错误)均由bit0 EIE(可以理解为ERR)表示。

这一步解决了,继续看代码,IT_Mask宏定义为0x001F,与USART相与以后保留低5位,其数值换算为十进制正好就是表征了对应的中断源在对应寄存器中的位置!

 itpos = USART_IT & IT_Mask;     itmask = (((uint32_t)0x01) << itpos);

举个栗子,比如RXNE中断:

#define USART_IT_RXNE                        ((uint16_t)0x0525)

itpos = 0x0005;0000 0000 0000 0000 0000 0000 0001 0000

再看CR1中RXNE位在哪里捏?

哎没毛病嗷老铁!

继续看下面的代码,这一步就是根据刚才确定寄存器的编号,将地址再USARTx的基地址基础上进行相应的偏移。

if (usartreg == 0x01) /* The IT is in CR1 register */{usartxbase += 0x0C;  }else if (usartreg == 0x02) /* The IT is in CR2 register */{usartxbase += 0x10;}else /* The IT is in CR3 register */{usartxbase += 0x14; }

最后就是按部就班的使能或者失能对应的中断:

 if (NewState != DISABLE){*(__IO uint32_t*)usartxbase  |= itmask;    //寄存器相应位置上的中断使能位置1}else{*(__IO uint32_t*)usartxbase &= ~itmask;    //中断使能位置0,其他位保持}

最后做一个小节,学习一下编程技巧:

对于寻找某个寄存器中的具体某一位,可以采取“分段策略”,某一位段用于表征寄存器的编号,其他某一位段用于表征该位在特定寄存器中的具体的位置。

寻找寄存器编号可以采取位移的方法,寻找位可以采取位移+根据位移值对0x1进行反位移操作。

附stm32f10x_usart.c中USART_ITConfig()完整代码:

void USART_ITConfig(USART_TypeDef* USARTx, uint16_t USART_IT, FunctionalState NewState)
{uint32_t usartreg = 0x00, itpos = 0x00, itmask = 0x00;uint32_t usartxbase = 0x00;/* Check the parameters */assert_param(IS_USART_ALL_PERIPH(USARTx));assert_param(IS_USART_CONFIG_IT(USART_IT));assert_param(IS_FUNCTIONAL_STATE(NewState));/* The CTS interrupt is not available for UART4 and UART5 */if (USART_IT == USART_IT_CTS){assert_param(IS_USART_123_PERIPH(USARTx));}   usartxbase = (uint32_t)USARTx;/* Get the USART register index */usartreg = (((uint8_t)USART_IT) >> 0x05);/* Get the interrupt position */itpos = USART_IT & IT_Mask;     //取USART_IT低五位,然而所有的USART_IT的bit4均为0,所以实质上是取低4为,提取了相应中断在寄存器中的位置itmask = (((uint32_t)0x01) << itpos);/* 在对应的USARTx的基地址基础上找到各自的CR1-3 地址 */if (usartreg == 0x01) /* The IT is in CR1 register */{usartxbase += 0x0C;  }else if (usartreg == 0x02) /* The IT is in CR2 register */{usartxbase += 0x10;}else /* The IT is in CR3 register */{usartxbase += 0x14; }if (NewState != DISABLE){*(__IO uint32_t*)usartxbase  |= itmask;    //寄存器相应位置上的中断使能位置1}else{*(__IO uint32_t*)usartxbase &= ~itmask;    //中断使能位置0,其他位保持}
}

浅谈STM32 USART串口中断配置函数USART_ITConfig()的编程思路相关推荐

  1. stm32之配置串口中断服务函数

    在学习51单片机的时候,配置串口中断服务函数,只需要查看串口中断的中断号,然后在编写中断服务函数的时候,在函数名后面加上中断号.而在stm32中,中断的数量较多,对于中断的管理也会稍微复杂一点,而且中 ...

  2. stm32中断优先级_浅谈STM32串口USART1的使用

    浅谈STM32串口USART1的使用 通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范 ...

  3. 浅谈STM32的DMA模块的使用

    浅谈STM32的DMA模块的使用 转自:http://blog.ednchina.com/jack_chang/123085/message.aspx http://article.ednchina. ...

  4. STM32 USART串口DMA 接收和发送的源码详解!

    硬件平台:STM32F103ZET6: 开发环境:KEIL 4: 先说说应用通讯模式,串口终端的工作方式和迪文屏差不多,终端被动接受MCU发的指令,终端会偶尔主动发送一些数据给MCU(像迪文屏的触摸信 ...

  5. STM32—USART串口发送+接收

    STM32-USART串口发送+接收 本文来自于<STM32--江科大>的笔记整理. 文章目录 STM32-USART串口发送+接收 10.3 串口发送 串口调试助手 10.3.1 数据模 ...

  6. STM32之串口相关配置

    配置串口 串口简介 ​ 通用同步异步收发器(Universal Synchronous Asynchronous Receiver and Transmitter)是一个串行通信设备,可以灵活地与外部 ...

  7. STM32 USART—串口通信

    目录 一.串口通信协议物理层电平标准: 1.RS232标准: 2.USB转串口通讯(常用) 3.原生的串口到串口 二.串口通信协议软件层: 三.串口功能框图 1.引脚 2.数据寄存器USART_DR ...

  8. RTX5 | 消息队列04 - (实战技巧)串口中断回调函数ISR同步线程

    文章目录 一.前言 二.实验目的 三.API 3.2.osMessageQueueGet 四.代码 4.1.main.h 4.2.stm32f1xx.it.c 4.3.main.c 五.Event R ...

  9. 借WS2812 PWM DMA驱动调试浅谈STM32调试思路

    借WS2812 PWM DMA驱动调试浅谈STM32调试思路 ​ 接触STM32差不多有4年了,在学校参加比赛时也需要进行各种调试工作,团队的配合也需要个人具有领域内快速定位与解决BUG的能力,前些日 ...

最新文章

  1. flask 创建基本模板
  2. Windows下 maven3.0.4的安装步骤+maven配置本地仓库(转载)
  3. 在SQL Server中使用JOIN更新表?
  4. .net应用程序中添加chm帮助文档打开显示此程序无法显示网页问题
  5. 粒子网格算法 pm_使粒子网格与Blynk一起使用的2种最佳方法
  6. c++ map用法_5分钟掌握Python | Map、Reduce和Filter如何运用?
  7. 硬件加密芯片的使用及适配(CC020加密芯片)
  8. python学习笔记 程序执行过程 基本数据类型
  9. 中国“古诗词”数据库还有可用的API
  10. VS2008 安装顺序
  11. 深度学习——卷积神经网络(CNN)
  12. 网友眼中的杭州IT公司排名
  13. LaTeX 格式、字母、符号、公式 (总结)
  14. iphone icloud无法载入储存空间信息
  15. Fzu 2206 函数求解【规律】
  16. 此计算机上无法找到autocad2017,主编操作win7系统安装autocad2017提示“无法定位inf文件ACAD.inf”的具体步骤...
  17. navicat for mysql新建表_navicat怎么新建表
  18. 基于python3.x的爬取马蜂窝旅游的游记照片
  19. 8个适用于Android和iOS的文件管理APP
  20. 【L2-021 点赞狂魔】天梯赛L2系列详细解析

热门文章

  1. FPGA和CPLD芯片选型介绍(三)
  2. steam游戏的计算机要求,吃鸡最低配置(《绝地求生》Steam官方公布:吃鸡最低电脑配置要求)...
  3. 利用http://forshare.me/qq/访问陌生人的QQ空间_三木_新浪博客
  4. Android L添加kk版的OOBE开机向导
  5. java毕业设计考研资源共享系统mybatis+源码+调试部署+系统+数据库+lw
  6. 点击“换一换”切换商品,使用jquery slice()实现无缝连接切换
  7. linux常见版本介绍
  8. leetcode-位运算
  9. 华为软件测试通信基础,【华为软件测试工程师面试】面试软件测试和通信相关的题目。-看准网...
  10. js报错 Cannot both specify accessors and a value or writable attribute