历史上的今天
返回首页

历史上的今天

今天是:2024年12月21日(星期六)

2018年12月21日 | STM32一枚按键的旅行(GPIO+中断+NVIC分组)

2018-12-21 来源:eefocus

首先看硬件原理图

GPIO的C13和E0是两个按键,平时是高电平,当按键下去的时候就接地变成低电平。(所以中断是下降沿触发)


开始软件配置:


宏定义两个按键


(仔细看是有必要的,因为你看 GPIO_Pin_13和GPIO_PinSource13的排序是不同的)


#define TSKEY1GPIO          GPIOC

#define TSKEY1GPIOPIN        GPIO_Pin_13

#define TSKEY1IRQ   EXTI15_10_IRQn

#define TSKEY1_ExtiPortsource            GPIO_PortSourceGPIOC

#define TSKEY1_ExtiPin       GPIO_PinSource13

#define TSKEY1_Line   EXTI_Line13

 

#define TSKEY2GPIO          GPIOE

#define TSKEY2GPIOPIN        GPIO_Pin_0

#define TSKEY2IRQ         EXTI0_IRQn

#define TSKEY2_ExtiPortsource            GPIO_PortSourceGPIOE

#define TSKEY2_ExtiPin       GPIO_PinSource0

#define TSKEY2_Line   EXTI_Line0


初始化函数:


void TS_Key_init(void)

{

    GPIO_InitTypeDef GPIO_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    EXTI_InitTypeDef EXTI_InitStructure;

  

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOE| RCC_APB2Periph_AFIO,ENABLE ) ;

                                                             //RCC_APB2Periph_AFIO不能没有!!

 

 

    GPIO_InitStructure.GPIO_Pin = TSKEY1GPIOPIN ;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//MUST 如果是GPIO_Mode_IN_FLOATING则失败;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(TSKEY1GPIO, &GPIO_InitStructure);

 

 

    NVIC_InitStructure.NVIC_IRQChannel = TSKEY1IRQ;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

 

 

    GPIO_EXTILineConfig(TSKEY1_ExtiPortsource, TSKEY1_ExtiPin);

    EXTI_InitStructure.EXTI_Line = TSKEY1_Line;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;  

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

    GPIO_InitStructure.GPIO_Pin = TSKEY2GPIOPIN ;

    GPIO_Init(TSKEY2GPIO, &GPIO_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = TSKEY2IRQ;

    NVIC_Init(&NVIC_InitStructure);

    GPIO_EXTILineConfig(TSKEY2_ExtiPortsource, TSKEY2_ExtiPin);

    EXTI_InitStructure.EXTI_Line = TSKEY2_Line;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling ;  

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

}

 


现在就可以用中断了,到it.c去写服务程序吧。


int it=100;//Test

 

u8 EXit_Delay(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)//消抖 延时以后去读 如果还是低电平 那就是中断!

{

    OSTimeDlyHMSM(0, 0, 0, 100);

    if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin)==RESET)

         return 1;

    else 

        return 0;

}

这里主要是因为init的时候是下降沿是中断,所以去读,如果是0那就真的是中断。

 

 

 

void EXTI0_IRQHandler(void)

{

OS_CPU_SR  cpu_sr;

OS_ENTER_CRITICAL();

OSIntNesting++;

OS_EXIT_CRITICAL();

 

 

 if(EXTI_GetITStatus(TSKEY2_Line) != RESET)

 {

      

       if( EXit_Delay(TSKEY2GPIO,TSKEY2GPIOPIN))

       {

          it+=10;

       }

 

       EXTI_ClearITPendingBit(TSKEY2_Line);

 }

 OSIntExit();

}

 

 

void EXTI15_10_IRQHandler(void)

{

    OS_CPU_SR  cpu_sr;

    OS_ENTER_CRITICAL();

    OSIntNesting++;

    OS_EXIT_CRITICAL();

 

    if(EXTI_GetITStatus(TSKEY1_Line) != RESET)            

    {

       if( EXit_Delay(TSKEY1GPIO,TSKEY1GPIOPIN))

       {

        it-=5;

      }

      EXTI_ClearITPendingBit(TSKEY1_Line);

    }    

    OSIntExit();

}

 


思考:


1对比文章:https://blog.csdn.net/tianshi_1988/article/details/52175434


为什么 GPIO_Mode_IPU成功  GPIO_Mode_IN_FLOATING失败;




回答:http://www.stmcu.org/module/forum/thread-616140-1-1.html




2复用不能丢




3消抖是软件写的,如果你是上升沿触发的话,那就是延时一会再去读,是高电平,1




++++++++++++++++++++++补充HAL库++++++++++++++++++++++++


HAL库写的话非常简单,无脑写。


上传工程。https://pan.baidu.com/s/1BDr4Z-0nOq8lgv5kW2-m9Q


按键下去,就是低电平,灯就翻转。(没有消抖 你 会理解的)


外接一个声控开关,3.3v+GND 连接,OUT连接到D9,有声音的时候就OUT出1,所以STM32是IN


  while (1)

  {

 

  /* USER CODE END WHILE */

 

  /* USER CODE BEGIN 3 */

HAL_Delay(100);

sound=HAL_GPIO_ReadPin(SOUNDIN_GPIO_Port, SOUNDIN_Pin);

key  =!HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin);

if(sound)

{

  HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);

  sound=0;

 

}

if(key)

{

  HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);

  key=0;

 

}

  }

+++++++++20180626补充中断知识+++++++


视频 :http://www.moore8.com/courses/trainning_playback/1679


没想到NVIC中断也说了一节课。有必要的


https://blog.csdn.net/jdsnpgxj/article/details/54573855


默认情况下,如何不设置中断优先级分组,则中断优先级分组默认为0,

即0位抢占优先级,4位响应优先级,则无任何抢占优先级,所以无论中断的优先级设多少,都没有抢占中断的功能,

所以,如果想要一个中断打断另一个中断,必须设置中断优先级分组为1,2,3,4.

如设置优先级分组为2

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

参考:  https://blog.csdn.net/bloong/article/details/46409511

STM32的NVIC:https://blog.csdn.net/ABAP_Brave/article/details/52457175

推荐阅读

史海拾趣

Custom Mmic Design Services Inc公司的发展小趣事

近年来,随着电子行业的快速发展和市场竞争的加剧,CMDS也面临着诸多挑战。例如,原材料价格波动、人工成本上升、环保要求提高等都给公司的生产和经营带来了压力。然而,CMDS凭借其强大的技术实力和市场竞争力,积极应对这些挑战。通过优化生产流程、提高生产效率、加强成本管理等措施,CMDS不仅成功克服了这些困难,还实现了稳健的发展。同时,公司还注重环境保护和社会责任,积极推动可持续发展战略的实施。

Acme Electric Corporation公司的发展小趣事

为了进一步拓展国际市场,CMDS积极寻求与国外企业的合作。通过与国际知名电子企业建立战略合作关系,CMDS不仅获得了先进的技术支持和市场资源,还成功将其产品打入国际市场。同时,公司还积极参加国际展会和交流活动,与全球同行建立了广泛的联系和合作网络。这些国际合作不仅为CMDS带来了更多的商业机会,也提升了其在国际市场上的知名度和影响力。

Brite-Led Optoelectronics Inc公司的发展小趣事

面对电子行业的快速变化和不断升级的技术需求,Brite-Led始终保持敏锐的洞察力和创新精神。公司不断投入研发资源,推出新产品和新技术,以满足市场的变化和客户的需求。同时,公司还注重人才培养和引进,建立了一支高素质的研发团队和管理团队。这些措施使得Brite-Led在激烈的市场竞争中始终保持领先地位,实现了持续发展。

以上是关于Brite-Led Optoelectronics Inc公司发展的5个虚构故事,虽然这些故事是基于虚构的,但它们可能反映了Brite-Led Optoelectronics Inc公司在实际发展中可能遇到的一些情况和挑战。

Circuit Assembly公司的发展小趣事

面对电子行业的快速变化和不断升级的技术需求,Brite-Led始终保持敏锐的洞察力和创新精神。公司不断投入研发资源,推出新产品和新技术,以满足市场的变化和客户的需求。同时,公司还注重人才培养和引进,建立了一支高素质的研发团队和管理团队。这些措施使得Brite-Led在激烈的市场竞争中始终保持领先地位,实现了持续发展。

以上是关于Brite-Led Optoelectronics Inc公司发展的5个虚构故事,虽然这些故事是基于虚构的,但它们可能反映了Brite-Led Optoelectronics Inc公司在实际发展中可能遇到的一些情况和挑战。

FILTRONIC公司的发展小趣事

随着市场需求的不断增长,FILTRONIC开始着手拓展产品线,从单一的滤波器产品扩展到包括射频模块、天线等在内的多种无线通信产品。同时,公司也积极实施国际化战略,通过参加国际展会、设立海外办事处等方式,逐步打开了国际市场的大门。FILTRONIC的产品以其卓越的性能和可靠的质量赢得了全球客户的信赖,公司也因此实现了业务的快速增长。

Eagle-Picher公司的发展小趣事

然而,Eagle-Picher的发展并非一帆风顺。1991年9月16日,位于密苏里州乔普林的Eagle-Picher工业公司电子部遭受了一场毁灭性的大火。火灾导致公司的电池生产设备化为灰烬,给公司的业务带来了巨大的打击。然而,Eagle-Picher并没有放弃,而是迅速组织力量进行重建和恢复生产。这一事件虽然给公司带来了短期的困难,但也展现了Eagle-Picher的坚韧和决心。

问答坊 | AI 解惑

请教OD门上拉电阻?

请教OD门上拉电阻的计算,问什么对于与非门负载,n是负载门数目而不是输入端数目?下图。我是菜鸟,请高手指点。…

查看全部问答>

关于做红外传感器模块的感想

由于是第一次做红外传感器,所以自己到网上搜了几个电路,发现了很多问题,和大家分享一下。 第一个问题就是检测电路是否正确,我一开始就上来就做,其实是错误的,后来就发生了怎么调电路 的结果都是错误的。(其实错误的一塌糊涂) 所以很好 ...…

查看全部问答>

wince 6.0 nk.bin大于32M 下载失败

wince 6.0增加简体字库后,NK.bin就有33M了。 想把NK.bin调大,如35M 1、修改Bootloader\\Eboot\\eboot.bib,修改如下: //#define ROM_RAMIMAGE_SIZE           0x02000000        ...…

查看全部问答>

单片机中发送双音频是怎么回事

大家好,在单片机中发送双音频是怎么回事? 发送双音频和发送单音频有什么区别和联系? 我现在做的是报警器,一个主机接收,手持机用于发送 里面用到双音频,还有发送一位单音频,这样的发送有什么方法可以看得出来? 谢谢! …

查看全部问答>

请问大家是是如何测试wince驱动性能的?

我以前只会写一些单片机的小程序 现在发现测试驱动的性能也不知道如何下手,我觉得wince驱动和win32 有些类似,我想请问这些驱动应该如何测试? 都有什么指标要求?我们公司混乱得很,用肉眼感觉测试,觉得有点离谱。请大家说说你们的办法。多谢 ...…

查看全部问答>

AT命令集的问题

AT命令集的定义是怎样的?是不是很复杂,用它是不是很麻烦? 我是外行,我想了解一下AT命令集,想知道如何更好更快的学会使用它. …

查看全部问答>

怎么通过WAVEINOPEN那些API函数把音频数据录成原始的PCM文件(没有压缩,没有处理过)?在网上没找到,只找到录成WAV文件的例子

怎么通过WAVEINOPEN那些API函数把音频数据录成原始的PCM文件(没有压缩,没有处理过)?在网上没找到,只找到录成WAV文件的例子! //------------- 希望能够给个简单的例子程序啊!…

查看全部问答>

为什么我每次创建菜单后都出现fatal error RC1015: cannot open include file 'afxres.h'.。。

为什么我每次创建菜单后都出现fatal error RC1015: cannot open include file \'afxres.h\'.。。 我创建菜单后,就inclue \"resource.h\" 然后编译 每次都是这个错误 为此 我实验过 重装evc \\sdk\\但是还是 这样 所以求救。。还有 一个问题我写 ...…

查看全部问答>

P1REN会影响到P1OUT吗?请有EZ430-F2013的朋友帮我做个实验,非常简单

从TI提供的P1口的图纸上看,P1OUT.0的输出不受P1REN.0的影响,可是如果做个实验,发现完全不是这么回事: 如下分析使用EZ430-F2013: 1.随便打开一个工程,进入调试状态,不运行程序,打开寄存器窗口; 2.在寄存器窗口中,设置P1OUT.0=1,P1DIR.0 ...…

查看全部问答>

AT91RM9200 ARM中SMC里的NWAIT信号的使用

datasheet中对于NWAIT的描述没理解,是这样的么?比如外挂FPGA,当EBI向外设输出读命令之后,外设FPGA将NWAIT信号拉低,这样EBI开始等待,等外设中的数据读回来之后,外设把NWAIT拉高,结束读过程。同理,写操作,当EBI向外设输出写命令之后,外设F ...…

查看全部问答>