历史上的今天
今天是:2025年02月03日(星期一)
2020年02月03日 | STM32单片机实现外部中断的步骤及方法
2020-02-03 来源:elecfans
先从最简单的问题开始,用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寄存器及(函数),设置中断线,中断方式,等;
voidEXTI_Configuration()
{
EXTI_InitTypeDefEXTI_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文件里:
voidEXTI0_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,为了和下拉区分)
voidGPIO_Config()
{
GPIOA-》CRL=0X03;
GPIOA-》ODR=0X01;
GPIOB-》CRL=0X08;
GPIOB-》ODR=0X01;
}
2. NVIC 初始化:
直接上代码:
voidNVIC_Configuration()
{
u32temp;
temp=SCB-》AIRCR;
temp&=0x0000f8ff;
temp|=0x05fa0000;
temp|=0x0700;
SCB-》AIRCR=temp;
NVIC-》ISER[0]=1《《6;
NVIC-》IP[1]=0;
}
3. EXTI初始化
和用函数方法差不多,设置几个寄存器;有点不明白的是这里好像可以不用清除标志位;
voidEXTI_Configuration()
{
AFIO-》EXTICR[0]=0X0001;
EXTI-》IMR=0X01;
EXTI-》RTSR=0X01;
}
然后是中断服务程序:
voidEXTI0_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”
voidGPIO_Config();
voidNVIC_Configuration();
voidEXTI_Configuration();
voidSysclkConfiguration();
intmain()
{
SysclkConfiguration();
GPIO_Config();
EXTI_Configuration();
NVIC_Configuration();
while(1);
return0;
}
voidSysclkConfiguration()
{
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);
}
}
voidGPIO_Config()
{
GPIO_InitTypeDefGPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;
GPIO
史海拾趣
|
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity fenpin is port(clk:in std_logic;--输入时钟 cmd:in std_logic_vector(7 downto 0);--分频指令cmd clkout:out std_logic);--输出时钟 end fenpin; ...… 查看全部问答> |
|
各位大虾: 最近要做一个手持设备,需要使用stm32F103的STOP模式,但同时我又开了独立看门狗,每当我一进入STOP模式看门狗马上就给我复位了,我怎样才能在进入STOP模式的时候让看门狗不起作用啊?… 查看全部问答> |
|
单片机的C语言的却是个好东西,自学有点难,偶尔在网上看到有个视频讲座.很好.可惜.当时没有把网给记下来.现在找,可就是找不到了.那位仁兄如果知道有这方面的视频讲座,请告诉我约.在下谢谢你了!… 查看全部问答> |
|
在TI或者RFSTORM电池板BB运行上Light_switch程序 以前的帖子,重新整理到这个版面。 在TI或者RFSTORM电池板BB运行上TI CC2530CC2530-Software Examples中light_switch程序的方法。ZBDC51BB(SMARTRF05BB)板和ZBDC51MB(SMARTRF05EB)最主要的区别就是有没有LCD显示。TI的Light_Switch默 ...… 查看全部问答> |
|
8051系统中 mov a,#83h mov ip ,a 问:执行以上程序后,中断优先级高的是————————;中断优先级低的是————————————————;… 查看全部问答> |
|
#include //包含\"位\"操作头文件 #include #include #include \"xianshi.c\" #define uchar unsigned char #define ui ...… 查看全部问答> |




