STM32_外部中断(寄存器版)_笔记

一、与STM32中断有关的寄存器:(通过结构体设置)

          1 、ISER[2]:中断使能寄存器组,CM3内核含有256个中断,由8个32位寄存器控制,STM32_F103可屏蔽中断只有60个,只用了ISER[0];ISER[1];

                                                                     ISER[0]的bit0~bit31对应中断0~31,ISER[1]的bit0~bit27对应中断32~59.                     写1有效

          2、ICER[2]:中断除能寄存器组,STM32的清除中断并非向ISER写0来清除,而是设置一个ICER来清除。                          写1有效

          3、ISPR[2]:中断挂起寄存器组,将正在执行的中断挂起,而执行同级或更高级别的中断,写0无效。                                  写1有效

          4、ICPR[2]:中断解挂寄存器组,与ICER作用一样,置1解挂。                                                                                                    写1有效

          5、IABR[2]:激活标志位寄存器组,同ISER一样,如果为1,表示该位正在被执行,通过它可知道当前在执行的中断时哪一位,中断执行完,硬件请0。

          6、IP[240:中断优先级控制寄存器组,(十分重要!)240个8位寄存器组成,STM32只有60个,IP[59]~IP[0],每个中断的8位中,只占用高4位bit[7:4],这4位又分为抢占优先级和响应优先级,而这两个优先级各占几个字节,又要根据SCB->AIRCR寄存器的bit[10:8]位来定义:具体分配关系如下

                       STM32_外部中断(寄存器版)_笔记_第1张图片

     假如:设定中断优先级为组2:(那么他就有2位抢占优先级和2位响应优先级,即4个抢占,4个响应)设置第一个中断:2抢占 1响应。第二个中断:3抢占 1响应

第三个中断:2抢占 0响应 、那么这三个中断优先级为:3>1>2。有三个注意点如下

             1、如果两个中断抢占与响应一样,则那个先发生执行哪个 (数值越小,优先级越高)

             2、优先级高的抢占可以打断优先级低的,但是响应优先级高的响应不可以打断低的。(上例中1和3均可以打断2,但是1和3不可以相互打断)

             3、写代码的时候中断分组都要统一


二、外部I/O中断的一般步骤      

             1、初始化I/O输入。

             2、开启I/O口复用时钟,设置I/O口与中短线的映射关系

             3、初始化线上中断,设置触发条件  

             4、配置中断分组(NVIC),并使能中断

             5、编写中断服务函数

三、程序深解

         //设置NVIC分组

         //NVIC_Group:NVIC分组0~4  共5组

         void MY_NVIC_PriorityGroupConfig(u8 NVIC_Group) 
        { 
     u32 temp,temp1; 
     temp1=(~NVIC_Group)&0x07;     //取后三位 、(~NVIC_Group)取反的意思是中断分组设置表中组0对应111,取反后对应000,即0组
       temp1<<=8;                                     //STM32的中断分组由SCB->AIRCR寄存器的bit[10:8]位来定义  所以左移8位
     temp=SCB->AIRCR;                      //读取先前的设置
     temp&=0X0000F8FF;                    //清空先前分组
     temp|=0X05FA0000;                      //写入钥匙,修改SCB->AIRCR寄存器需要先写入0x05FA这个密匙后才可以修改
     temp|=temp1;  
     SCB->AIRCR=temp;                      //设置分组    
        }


         //设置NVIC
         //NVIC_PreemptionPriority               //抢占优先级
         //NVIC_SubPriority                             //响应优先级
         //NVIC_Channel                                 //中断编号(范围0~59)
         //NVIC_Group                                     //中断分组(0~4)
         //NVIC_SubPriorit和ÍNVIC_PreemptionPriority的原则是:数值越小越优先
       void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group) 
      { 
    u32 temp;
    MY_NVIC_PriorityGroupConfig(NVIC_Group);                             //设置分组
    temp=NVIC_PreemptionPriority<<(4-NVIC_Group); 
    temp|=NVIC_SubPriority&(0x0f>>NVIC_Group);                         
    temp&=0xf;                                                                                          // 取低4位                                                                                                                                        
    if(NVIC_Channel<32)NVIC->ISER[0]|=1<    else NVIC->ISER[1]|=1<<(NVIC_Channel-32);                                                           
    NVIC->IP[NVIC_Channel]|=temp<<4;                                  //将计算结果付给IP设置响应优先级和抢占优先级  
       }

 EXTI外部中断寄存器结构体

          //外部中断配置函数

          //只针对GPIOA~G

          //GPIOx:0~6代表A~G        BITx:使能位        TRIM:触发模式   1:下降沿  2:上升沿  3:任意

          //该函数一次只能配置一个I/O口,多个I/O口需要多次调用

          //自动开启对应中断,以及屏蔽线

         void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 TRIM) 
        {
    u8 EXTADDR;
    u8 EXTOFFSET;
    EXTADDR=BITx/4;                                                                       //得到中段寄存器组   EXTICR[0]代表了GPIOx.0~4位  所以对4取整得到寄存器组 
    EXTOFFSET=(BITx%4)*4;                                                          //假如BIT为3  则EXTADDR=0;EXTOFFSET=12  即EXTI[3]  下面会有介绍
    RCC->APB2ENR|=0x01;                                                            //使能I/O口复用时钟
    AFIO->EXTICR[EXTADDR]&=~(0x000F<    AFIO->EXTICR[EXTADDR]|=GPIOx<
    EXTI->IMR|=1<           //EXTI->EMR|=1<       if(TRIM&0x01)EXTI->FTSR|=1<    if(TRIM&0x02)EXTI->RTSR|=1<          } 

EXTICR[0]~EXTICR[3] 这4个寄存器组用来配置中短线到哪个I/O上,每个寄存器只用了低16位。

        EXTICR[0]的[3:0]位对应EXTI0,这4位从0000~0110对应GPIOA~G.0;EXTICR[0]的[4:7]位对应EXTI1,这4位从0000~0110对应GPIOA~G.1

                       EXTICR[0]的[8:11]位对应EXTI2,这4位从0000~0110对应GPIOA~G.2;EXTICR[0]的[12:15]位对应EXTI3,这4位从0000~0110对应GPIOA~G.3

        EXTICR[1]的[3:0]位对应EXTI4,这4位从0000~0110对应GPIOA~G.4;EXTICR[1]的[4:7]位对应EXTI5,这4位从0000~0110对应GPIOA~G.5

                       EXTICR[1]的[8:11]位对应EXTI6,这4位从0000~0110对应GPIOA~G.6;EXTICR[1]的[12:15]位对应EXTI7,这4位从0000~0110对应GPIOA~G.7

        EXTICR[2]的[3:0]位对应EXTI8,这4位从0000~0110对应GPIOA~G.8;EXTICR[2]的[4:7]位对应EXTI9,这4位从0000~0110对应GPIOA~G.9

                       EXTICR[2]的[8:11]位对应EXTI10,这4位从0000~0110对应GPIOA~G.10;EXTICR[2]的[12:15]位对应EXTI11,这4位从0000~0110对应GPIOA~G.11

        EXTICR[3]的[3:0]位对应EXTI12,这4位从0000~0110对应GPIOA~G.12;EXTICR[3]的[4:7]位对应EXTI13,这4位从0000~0110对应GPIOA~G.13

                       EXTICR[3]的[8:11]位对应EXTI14,这4位从0000~0110对应GPIOA~G.14;EXTICR[3]的[12:15]位对应EXTI15,这4位从0000~0110对应GPIOA~G.15


下面看一下STM32处理中断的映射图

     STM32的每个I/O口均可作为外部中断输入,支持19个外部中断/事件请求。每个中断有状态位,每个事件/中断都有独立的触发和评比设置。STM32F103有19个外部中断:

     分别为: 线0~15:对应外部I/O口的输入中断

                      线16     : 连接到PVD输出。(电源电压过低,产生中断)

                      线17     :连接RTC闹钟事件。

                      线18     :连接到USB唤醒事件。

     STM32中短线有16个,但是I/O口却不止16个,它把GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G)分别对应中断线0~15,这样就可以解决问题了,比如线0,可以映射DA到GPIOA.0,

GPIOB.0,~,GPIOG.0。

                           

接下来就是应用 

     //外部中断0服务程序   

     void EXTI0_IRQHandler(void)
     {
         delay_ms(10);    
if(KEY3==1)      
{
             LED0=0;
         }
EXTI->PR=1<<0;                 //PR:挂起寄存器。当外部中断发生了选择的边沿事件,该寄存器的对应为会被置1。0表示对应线上没有触发请求,写1来清除中断请求
     }

    //外部中断2服务程序

     void EXTI2_IRQHandler(void)
     {
   delay_ms(10);     
   if(KEY2==0)    
   {
LED0=!LED0;
   }  
   EXTI->PR=1<<2;   
      }

      void EXTIX_Init(void)
      {
         KEY_Init();

 Ex_NVIC_Config(GPIO_A,0,RTIR);   
 Ex_NVIC_Config(GPIO_E,2,FTIR);   


 MY_NVIC_Init(2,3,EXTI0_IRQn,2);   
 MY_NVIC_Init(2,2,EXTI2_IRQn,2);  
        }

以上为STM32_外部中断(寄存器版)_笔记   初学者,有不完善的,待修改

你可能感兴趣的:(STM32程序)