STM32F10X系列GPIO外部中断

来源:互联网 发布:idea怎么关联源码 编辑:程序博客网 时间:2024/06/05 09:30


先从最简单的问题开始,用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);
}

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

            



2,配置EXTI寄存器及(函数),设置中断线,中断方式,等;

            

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文件里:

            

void EXTI0_IRQHandler(void){  if(EXTI_GetITStatus(EXTI_Line0)==SET)  {   EXTI_ClearITPendingBit(EXTI_Line0);if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET){   GPIO_SetBits(GPIOA,GPIO_Pin_0);}else{GPIO_ResetBits(GPIOA,GPIO_Pin_0);}  }}

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


说几点容易忽略的地方:

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

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

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

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

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

        

    



下面是直接操作寄存器的方法:

1.GPIO初始化:这里只要注意GPIOB.0设置成上拉输入(不光要设置GPIOB->CRL=0X08,还要设置GPIOB->ODR=0X01,为了和下拉区分)

  

void GPIO_Config(){GPIOA->CRL=0X03;GPIOA->ODR=0X01;GPIOB->CRL=0X08;GPIOB->ODR=0X01;}


2. NVIC 初始化:

    直接上代码:

      

void NVIC_Configuration()        {u32 temp;temp=SCB->AIRCR;temp &=0x0000f8ff;temp |=0x05fa0000;temp |=0x0700;SCB->AIRCR =temp;NVIC->ISER[0] =1<<6;NVIC->IP[1]=0;}

3. EXTI初始化

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

        

void EXTI_Configuration(){AFIO->EXTICR[0]=0X0001;EXTI->IMR =0X01;EXTI->RTSR =0X01;}


然后是中断服务程序:

   

void EXTI0_IRQHandler(void){  if(EXTI_GetITStatus(EXTI_Line0)==SET)  {   EXTI->PR =0X01;if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_0)==Bit_RESET){   GPIO_SetBits(GPIOA,GPIO_Pin_0);}else{GPIO_ResetBits(GPIOA,GPIO_Pin_0);}  }}


下面是整个用函数代码:

#include"stm32f10x.h"void GPIO_Config();void NVIC_Configuration();void EXTI_Configuration();void SysclkConfiguration();int main(){SysclkConfiguration();GPIO_Config();EXTI_Configuration();NVIC_Configuration();while(1); return 0;}void SysclkConfiguration()        {       RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);if(RCC_WaitForHSEStartUp()==SUCCESS){RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource()!=0X08);          RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);     }} void GPIO_Config(){GPIO_InitTypeDef GPIO_InitStructure;   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_0);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;GPIO_Init(GPIOB,&GPIO_InitStructure);}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); }

下面是用寄存器代码:

      

#include"stm32f10x.h"void GPIO_Config();void NVIC_Configuration();void EXTI_Configuration();void SysclkConfiguration();int main(){SysclkConfiguration();GPIO_Config();EXTI_Configuration();NVIC_Configuration();while(1); return 0;}void SysclkConfiguration()        {       RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);if(RCC_WaitForHSEStartUp()==SUCCESS){RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);RCC_PLLCmd(ENABLE);while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);while(RCC_GetSYSCLKSource()!=0X08);          RCC_HCLKConfig(RCC_SYSCLK_Div1);RCC_PCLK1Config(RCC_HCLK_Div2);RCC_PCLK2Config(RCC_HCLK_Div1);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_AFIO,ENABLE);     }} void GPIO_Config(){GPIOA->CRL=0X03;GPIOA->ODR=0X01;GPIOB->CRL=0X08;GPIOB->ODR=0X01;}void NVIC_Configuration()        {u32 temp;temp=SCB->AIRCR;temp &=0x0000f8ff;temp |=0x05fa0000;temp |=0x0700;SCB->AIRCR =temp;NVIC->ISER[0] =1<<6;NVIC->IP[1]=0;}void EXTI_Configuration(){AFIO->EXTICR[0]=0X0001;EXTI->IMR =0X01;EXTI->RTSR =0X01;EXTI->PR =0X01;}

然后是一些用到的文章:

  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

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


0 0
原创粉丝点击