STM32F030F4P6按键函数

2019-07-14 19:35发布

本人用STM32F030F4P6写了个按键程序,想要的功能是按键按一次亮再按一次灭,但自己写的程序跟想要的功能差距太大,求指正!(这个程序能实现的功能是:按键按一次就亮,但再按一次就没反应了,如果按了一次那第二次无论按哪个按键都是没反应的;如果第一次按J5那D2亮,按第二次没反应,同时按下J5和J6后在放开D6亮,D2灭,然后同时按J6和J7,D7亮,D6灭;如果第一次按J6那D6亮,同时按J6和J7,D7亮,D6灭,同时按J7和J5,D2亮,D7灭,然后同时按两个都D2都是亮的,(同时按下时都是灭的,松开才亮),还有一个也是这样)之前用过定时器来写也失败了!!这个是用外部中断写的,代码如下:
#include "led.h"
#include "delay.h"

void Gpio_init(void)
{
    GPIO_InitTypeDef        GPIO_InitStructure;
          EXti_InitTypeDef        EXTI_InitTypeStu;
          NVIC_InitTypeDef        NVIC_InitTypeStu;
    /* GPIOC Periph clock enable */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

    /* Configure PC8 and PC9 in output pushpull mode */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
//    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
       
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
//          GPIO_ResetBits(GPIOA,GPIO_Pin_3);
       
       
          EXTI_InitTypeStu.EXTI_Line=EXTI_Line0;
                EXTI_InitTypeStu.EXTI_LineCmd=ENABLE;
                EXTI_InitTypeStu.EXTI_Mode=EXTI_Mode_Interrupt;
                EXTI_InitTypeStu.EXTI_Trigger=EXTI_Trigger_Falling;
          EXTI_Init(&EXTI_InitTypeStu);
                SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
               
                EXTI_InitTypeStu.EXTI_Line=EXTI_Line1;
                EXTI_InitTypeStu.EXTI_LineCmd=ENABLE;
                EXTI_InitTypeStu.EXTI_Mode=EXTI_Mode_Interrupt;
                EXTI_InitTypeStu.EXTI_Trigger=EXTI_Trigger_Falling;
          EXTI_Init(&EXTI_InitTypeStu);
                SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource1);
               
                EXTI_InitTypeStu.EXTI_Line=EXTI_Line2;
                EXTI_InitTypeStu.EXTI_LineCmd=ENABLE;
                EXTI_InitTypeStu.EXTI_Mode=EXTI_Mode_Interrupt;
                EXTI_InitTypeStu.EXTI_Trigger=EXTI_Trigger_Falling;
          EXTI_Init(&EXTI_InitTypeStu);
                SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource2);
               
                NVIC_InitTypeStu.NVIC_IRQChannel=EXTI0_1_IRQn;
                NVIC_InitTypeStu.NVIC_IRQChannelCmd=ENABLE;
                NVIC_InitTypeStu.NVIC_IRQChannelPriority=0x00;
                NVIC_Init(&NVIC_InitTypeStu);
               
                NVIC_InitTypeStu.NVIC_IRQChannel=EXTI2_3_IRQn;
                NVIC_InitTypeStu.NVIC_IRQChannelCmd=ENABLE;
                NVIC_InitTypeStu.NVIC_IRQChannelPriority=0x01;
                NVIC_Init(&NVIC_InitTypeStu);
}

void EXTI0_1_IRQHandler(void)
{
         GPIO_InitTypeDef        GPIO_InitStructure;
         
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
        if(EXTI_GetITStatus(EXTI_Line0) != RESET)
        {
                if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == 0)
        {
                delay_ms(10);
                 GPIO_SetBits(GPIOA,GPIO_Pin_3);
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0/*|GPIO_Pin_1|GPIO_Pin_2*/;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
//          GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_2);
//                GPIOA->ODR ^= GPIO_Pin_0;
                GPIOA->ODR = ~GPIO_Pin_0;
               
        }
               
        }
        EXTI_ClearFlag(EXTI_Line0);
//        EXTI_ClearITPendingBit(EXTI_Line0);
        if(EXTI_GetITStatus(EXTI_Line1) != RESET)
        {
                if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1) == 0)
        {
                delay_ms(10);
                GPIO_SetBits(GPIOA,GPIO_Pin_3);
                GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
//                 GPIO_SetBits(GPIOA,GPIO_Pin_0|GPIO_Pin_2);
//                GPIOA->ODR ^= GPIO_Pin_1;
                GPIOA->ODR = ~GPIO_Pin_1;
        }
       
        }
        EXTI_ClearFlag(EXTI_Line1);
        EXTI_ClearITPendingBit(EXTI_Line1);
}

void EXTI2_3_IRQHandler(void)
{
        GPIO_InitTypeDef        GPIO_InitStructure;
         
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
        if(EXTI_GetITStatus(EXTI_Line2) != RESET)
        {
                if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2) == 0)
        {
                delay_ms(10);
                GPIO_SetBits(GPIOA,GPIO_Pin_3);
                GPIO_InitStructure.GPIO_Pin = /*GPIO_Pin_0|GPIO_Pin_1|*/GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
//                GPIO_SetBits(GPIOA,GPIO_Pin_1|GPIO_Pin_0);
//                GPIOA->ODR ^= GPIO_Pin_2;
                        GPIOA->ODR = ~GPIO_Pin_2;
        }
       
        }
        EXTI_ClearFlag(EXTI_Line2);

}


#include "stm32f0xx.h"
#include "delay.h"
#include "led.h"
#include "uart.h"


int main(void)
{
        delay_init();
   Gpio_init();
       
        while(1)
        {
//                Gpio_init();
        }
}


1494083821420.jpg
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
7条回答
机器人工作者
1楼-- · 2019-07-15 00:07
没有单独写按键检测函数啊,而且直接用取反指令就能实现的功能啊,你这个程序看起来有点小复杂~
蛋糕了
2楼-- · 2019-07-15 04:46
meimengxing2014 发表于 2017-6-6 18:43
你这个问题比较多:
1.最忌讳的就是在中断服务程序中用延时,其实可以在按键中断后打开定时器定时20ms后再处理按键程序
2.IO口只要配置一次就行了,没有必要每次都在中断中再次配置

已经解决了
蛋糕了
3楼-- · 2019-07-15 08:17
 精彩回答 2  元偷偷看……
meimengxing2014
4楼-- · 2019-07-15 12:50
蛋糕了 发表于 2017-6-8 19:04
已经解决了

如果你是在中断中用延时解决的,虽然现在解决了,但是以后你肯定会后悔的
座机呀
5楼-- · 2019-07-15 13:54
很乱的代码,不想看,倒胃口
蛋糕了
6楼-- · 2019-07-15 19:34
meimengxing2014 发表于 2017-6-8 22:06
如果你是在中断中用延时解决的,虽然现在解决了,但是以后你肯定会后悔的

换了另一种思路写出来了

一周热门 更多>