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
最后说下,第一次写笔记,感谢大家阅读,如果有什么不对的地方,欢迎大家留言指正 !
- STM32F10X系列GPIO外部中断
- STM32F10x外部中断释疑
- STM32--GPIO和外部中断
- K60 GPIO外部中断
- STM32 外部GPIO中断配置
- STM32 GPIO外部中断总结
- STM32 GPIO外部中断总结
- imx6系列--将一个gpio设置为可唤醒系统的外部中断流程
- 28335GPIO及外部中断配置介绍
- 【DSP】TMS320F28035 GPIO外部中断例程
- STM32F10x 之GPIO
- STM32F10x GPIO引脚说明
- STM32F10x的中断
- GPIO工作原理(stm32F10x)
- STM32简单入门程序分析之GPIO,外部中断
- LPC1768菜鸟学习之GPIO和外部中断
- (4.2)uboot详解——外部中断(GPIO)
- STM32F103 GPIO的外部中断的使用例子。
- Nginx和Apache的优缺点比较
- 在不同系统情况下安装sun公司JDK以及Linux下安装Centos 7.0图文详解
- RN第三方下载组件
- Windows下面制作绿色版的Python
- 开发人员也要关心产品设计
- STM32F10X系列GPIO外部中断
- Android 碎片管理
- window下安装tensorflow
- jquery validate 验证去除记忆方法
- ngx_connection_t结构体
- 微服务架构案例及分布式事务解决方案
- Java--多态(polymorphic),上下转型,多态好处弊端
- PHP工作笔记:离线执行php任务
- 简述Yii2里的AOP思想