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

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

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

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

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

 

转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见

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

转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见
转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见

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

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

 

转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见转】ARM学习《七》鈥斺敼赜赟TM32中断设置之浅见

    现在我们再回到STM32的中断中来,STM32支持43个外部中断,既IRQ0~IRQ42窗口看门狗中断~USB 从挂起唤醒中断),我们拿串口中断来说,如果要使能串口中断,就要找到串口终端号,查看STM32控制寄存器资料手册中的中断向量表得知串口1UART1)的终端号为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)

 {

 }

}

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

 

更多请见http://blog.sina.com.cn/s/blog_8774aec90100yoma.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值