打印
[STM32F0]

按键函数

[复制链接]
400|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
用STM32F030F4P6写了个按键程序,想要的功能是按键按一次亮再按一次灭,但自己写的程序跟想要的功能差距太大,求指正!(这个程序能实现的功能是:按键按一次就亮,但再按一次就没反应了,如果按了一次那第二次无论按哪个按键都是没反应的;如果第一次按J5那D2亮,按第二次没反应,同时按下J5和J6后在放开D6亮,D2灭,然后同时按J6和J7,D7亮,D6灭;如果第一次按J6那D6亮,同时按J6和J7,D7亮,D6灭,同时按J7和J5,D2亮,D7灭,然后同时按两个都D2都是亮的,(同时按下时都是灭的,松开才亮),还有一个也是这样)之前用过定时器来写也失败了

使用特权

评论回复
沙发
zyf部长| | 2020-3-7 11:47 | 只看该作者

楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因

使用特权

评论回复
板凳
liuzaiy|  楼主 | 2020-3-7 11:52 | 只看该作者
这个是用外部中断写的,代码如下:
#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();
        }
}

使用特权

评论回复
地板
liuzaiy|  楼主 | 2020-3-7 11:54 | 只看该作者

使用特权

评论回复
5
wenfen| | 2020-3-7 11:57 | 只看该作者
最忌讳的就是在中断服务程序中用延时

使用特权

评论回复
6
juventus9554| | 2020-3-7 12:01 | 只看该作者
其实可以在按键中断后打开定时器定时20ms后再处理按键程序

使用特权

评论回复
7
xxrs| | 2020-3-7 12:04 | 只看该作者
IO口只要配置一次就行了,没有必要每次都在中断中再次配置

使用特权

评论回复
8
pangb| | 2020-3-7 12:10 | 只看该作者
没有单独写按键检测函数啊,而且直接用取反指令就能实现的功能啊

使用特权

评论回复
9
lium| | 2020-3-7 12:12 | 只看该作者
不能用中断中用延时解决的

使用特权

评论回复
10
liuzaiy|  楼主 | 2020-3-7 12:48 | 只看该作者

嗯,我再好好缕一缕吧,有了好消息及时通知大家

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

735

主题

7546

帖子

2

粉丝