历史上的今天
返回首页

历史上的今天

今天是:2024年10月09日(星期三)

正在发生

2021年10月09日 | STM32_按键中断

2021-10-09 来源:eefocus

***************************************************************************************************************************************


开发板   :奋斗STM32


CPU        :STM32F103


开发环境:keil uVsion4


****************************************************************************************************************************************


前言:本文主要是通过按键中断,实现当按下按键时,LED灯灭,释放按键时,LED灯亮。(不过我设置LED的起始状态为亮,也就是上电就点亮了LED灯。)


我的开发板按键,LED所对应的GPIO管脚原理图如下:

我写的按键中断程序实现的功能是:按下按键K2,LED3由亮变灭,释放按键LED3又变亮。(按键K2对应PC2管脚,LED3对应PD3管脚)。


测试代码:

#include "misc.h"

#include "stm32f10x_gpio.h"

#include "stm32f10x_exti.h"

#include "stm32f10x_rcc.h"

 

#define LED_ON GPIO_SetBits(GPIOD, GPIO_Pin_3);

 

//unsigned char flag=0;

//unsigned char num=0;

void LED_Config(void);

void EXTI_PC2_Config(void);

void RCC_Config(void);

//void KEY_Dither(void);

//void delay_nms(u16 time);

int main(void)

// unsigned char a = 0;

RCC_Config();

LED_Config();

EXTI_PC2_Config();

LED_ON;

while(1)

{

//KEY_Dither();

//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;}

  }

}

/*void KEY_Dither(void)

{

num=0;

if(flag==1)

{   

  delay_nms(12000);

   if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==0)

{

delay_nms(12000);

   if(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==0)

{

while(GPIO_ReadInputDataBit(GPIOD,GPIO_Pin_6)==0)

num=1;

   goto n_exit;

   }

    }

else ;

           n_exit:;

           flag=0;

}

}  

void delay_nms(u16 time)

{    

   u16 i=0;  

   while(time--)

   {

      i=12000;  //自己定义

      while(i--) ;    

   }

}

*/

void RCC_Config(void)  

{    

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 

   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOD,ENABLE); 

     SystemInit();  

 

}  

 

void LED_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

 

/*led config*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOD, &GPIO_InitStructure);

 

}

void EXTI_PC2_Config(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

EXTI_InitTypeDef EXTI_InitStructure;

GPIO_InitTypeDef GPIO_InitStructure;

  /*config for NVIC*/

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);

  /*EXIT line(PC2) mode config */

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);

 

}

void EXTI2_IRQHandler(void)  

{  

    if (EXTI_GetITStatus(EXTI_Line2) != RESET)  

    {  

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

    /*LED取反*/

         GPIO_WriteBit(GPIOD, GPIO_Pin_3,  

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

  

        EXTI_ClearITPendingBit(EXTI_Line2);  

    }  

}  

************************************************************************************************************************************

说明:我写的这个程序只是实现了按键按下灯由亮变灭的简单功能,但是测试发现,这个按键抖动太严重,轻轻的触摸按键,灯会闪闪的亮,有时


候碰一下按键,还没有按下按键时,LED灯就熄灭了。所以用delay_nms()延时函数进行去抖,代码中注释掉的代码是为了按键去抖,不过这个去抖效果不是很好,还是会有抖动现象,但相比之前会好一点!不过官方提供了一个延时函数,可以调用官方写好的延时函数,一般10ms的时间可以去抖。


************************************************************************************************************************************************


写这个程序主要是完成相应的配置工作,步骤如下:



(1)初始化系统时钟和


初始化外部时钟(时钟配置)

void RCC_Config(void)  

{    

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);  

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOD,ENABLE); 

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

}  

*****************************************************************************************************************************************************************************


说明:我们可以不用加SystemInit();不加这个函数也没影响,因为startup_stm32f10x_hd.s这个文件已经帮我们做了这些事情。


*****************************************************************************************************************************************************************************


(3)配置LED


void LED_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

 

/*led config*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOD, &GPIO_InitStructure);

 

}

(4)配置中断优先级


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);

*********************************************************************************************************************************************************************************

说明:这个中断优先级的设置可以随便设置,原因是我创建的工程中只用到了按键中断,没有其他中断,当然如果有多个中断,就得按照中断向量表


以及中断优先级设定规则来设,具体规则可以参考网上的资料,有很多,可以看看,这里我就不说明了。这里我设置的是第一组中断,抢占优先级是


0,响应优先级也是0。


************************************************************************************************************************************************************************************

(5)配置外部中断线


/*EXIT line(PC2) mode config */

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);

*************************************************************************************************************************************************************************************

说明:这个中断模式有两种,一是Event,二是Interrupt,因为这里是中断,所以我们设为


Interrupt ,因为是按键Key2,则这里中断线为EXTI_Line2,如果按键是5-9则这里就要统一写成EXTI9_5_IRQn。

**************************************************************************************************************************************************************************************



(6)中断处理函数


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); //清除中断标志位

}

****************************************************************************************************************************************************************************************

说明:这里的中断处理函数我们通常最好是放在 stm32f10x_it.c这个文件,这是官方提供的一个用来放所有外部中断处理函数的文件,当主程序在执行程序时,如果发生中断,cpu会立即跳到这里来执行中断处理函数,这里因为只有按键中断,还体现不出这样做的好处,如果是一个大工程,用到多个中断时,把中断函数统一放在这个文件中的话,可以大大优化代码。

***************************************************************************************************************************************************************************************

推荐阅读

史海拾趣

BTCPower公司的发展小趣事

在面对行业竞争加剧和市场需求变化的挑战时,BTCPower展现了出色的危机应对能力。公司及时调整战略和业务结构,开始向智能家居、物联网等新兴领域拓展业务。通过不断创新和转型,BTCPower成功度过了危机,并迎来了新的发展机遇。

这些故事基于电子行业常见的情境和趋势进行虚构,旨在满足您的需求。请注意,这些故事并非真实事件,也不代表任何真实公司的经历。

Bellnix Co Ltd公司的发展小趣事

Bellnix Co Ltd自创立之初,便以技术创新为核心竞争力。在电子元器件制造领域,公司不断投入研发,推出了一系列高性能、低成本的芯片产品。这些产品不仅在国内市场占据了一席之地,还成功打入了国际市场,赢得了众多客户的认可。随着技术的不断积累,Bellnix逐渐在行业内树立起了技术领先的形象,从而实现了公司的快速发展。

ADI(亚德诺半导体)公司的发展小趣事

随着国内市场的逐渐饱和,Bellnix开始将目光投向海外市场。公司制定了国际化战略,通过设立海外分公司、建立销售网络等方式,积极拓展海外市场。同时,Bellnix还加强与国际同行的交流与合作,引进先进的技术和管理经验,提升公司的国际化水平。这些举措使Bellnix在国际市场上取得了显著成绩,为公司的发展注入了新的动力。

达晶微(CREATEK)公司的发展小趣事

达晶微注重企业文化建设和团队建设。公司倡导创新、协作、务实、进取的企业精神,鼓励员工勇于挑战、追求卓越。同时,公司还建立了完善的培训体系和人才激励机制,为员工提供了广阔的发展空间和良好的职业前景。这些措施有效地激发了员工的工作热情和创造力,为公司的发展注入了源源不断的动力。

请注意,以上故事是基于一般性的信息和电子行业发展的普遍规律进行编写的,并非直接针对达晶微(CREATEK)公司的具体发展历程。如需了解更多详细信息,建议您查阅达晶微(CREATEK)公司的官方网站或相关新闻报道。

Daburn公司的发展小趣事

在追求企业发展的同时,Daburn公司也积极履行社会责任。公司注重环保和可持续发展,通过采用环保材料和节能设备、优化生产流程等方式降低对环境的影响。此外,Daburn还积极参与公益事业和社会活动,为社会做出积极贡献。这种社会责任感让Daburn在行业中树立了良好的形象。

ENTRELECUK公司的发展小趣事

随着业务的不断发展,ENTRELEC UK开始寻求全球市场的拓展。公司通过与国外代理商建立合作关系,将产品销往世界各地。同时,公司还在海外设立研发中心和生产基地,以便更好地了解当地市场需求,提供定制化的解决方案。这些举措使ENTRELEC UK在全球电子行业中树立了良好的品牌形象。

问答坊 | AI 解惑

最早的手机

本帖最后由 jameswangsynnex 于 2015-3-3 20:01 编辑 手机从问世到现在已经有20多年的历史了,从巨型大哥大到现在的直板,滑盖,翻盖,旋盖等造型并存,手机的外形越来越小巧,而造型则是越来越时尚,我们一起来回顾一下最早的手机: …

查看全部问答>

噪声问题

  --------------------------------------------------------------------------------     我的收音机用的是cl6017s,它在收听到电台的时候总是有类似于单片机(MSP430F135)扫描键盘那种节奏的嘟嘟声噪音,我用示波器亮了 ...…

查看全部问答>

6410的otg怎么配置成host使用?

6410的otg怎么配置成host使用?…

查看全部问答>

windML3.0 的编译错误问题

安装了Tornado2.2.1(for MIPS)和windML3.0 编译WindML库文件时遇到下面的错误。请高手分析一下。谢谢 子目录或文件 D:\\Tornado2.2_MIPS\\target\\lib\\mips\\MIPS64\\gnule\\objwndml 已经存在。 make.exe[4]: [checkdir] Error 0x1 (ignored ...…

查看全部问答>

求助 flash烧写

pxa271的芯片能用flashpgm烧写bootloader么?如果不能,应该用什么烧写工具呢?…

查看全部问答>

【号外】STM32F101也有USB

刚做的东西给几个小MM去贴片,把101当103贴上去了,居然USB也可以联机。但操作偶尔有问题,手工复位一般可以解决掉。听小道消息说,101是阉割的103,就像奔腾的cache有瑕疵变成赛扬一样。…

查看全部问答>

RTC校准应用笔记中文版,望置顶

                                 我翻译的,大家多多指教!…

查看全部问答>

正弦波振荡器,求解释

小弟菜菜~在学模拟电子,看了正弦波振荡器就尝试自己做了一个~但是输出的波形却是下面这个图上的   望路过的各位大大们能解释下,小弟感激不敬啊~~…

查看全部问答>

AD633应用

本帖最后由 dontium 于 2015-1-23 13:12 编辑 各位帮忙看一下。用AD633搭的一个乘法电路,实现两个郑玄信号的相乘。正弦信号相位相同。按说最后只会剩下直流分量与和频分量的合成曲线,但是用滤波器想过滤掉交变分量,只剩直流分量。可是滤波后得 ...…

查看全部问答>

在DSP系统的设计初期,是否需要CPLD来增加布线灵活性

在DSP系统的设计初期,是否需要CPLD来增加布线灵活性?之前做过几个板遇到IO端口设计不合理导致板子要重做的情况。增加CPLD成本就自然增加了。 [ 本帖最后由 weipingying 于 2012-12-26 08:43 编辑 ]…

查看全部问答>