NVIC中断优先级管理+串口通信基本原理+串口通信

发布者:SparkStar22最新更新时间:2018-04-17 来源: eefocus关键字:NVIC  中断优先级  串口通信 手机看文章 扫描二维码
随时随地手机看文章

今天主要总结和复习三个知识点,NVIC中断优先级管理、串口通信、及串口通信的简单配置实例:

第一部分:

NVIC中断优先级管理:

首先是中断分组,我们知道所用的CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。然而STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。而我所用的STM32F103系列上面,又只有60个可屏蔽中断(在107系列才有68个),而STM系列把中断分为5个组,如下图一所示

图一

这么多大概60个中断如何管理,这是我一开始想到的问题,当然是用寄存器进行管理,有七组寄存器对所有的中断进行管理,中断寄存器分别如下,引用MDK对寄存器组的分类:

typedef struct
{
  __IO uint32_t ISER[8];                   //中断使能寄存器组:设置为:8个32位寄存器来控制256个中断,由于我用的只有60个故只需设置ISER[0]-ISER[2]即可
       uint32_t RESERVED0[24];                                   
  __IO uint32_t ICER[8];                      //中断除能寄存器组:设置和中断使能一样
       uint32_t RSERVED1[24];                                    
  __IO uint32_t ISPR[8];                      //中断挂起寄存器组:设置和中断使能一样,通过置一把正在执行的中断挂起从而执行同级别或更高级别的中断,写0无效
       uint32_t RESERVED2[24];                                   
  __IO uint32_t ICPR[8];                      //中断解挂控制寄存器组:设置和中断使能一样作用和挂起寄存器组相反
       uint32_t RESERVED3[24];                                   
  __IO uint32_t IABR[8];                   //   中断激活标志位寄存器组:这是一个只读寄存器,如果置一可以知道该位所对应的正在运行的中断,运行完毕由硬件自动清零
       uint32_t RESERVED4[56];                                   
  __IO uint8_t  IP[240];                   //  中断优先级控制寄存器组:这是非常重要的一个寄存器,总共有240个8位的寄存器组成,每8位代表一个中断,而每八位只用了其高八位,我所用的103系列只用了0-//67即可,详细的会在下面给出
       uint32_t RESERVED5[644];                                  
  __O  uint32_t STIR;                      // 软件触发中断寄存器组
}  NVIC_Type;      

中断优先级控制寄存器组,说这个之前得明白一个概念,优先级概念,STM系列的中断优先级分为两级,抢占优先级和响应优先级。而又得知道两者的区别,其中区别如下:

1、高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。

2、抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

3、抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。

4、如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;

抢占优先级和响应优先级中,数字越小说明级别越大。举个例子,假定设置中断优先级组为2,然后设置中断1(RTC中断)的抢占优先级为2,响应优先级为1。  中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断4(外部中断1)的抢占优先级为2,响应优先级为0。则中断优先级为中断4>中断1>中断6.

在详细弄懂了上述所有知识后,就可以设置自己我们自己的中断,具体步骤如下:

①系统运行后先设置中断优先级分组。调用函数:

voidNVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);/

 整个系统执行过程中,只设置一次中断分组。

②针对每个中断,设置对应的抢占优先级和响应优先级:

voidNVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);

③ 如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

第二部分:串口通信基本原理

这个复习得从通信的背景开始阐述,处理器与外部的通信分为两种方式并行和串行方式:并行的优点是速度快缺点为占用IO口较多,串行则速度慢优点为占用的IO口较少。串行通信按照传输方向又有三种方式,单工,半双工,全双工如图二所示:


图二

看完图应该就很清晰了,再解释一下

1、单工:数据传输只支持数据在一个方向上传输

2、半双工:允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信;

3、全双工:允许数据同时在两个方向上传输,因此,全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。 

按照是否带时钟分为同步和异步,其中STM32的串口通信接口,UART:通用异步收发器,USART:通用同步异步收发器

我所用的板子中的大概电路如图三:


图三

STM32串口异步通信主要的参数定义为:起始位,数据位,硬件流位,停止位,波特率设置。举个例子如图四:


图四

第三部分:

下面进行第三部分,实例演示,在这之前得明白所用的三个寄存器

1、USART_SR状态寄存器

2、USART_DR数据寄存器

3、USART_BRR波特率寄存器

而我们在运用库函数编写串口代码过程一般会运用到下面的几个库函数:

voidUSART_Init();//串口初始化:波特率,数据字长,奇偶校验,硬件流控以及收发使能

voidUSART_Cmd();//使能串口

voidUSART_ITConfig();//使能相关中断

voidUSART_SendData();//发送数据到串口,DR

uint16_tUSART_ReceiveData();//接受数据,从DR读取接受到的数据

FlagStatusUSART_GetFlagStatus();//获取状态标志位

voidUSART_ClearFlag();//清除状态标志位

ITStatusUSART_GetITStatus();//获取中断状态标志位

voidUSART_ClearITPendingBit();//清除中断状态标志位

其中提出一点波特率的计算方式如图5所示:


图五


最后就可以进行实例操作:总结步骤如下:

①串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();

②串口复位:USART_DeInit(); 这一步不是必须的

③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF_PP

④串口参数初始化:USART_Init();

⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)

      NVIC_Init();

      USART_ITConfig();

⑥使能串口:USART_Cmd();

⑦编写中断处理函数:USARTx_IRQHandler();

⑧串口数据收发:

void USART_SendData();//发送数据到串口,DR

uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据

⑨串口传输状态获取:

FlagStatusUSART_GetFlagStatus(USART_TypeDef* USARTx,uint16_t USART_FLAG);

void USART_ClearITPendingBit(USART_TypeDef* USARTx, uint16_t USART_IT);

编写得主函数代码如下:

#include "stm32f10x.h"
//串口通信实验1
void my_usart_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructA;
USART_InitTypeDef USART_InitStructA;
NVIC_InitTypeDef NVIC_InitStructA;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//enable GPIOA和USART1 的时钟
//初始化GPIOA,查表可知串口1发送模式下是全双工,GPIO口设置为推挽复用模式
GPIO_InitStructA.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStructA.GPIO_Pin=GPIO_Pin_9;
GPIO_InitStructA.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructA); 
//初始化GPIOA,查表可知串口1接受模式下是全双工,GPIO口设置为浮空输入模式
GPIO_InitStructA.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStructA.GPIO_Pin=GPIO_Pin_10;
GPIO_InitStructA.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructA); 
//初始化串口参数
USART_InitStructA.USART_BaudRate=115200;
USART_InitStructA.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_InitStructA.USART_Mode=USART_Mode_Tx|USART_Mode_Rx;
USART_InitStructA.USART_Parity=USART_Parity_No;
USART_InitStructA.USART_StopBits=USART_StopBits_1;
USART_InitStructA.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_InitStructA);

//开启接受中断且初始化NVIC
NVIC_InitStructA.NVIC_IRQChannel=USART1_IRQn;
NVIC_InitStructA.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructA.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStructA.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_InitStructA);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//设置串口状态
USART_Cmd(USART1, ENABLE);                    //使能串口1 
}
void USART1_IRQHandler(void)
{
u8 res;
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))//由于有可能开启了很多中断故需要判断是否是我们所要的中断函数
{
res=USART_ReceiveData(USART1);//接受来自串口一的数据
USART_SendData(USART1,res);//
}
}
 int main(void)
 {
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
my_usart_Init();
while(1);
//运行以后就一直在主函数等待,当电脑给单片机发送数据时就跳到中断
 
 }
由于我没有JLINK在线调试,故用USB直接下载到单片机进行调试,最后用串口助手可以得到所设想达到的输出:结果如图六


图六


其中白色的发送是先经过PC先发送给单片机,如然后单片机又发送给PC由串口助手在打印得出;


关键字:NVIC  中断优先级  串口通信 引用地址:NVIC中断优先级管理+串口通信基本原理+串口通信

上一篇:基于STM32的OLED与TFTLCD详解1(IC驱动及FSMC初探)
下一篇:STM32中SYSTICK定时器、端口复用和重映射

推荐阅读最新更新时间:2024-03-16 16:00

基于PIC18F258的全自动热敏电阻测试仪
   引言   热敏电阻作为一种常用的温度传感器广泛应用于消费电子、工业控制、通信、航空等领域。在热敏电阻的生产过程中,电阻的性能测试和标定环节非常关键。本文设计了一种能够实现对热敏电阻性能进行自动测试和分析的仪器——热敏电阻测试仪,它能够同时对十五个热敏电阻进行性能测试,在测试过程中,用户可以通过上位机界面来控制测试中的温度范围及温度间隔。得到测量数据后,用户可以通过Excel表格程序绘制各个电阻的热温曲线,从而可以很容易识别出次品电阻。该仪器缩短了对热敏电阻进行检测的平均时间,提高了厂家的生产效率。    测量的基本原理   对热敏电阻进行测试需要将其放入恒温箱中进行,本测试仪也需要对恒温箱中的温度进行测定,才能根据不同
[工业控制]
基于PIC18F258的全自动热敏电阻测试仪
MSP430的中断优先级及中断嵌套
MSP430的中断优先级、打开关闭、中断嵌套 优先级顺序从高到低为: PORT2_VECTOR (1 * 2u) /* 0xFFE2 Port 2 */ PORT1_VECTOR (4 * 2u) /* 0xFFE8 Port 1 */ TIMERA1_VECTOR (5 * 2u) /* 0xFFEA Timer A CC1-2, TA */ TIMERA0_VECTOR (6 * 2u) /* 0xFFEC Timer A CC0 */ ADC_VECTOR (7 * 2u) /* 0xFFEE ADC */ USART0TX_VECTOR (8 * 2u) /* 0xFFF0 USART 0 Transmit */ USA
[单片机]
STM32中断优先级和开关总中断(很老很经典)
一、中断优先级: STM32(Cortex-M3)中的优先级概念 STM32(Cortex-M3)中有两个优先级的概念——抢占式优先级和响应优先级,有人把响应优先级称作'亚优先级'或'副优先级',每个中断源都需要被指定这两种优先级。 具有高抢占式优先级的中断可以在具有低抢占式优先级的中断处理过程中被响应,即中断嵌套,或者说高抢占式优先级的中断可以嵌套低抢占式优先级的中断。 当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决
[单片机]
STM32<font color='red'>中断优先级</font>和开关总中断(很老很经典)
嵌入式学习笔记11——51单片机之中断串口通信
1. 计算机通信指计算机与外设或计算机与计算机之间的信息交换,分为两大类:并行通信(控制简单)和串行通信(从低到高,一位一位的传送,长距离传输时成本低)。 2. 异步通信 异步通信是以字符(构成的帧)为单位进行传输,字符与字符之间的间隙(时间间隔)是任意的,但每个字符中的各位是以固定的时间传送的。 异步通信的数据格式: 格式中的校验位通常有3种方式获得:(1)奇偶校验:奇校验 数据中的 1 的个数与校验位 1 的个数之和应为奇数;偶校验 数据中的 1 的个数与校验位 1 的个数之和应为偶数。(2)代码和校验:发送方将所发数据块求和(或各字节异或),产生一个字节的校验字符(校验和)附加到数据块
[单片机]
嵌入式学习笔记11——51单片机之中断<font color='red'>串口通信</font>
STM32F1串口通信总结
1、处理器与外部设备通信的两种方式: 1.并行通信-传输原理:数据各个位同时传输。优点:速度快。缺点:占用引脚资源多。 2.串行通信-传输原理:数据按位顺序传输。优点:占用引脚资源少。缺点:速度相对较慢。 2、串行通信按照数据传送方向,分为: 1.单工:数据传输只支持数据在一个方向上传输 。 2.半双工:允许数据在两个方向上传输,但是在某一时刻,只允许数据在一个方向上传输,它实际上是一种切换方向的单工通信; 3.全双工:允许数据同时在两个方向上传输,因此全双工通信是两个单工通信方式的结合,它要求发送设备和接收设备都有独立的接收和发送能力。 3、串行通信的通信方式 : 1.同步通信:带时钟同步信号传输
[单片机]
STM32F1<font color='red'>串口通信</font>总结
STM32F429 串口通信_初始化
一、相关原理: 1. 初始化HAL库; 2. 初始化stm32系统时钟,设置时钟,包括PLL时钟、以及外设时钟APB1,APB2....... 3. 初始化时延系统; 4. 初始化串口,包括串口、串口使用的GPIO口、使能串口本身的中断、使能串口在NVIC上对应的中断; 二、 代码实现: 1. 初始化HAL库 HAL_StatusTypeDef HAL_Init() { HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2); HAL_InitTick(TICK_INT_PRIORITY); HAL_MspInit(); } 2. 时钟初始化 Stm32_Clock_In
[单片机]
PIC单片机-RS232串口通信
编写程序实现以下功能。在计算机上使用串口大师向开发板发每次发送1个字符。开发板每接收到一个数据,则交换该数据的高低4位,再发送回计算机。 端口初始化时使能发送与接收,使用扫描方式接收数据,接收到数据后立即交换高低四位并发送,交换高低四位方式如下: i = ((RCREG & 0xff) 4) | (RCREG 4) 完整程序: /******************************************************************************* * 标 题: 异步串口通讯 * 功能描述: 在计算机上使用串口大师向开发板发每次发送1个字符。 * 开发板每接收到一个数据,则交
[单片机]
嵌入式系统中串口通信帧的同步方法
引 言 串口通信是日前单片机和DSP等嵌入式系统之间,以及嵌入式系统与PC机或无线模块之间的一种非常重要且普遍使用的通信方式。在嵌入式系统的硬件结构中,通常只有一个8位或16位的CPU,不仅要完成主流程的工作,同时还要处理随时发生的各种中断,因而嵌入式系统中的串口通信程序设计与PC机有很大的不同。若嵌入式系统中.中断服务子程序在系统运行过程中占用了较多的时间,就有可能在中断眼务子程序正运行时,又产生一个同类型或其他类型的中断,从而造成主程序得不到执行或后续中断数据丢失。所以,嵌入式系统中的串口通信虽然看似简单,但其中仍有许多问题值得研究,例如串口通信过程中的帧同步问题。本文针对该问题给出了逐次比较、基于FIFO队列和基于状态机的
[工业控制]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved