ARM学习《七》——关于STM32中断设置之浅见

编程入门 行业动态 更新时间:2024-10-27 12:36:35

ARM学习《七》——关于STM32中断设置之<a href=https://www.elefans.com/category/jswz/34/1752208.html style=浅见"/>

ARM学习《七》——关于STM32中断设置之浅见

关于中断的设置,在STM32的PDF文档中是找不到关于NVIC相关寄存器的说明的,我不知道为什么,是让大家摸不着门道吗?还是故装高深?我非常的不理解。我最后是在《Cortex-M3权威指南》这本书上找到NVIC相关寄存器的,这本书很好,建议大家买来仔细阅读。

在STM32的PDF文档中关于中断的设置只给出了一个中断异常向量表,让人摸不着头脑,其实NVIC相关寄存器才是管理STM32所有中断开关和中断优先级的司令部,NVIC 共支持1 至240 个外部中断输入(通常外部中断写作IRQs)。具体的数值由芯片厂商在设计芯片时决定。此外,NVIC 还支持一个“永垂不朽”的不可屏蔽中断(NMI)输入。NMI 的实际功能亦由芯片制造商决定。

     先说为什么NVIC 共支持1 至240 个外部中断。Cortex‐M3 在内核水平上搭载了一个异常响应系统,这个系统规定为0到256个中断异常,支持为数众多的系统异常和外部中断。其中,编号为1-15 的对应系统异常,大于等于16 的则全是外部中断。除了个别异常

的优先级被定死外,其它异常的优先级都是可编程的。异常的优先级在这里我们先不说,对于所有的Cortex‐M3 内核处理器(包括STM32)256个异常中的0~15号异常都是一样的,内核规定好的,这就是Cortex‐M3的特点。0~15号异常如下:

 

    从16 开始的外部中断类型,是制造商做成芯片后,支持的中断源数,自然各种芯片的中断源数目常常不到240 个,并且优先级的位数也由芯片厂商最终决定。如表:

这240个中断的使能与除能分别使用各自的寄存器来控制——这与传统的,使用单一比特的两个状态来表达使能与除能是不同的。CM3 中可以有240 对使能位/除能位,每个中断拥有一对。这240 个对子分布在8 对32 位寄存器中(最后一对没有用完)。欲使能一个中断,你需要写1 到对应SETENA 的位中;欲除能一个中断,你需要写1 到对应的CLRENA 位中;如果往它们中写0,不会有任何效果。通过这种方式,使能/除能中断时只需把“当事位”写成1,其它的位可以全部为零。再也不用像以前那样,害怕有些位被写入0 而破坏其对应的中断设置(写0 没有效果),从而实现每个中断都可以自顾地设置,而互不侵犯——只需单一的写指令,不再需要读‐改‐写。

如上所述,SETENA 位和CLRENA 位可以有240 对,对应的32 位寄存器可以有8 对,因此使用数字后缀来区分这些寄存器,如SETENA0, SETENA1…SETENA7,如表8.1 所示。但是在特定的芯片中,只有该芯片实现的中断,其对应的位才有意义。因此,如果你使用的芯片支持32 个中断,则只有SETENA0/CLRENA0 才需要使用。SETENA/CLRENA 可以按字/半字/字节的方式来访问。又因为前16 个异常已经分配给系统异常,故而中断0 的异常号是16。

 

    现在我们再回到STM32的中断中来,STM32支持43个外部中断,既IRQ0~IRQ42(窗口看门狗中断~USB 从挂起唤醒中断),我们拿串口中断来说,如果要使能串口中断,就要找到串口终端号,查看STM32控制寄存器资料手册中的中断向量表得知串口1(UART1)的终端号为37,那么我们见寄存器SETENA1中的位5置一就可使能UART1中断。就这么简单

   下面我们将上篇中的串口调试程序以串口中断的形式实现如下:

//头文件中增加SETENA1寄存器

/

#define SETENA1    (*((volatile unsigned long *)0xE000E104))

/

void stm32_UsartSetup ()  

{

 RCC_APB2ENR|=0x00004000; // enable clock for USART1

 RCC_APB2ENR|=0x00000001; //复用功能IO时钟使能

 RCC_APB2ENR|=0x00000004; //端口A时钟使能

 GPIO_PORTA_CRH&=~(0x00000FF0); // Clear PA9, PA10

 GPIO_PORTA_CRH|=0x000000B0; // USART1 Tx (PA9)  alternate output push-pull

 GPIO_PORTA_CRH|=0x00000400; // USART1 Rx (PA10) input floating

 

 

 USART1_BRR=0x00000823;  波特率9600/20M

 USART1_CR1&=0xFFFFEFFF; // set Data bits

 USART1_CR2&=0xFFFFCFFF; // set Stop bits

 USART1_CR1&=0xFFFFFBFF; //  // set Parity

 

 USART1_CR1|=(0x00000004|0x00000008);  // RX, TX enable

 USART1_CR1|=0x00002000; // USART enable

 

 USART1_CR1|=0X00000020;   //允许接收中断

 SETENA1=0x00000020;       //使能UART1中断

}

 

void USART1_IRQHandler(void) //串口中断处理程序

{  

   unsigned long flag=0;

   while(USART1_SR&0x00000020)

   {

     USART1_CR1&=0xffffffdf;

     flag=USART1_DR&0xff;

    USART1_DR=flag&0xff;

 while((USART1_SR)&0x80==0); //等待发送完毕

 while((USART1_SR)&0x40==0);

  flag=USART1_SR;

  

  USART1_CR1|=0x00000020;

}

int main()

 {

  SystemInit0(); //时钟初始化

stm32_UsartSetup (); //串口初始化

 while(1)

 {

 }

}

   就这么简单!当然,库函数考虑的很全面,有好多地方是值得我们学习的,但先学会,弄懂了它的基本功能功能再提高也不迟……

 

更多请见.html

更多推荐

ARM学习《七》——关于STM32中断设置之浅见

本文发布于:2024-03-04 09:54:59,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1708952.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:浅见   置之   ARM

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!