STM32F10X系列GPIO外部中断
2017-02-20 17:41
399 查看
先从最简单的问题开始,用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寄存器及(函数),设置中断线,中断方式,等;
3,写中断服务函数
中断服务程序一般写在STM32F10X_it.c文件里:
其中最重要的一点:需要注意进入服务程序后清除中断标志位;
说几点容易忽略的地方:
1.中断服务程序一定要清除中断标志位;
2.联结相应端口与中断线;
3.按键端口设置成上拉输入;
4.在配置EXTI时清除中断标志位;
按键部分的短路自己连的:
下面是直接操作寄存器的方法:
1.GPIO初始化:这里只要注意GPIOB.0设置成上拉输入(不光要设置GPIOB->CRL=0X08,还要设置GPIOB->ODR=0X01,为了和下拉区分)
2. NVIC 初始化:
直接上代码:
3. EXTI初始化
和用函数方法差不多,设置几个寄存器;有点不明白的是这里好像可以不用清除标志位;
然后是中断服务程序:
下面是整个用函数代码:
下面是用寄存器代码:
然后是一些用到的文章:
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
最后说下,第一次写笔记,感谢大家阅读,如果有什么不对的地方,欢迎大家留言指正 !
先总的说下实现中断的步骤:
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
最后说下,第一次写笔记,感谢大家阅读,如果有什么不对的地方,欢迎大家留言指正 !
相关文章推荐
- imx6系列--将一个gpio设置为可唤醒系统的外部中断流程
- imx6系列--将一个gpio设置为可唤醒系统的外部中断流程
- K60 GPIO外部中断
- AVR系列之外部中断测试
- STM32 外部GPIO中断配置
- LPC1768外部中断与GPIO中断
- STM32F1x系列——外部中断
- GPIO口中断例程_MK20DX128VLH5_K20系列
- STM32之中断与事件---一个使用GPIO作为外部中断的示例
- (4.2)uboot详解——外部中断(GPIO)
- STM32CubeMX学习教程之二:GPIO输入之外部中断
- At91SAMXX系列设置GPIO口中断端口方法
- stm32L151的GPIO外部中断调试
- 【NUCLEO_F767ZI开发板系列】四、外部中断控制LED
- 第17章 EXTI—外部中断/事件控制器—零死角玩转STM32-F429系列
- STM32--GPIO和外部中断
- 【DSP】TMS320F28035 GPIO外部中断例程
- STM32简单入门程序分析之GPIO,外部中断
- STM8_GPIO 外部中断输入
- LPC1788的外部中断和GPIO中断