×
单片机 > 单片机程序设计 > 详情

STM32F10X系列GPIO外部中断

发布时间:2020-08-31 发布时间:
|

先从最简单的问题开始,用STM32外部中断的方法实现PB.0按键控制PA.0LED灯:

先总的说下实现中断的步骤:

1,配置NVIC寄存器(函数),设置中断为第几组,占先优先级和次优先级;

      函数方法:

           void NVIC_Configuration()      
  {
        NVIC_InitTypeDef NVIC_InitStruct;
      NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  
      NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;            
      NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;   
      NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;           
      NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;          
      NVIC_Init(&NVIC_InitStruct);
}

      以上为配置优先级的一般步骤:设置优先级分组,设置中断通道,分别设置先占优先级,次占优先级,使能等;

             

  • void EXTI_Configuration()  

  • {  

  •             EXTI_InitTypeDef EXTI_InitStructure;  

  •                 EXTI_ClearITPendingBit(EXTI_Line0);  

  •             GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);  

  •         EXTI_InitStructure.EXTI_Line = EXTI_Line0;  

  •         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  

  •         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;   

  •         EXTI_InitStructure.EXTI_LineCmd = ENABLE;   

  •         EXTI_Init(&EXTI_InitStructure);   

  • }  

  •    和配置NVIC一样,这也是EXTI配置的一般步骤:清除相应中断线标志位(这个很重要,刚开始一直没找到这个问题),联结端口与中断线(也可以在GPIO初始化时配置),选择中断线,设置中断模式,中断方式,使能等;


    3,写中断服务函数

            中断服务程序一般写在STM32F10X_it.c文件里:


    1. void EXTI0_IRQHandler(void)  

    2. {  

    3.   if(EXTI_GetITStatus(EXTI_Line0)==SET)  

    4.   {  

    5.     EXTI_ClearITPendingBit(EXTI_Line0);  

    6.         if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET)  

    7.         {  

    8.            GPIO_SetBits(GPIOA,GPIO_Pin_0);    

    9.         }  

    10.         else  

    11.         {  

    12.             GPIO_ResetBits(GPIOA,GPIO_Pin_0);  

    13.         }  

    14.   }   

    15. }  

         其中最重要的一点:需要注意进入服务程序后清除中断标志位;


    说几点容易忽略的地方:

         1.中断服务程序一定要清除中断标志位;

         2.联结相应端口与中断线;

         3.按键端口设置成上拉输入;

         4.在配置EXTI时清除中断标志位;

    按键部分的短路自己连的:

             

  • void GPIO_Config()  

  • {  

  •     GPIOA->CRL=0X03;  

  •     GPIOA->ODR=0X01;  

  •     GPIOB->CRL=0X08;  

  •     GPIOB->ODR=0X01;  

  • }  


  • 2. NVIC 初始化:

        直接上代码:


    1. void NVIC_Configuration()        

    2.   {  

    3.         u32 temp;  

    4.         temp=SCB->AIRCR;  

    5.         temp &=0x0000f8ff;  

    6.         temp |=0x05fa0000;  

    7.         temp |=0x0700;  

    8.         SCB->AIRCR =temp;  

    9.         NVIC->ISER[0] =1<<6;  

    10.         NVIC->IP[1]=0;  

    11. }  

    3. EXTI初始化

         和用函数方法差不多,设置几个寄存器;有点不明白的是这里好像可以不用清除标志位;


    1. void EXTI_Configuration()  

    2. {  

    3.     AFIO->EXTICR[0]=0X0001;  

    4.     EXTI->IMR =0X01;  

    5.     EXTI->RTSR =0X01;  

    6. }  


    然后是中断服务程序:

       

    1. void EXTI0_IRQHandler(void)  

    2. {  

    3.   if(EXTI_GetITStatus(EXTI_Line0)==SET)  

    4.   {  

    5.   

    6.    EXTI->PR =0X01;  

    7.         if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET)  

    8.         {  

    9.            GPIO_SetBits(GPIOA,GPIO_Pin_0);    

    10.         }  

    11.         else  

    12.         {  

    13.             GPIO_ResetBits(GPIOA,GPIO_Pin_0);  

    14.         }  

    15.   }   

    16. }  



    下面是整个用函数代码:


    1. #include"stm32f10x.h"  

    2. void GPIO_Config();  

    3. void NVIC_Configuration();  

    4. void EXTI_Configuration();  

    5. void SysclkConfiguration();  

    6. int main()  

    7. {  

    8.     SysclkConfiguration();  

    9.     GPIO_Config();  

    10.     EXTI_Configuration();  

    11.     NVIC_Configuration();  

    12.     while(1);  

    13.      return 0;  

    14. }  

    15.   

    16. void SysclkConfiguration()          

    17.         {  

    18.        RCC_DeInit();  

    19.             RCC_HSEConfig(RCC_HSE_ON);  

    20.             if(RCC_WaitForHSEStartUp()==SUCCESS)  

    21.             {  

    22.             RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);  

    23.             RCC_PLLCmd(ENABLE);  

    24.                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);  

    25.             RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  

    26.             while(RCC_GetSYSCLKSource()!=0X08);  

    27.           RCC_HCLKConfig(RCC_SYSCLK_Div1);  

    28.                 RCC_PCLK1Config(RCC_HCLK_Div2);  

    29.                 RCC_PCLK2Config(RCC_HCLK_Div1);  

    30.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);       

    31.             }  

    32.         }  

    33.   

    34.  void GPIO_Config()  

    35. {  

    36.     GPIO_InitTypeDef GPIO_InitStructure;   

    37.   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  

    38.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;  

    39.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  

    40.     GPIO_Init(GPIOA, &GPIO_InitStructure);   

    41.     GPIO_ResetBits(GPIOA,GPIO_Pin_0);  

    42.       

    43.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;  

    44.     GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;  

    45.     GPIO_Init(GPIOB,&GPIO_InitStructure);  

    46. }  

    47.   

    48. void NVIC_Configuration()        

    49.   {  

    50.         NVIC_InitTypeDef NVIC_InitStruct;  

    51.             NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);  

    52.             NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;  

    53.             NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;  

    54.             NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;  

    55.             NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;      

    56.             NVIC_Init(&NVIC_InitStruct);  

    57. }  

    58. void EXTI_Configuration()  

    59. {  

    60.     EXTI_InitTypeDef EXTI_InitStructure;  

    61.     EXTI_ClearITPendingBit(EXTI_Line0);  

    62.         GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource0);  

    63.         EXTI_InitStructure.EXTI_Line = EXTI_Line0;  

    64.         EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  

    65.         EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;   

    66.         EXTI_InitStructure.EXTI_LineCmd = ENABLE;   

    67.         EXTI_Init(&EXTI_InitStructure);   

    68.       

    69. }  

    下面是用寄存器代码:

          

    1. #include"stm32f10x.h"  

    2. void GPIO_Config();  

    3. void NVIC_Configuration();  

    4. void EXTI_Configuration();  

    5. void SysclkConfiguration();  

    6. int main()  

    7. {  

    8.     SysclkConfiguration();  

    9.     GPIO_Config();  

    10.     EXTI_Configuration();  

    11.     NVIC_Configuration();  

    12.     while(1);  

    13.      return 0;  

    14. }  

    15.   

    16. void SysclkConfiguration()          

    17.         {  

    18.        RCC_DeInit();  

    19.             RCC_HSEConfig(RCC_HSE_ON);  

    20.             if(RCC_WaitForHSEStartUp()==SUCCESS)  

    21.             {  

    22.             RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);  

    23.             RCC_PLLCmd(ENABLE);  

    24.                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);  

    25.             RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);  

    26.             while(RCC_GetSYSCLKSource()!=0X08);  

    27.           RCC_HCLKConfig(RCC_SYSCLK_Div1);  

    28.                 RCC_PCLK1Config(RCC_HCLK_Div2);  

    29.                 RCC_PCLK2Config(RCC_HCLK_Div1);  

    30.                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);       

    31.             }  

    32.         }  

    33.   

    34.  void GPIO_Config()  

    35. {  

    36.     GPIOA->CRL=0X03;  

    37.     GPIOA->ODR=0X01;  

    38.     GPIOB->CRL=0X08;  

    39.     GPIOB->ODR=0X01;  

    40. }  

    41.   

    42. void NVIC_Configuration()        

    43.   {  

    44.         u32 temp;  

    45.         temp=SCB->AIRCR;  

    46.         temp &=0x0000f8ff;  

    47.         temp |=0x05fa0000;  

    48.         temp |=0x0700;  

    49.         SCB->AIRCR =temp;  

    50.         NVIC->ISER[0] =1<<6;  

    51.         NVIC->IP[1]=0;  

    52. }  

    53. void EXTI_Configuration()  

    54. {  

    55.     AFIO->EXTICR[0]=0X0001;  

    56.     EXTI->IMR =0X01;  

    57.     EXTI->RTSR =0X01;  

    58.     EXTI->PR =0X01;  

    59. }  

    然后是一些用到的文章:

      http://www.st.com/content/ccc/resource/technical/document/programming_manual/6c/3a/cb/e7/e4/ea/44/9b/DM00046982.pdf/files/DM00046982.pdf/jcr:content/translations/en.DM00046982.pdf

    http://www.ichanging.org/stm32_NVIC.html


    最后说下,第一次写笔记,感谢大家阅读,如果有什么不对的地方,欢迎大家留言指正 !



    『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

    热门文章 更多
    浅谈AVR中定时器几种工作模式