2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > stm32l4 外部中断按键会卡死_STM32学习之路-按键中断测试(外部中断)

stm32l4 外部中断按键会卡死_STM32学习之路-按键中断测试(外部中断)

时间:2020-07-07 22:25:02

相关推荐

stm32l4 外部中断按键会卡死_STM32学习之路-按键中断测试(外部中断)

void RCC_Config(void)

{

SystemInit(); //系统时钟初始化

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB

| RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD

| RCC_APB2Periph_GPIOE | RCC_APB2Periph_GPIOF

| RCC_APB2Periph_GPIOG, ENABLE);

}

当然, 我们可以不用加SystemInit();这个函数也没事.原因是startup_stm32f10x_hd.s这个文件已经在帮我们干了这些事情了.. 它具体是怎么弄的,还有一些其它东西,目前还没

去研究过,下次再研究看看.

(3)LED配置

void LED_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/*led config*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOD, &GPIO_InitStructure);

}

LED的配置前面应该已经记录了,所以这里就不弄了

(4)配置中断优先级和(5)配置外部中断线,这两个我选择放在一个模块,因为都是和中断有关系的嘛

void EXTI_PC2_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

EXTI_InitTypeDef EXTI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* key for exti */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

GPIO_Init(GPIOC, &GPIO_InitStructure);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);

EXTI_InitStructure.EXTI_Line = EXTI_Line2;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

}

这也没什么好解释的了,前面的文章已经解释了

(6)中断处理函数

这家伙推荐在stm32f10x_it.c里面写,因为那里有命名的模版,跟着官方走,错不了

void EXTI2_IRQHandler(void)

{

if (EXTI_GetITStatus(EXTI_Line2) != RESET) //判断按键是否按下

{

//LED取反

GPIO_WriteBit(GPIOD, GPIO_Pin_6,

(BitAction)((1-GPIO_ReadOutputDataBit(GPIOD, GPIO_Pin_6))));

EXTI_ClearITPendingBit(EXTI_Line2); //清除中断标志位

}

}

这里要注意的就是前面EXTIx这里的数字问题了,1-4没什么问题,5-9就要稍微注意下.如果是应该是这样,它应该是EXTI9_5_IRQHandler

这儿我有个问题,为什么没看到外部中断6呢,也就是EXTI6或7,8这些单独的呢.. 原因可能是5-9他们都使用了同一个中断向量表,这个话我印象中好像在哪儿看过

好,到这里基本功能就完成了.. 现象是可以出了.但是会有个问题就是有时候按一些按键,LED等会没反应或者亮灭几下.. 这就是按键抖动的问题了;

好,接下来说说怎么削抖:

这里说软件消抖,硬件就不说了.. 传说中的抖动出现的原因就是你的手速不够快,使中断触发了一次以上.. 我想如果你以到30年的专业单身手速(右手哦)来按的话

肯定没这个问题..哈哈..好,直接上代码..借鉴人家的:

用下面这个方法,就要调整前面的代码了.

void KEY_DEL(void)

{

num = 0;

if (_keyon == 1) //按键是否按下,在中断处理函数中

{

if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2) == 0)

{

Delay(0x3ffff);//延迟,为的是让你的手速能跟上

if (GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2) == 0) //按键是否抖动

{

while(GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2) == 0); //是否松开

num = 1;

goto n_exit;

}

}

}

n_exit:;

_keyon = 0;

}

void EXTI2_IRQHandler(void)

{

if (EXTI_GetITStatus(EXTI_Line2) != RESET)

{

_keyon = 1;//按键按下标志

EXTI_ClearITPendingBit(EXTI_Line2);

}

}

#include "misc.h"

#include "stm32f10x_gpio.h"

#include "stm32f10x_exti.h"

#include "stm32f10x_rcc.h"

#include "system_stm32f10x.h"

#define LED_ON GPIO_SetBits(GPIOD, GPIO_Pin_6);

void LED_Config(void);

void EXTI_PC2_Config(void);

void RCC_Config(void);

void KEY_DEL(void);

void Delay(u32 times);

unsigned char _keyon = 0, num = 0;

int main(void)

{

unsigned char a = 0;

RCC_Config();

LED_Config();

EXTI_PC2_Config();

LED_ON;

while(1)

{

KEY_DEL();

if (num == 1 && a == 0)

{

GPIO_ResetBits(GPIOD, GPIO_Pin_6);

a = 1;

}

else if(num == 1 && a == 1)

{

GPIO_SetBits(GPIOD, GPIO_Pin_6);

a = 0;

}

}

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。