OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4387|回复: 6

外部中断有点问题,不能完全执行

[复制链接]

3

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2021-1-11
在线时间
30 小时
发表于 2021-7-14 11:38:41 | 显示全部楼层 |阅读模式
2金钱
这是我要做的:   有两个LED灯(LED1和LED2),两个按键(KEY1和KEY2),KEY1和KEY2分别控制LED1和LED2两个灯; KEY1和KEY2都必须用外部中断读取按键高低电平; 当KEY1按下时,LED1亮,同时向上位机发送“KEY1按下”;当KEY1松开时,LED1熄灭,同时向上位机发送"KEY1松开"; 同理当KEY2键按下,LED2亮,同时向上位机发送“KEY2按下”;当KEY2松开时,LED2熄灭,同时向上位机发送"KEY2松开";
在实验5中改的 但是我按下KEY0或者是KEY1,有时可以控制LED的亮和熄灭,但是大多数是按下去的话,LED亮了,松开时,LED还是在亮。没有熄灭。我不知道在哪里改。
exit.c
#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
    int c;
//外部中断0服务程序
void EXTIX_Init(void)
{

           EXTI_InitTypeDef EXTI_InitStructure;
         NVIC_InitTypeDef NVIC_InitStructure;


    KEY_Init();         //        按键端口初始化


          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能复用功能时钟






   //GPIOE.3          中断线以及中断初始化配置 下降沿触发 //KEY1
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
          EXTI_InitStructure.EXTI_Line=EXTI_Line3;
          EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
          EXTI_Init(&EXTI_InitStructure);                  //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器


   //GPIOE.4          中断线以及中断初始化配置  下降沿触发        //KEY0
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
          EXTI_InitStructure.EXTI_Line=EXTI_Line4;
          EXTI_Init(&EXTI_InitStructure);                  //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器




   //GPIOA.0          中断线以及中断初始化配置 上升沿触发 PA0  WK_UP
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);


          EXTI_InitStructure.EXTI_Line=EXTI_Line0;
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
          EXTI_Init(&EXTI_InitStructure);                //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器




          NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                        //使能按键WK_UP所在的外部中断通道
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        //抢占优先级2,
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03;                                        //子优先级3
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);


          NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;                        //使能按键KEY1所在的外部中断通道
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        //抢占优先级2
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                                        //子优先级1
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);            //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器


          NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;                        //使能按键KEY0所在的外部中断通道
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        //抢占优先级2
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;                                        //子优先级0
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);            //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

}


//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
        delay_ms(10);//消抖
        if(WK_UP==1)                  //WK_UP按键
        {                                 
        }
        EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位  
}



//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
        delay_ms(5);//消抖
        if(KEY1==1)         //按键KEY1
        {                 LED1=1;  c=2;delay_ms(10);}
    else if(KEY1==0)//有时是检查不到
        {       LED1=0;  c=1;}               
        EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE3上的中断标志位  
}


void EXTI4_IRQHandler(void)
{
        delay_ms(5);//消抖
        if(KEY0==1)         //按键KEY0
        {        LED0=1; c=4;delay_ms(10);}       
   else if(KEY0==0)//有时是检查不到
        {   LED0=0; c=3;}               
        EXTI_ClearITPendingBit(EXTI_Line4);  //清除LINE4上的中断标志位  
}

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include "exti.h"
        extern int c;
int main(void)
{               
        delay_init();                     //延时函数初始化       
    KEY_Init();         
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        uart_init(115200);         //串口初始化为115200
        LED_Init();                                  //初始化与LED连接的硬件接口
        EXTIX_Init();                 //初始化外部中断输入
        while(1)
        {         delay_ms(10);
                switch(c){
                        case 1:printf("KEY1按下\r\n");c=0; break;
                        case 2:printf("KEY1松开\r\n");c=0; break;
                        case 3:printf("KEY0按下\r\n");c=0; break;
                        case 4:printf("KEY0松开\r\n");c=0; break;
                }
                       
                       
                 
        }         
}




最佳答案

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

3

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2021-1-11
在线时间
30 小时
 楼主| 发表于 2021-7-14 11:38:42 | 显示全部楼层
回复

使用道具 举报

3

主题

40

帖子

0

精华

初级会员

Rank: 2

积分
166
金钱
166
注册时间
2021-1-11
在线时间
30 小时
 楼主| 发表于 2021-7-14 11:39:09 | 显示全部楼层
有大佬看看吗
回复

使用道具 举报

12

主题

3389

帖子

1

精华

论坛元老

Rank: 8Rank: 8

积分
8644
金钱
8644
注册时间
2020-5-11
在线时间
4099 小时
发表于 2021-7-14 15:50:26 | 显示全部楼层
"下降沿触发"怎么检测上升沿?
专治疑难杂症
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2021-7-14 16:17:20 | 显示全部楼层
没做去抖的动作, 一个边沿没处理完另一个边沿又来了, 只要中间有一边沿漏掉就会出现这现象
其实没必要用外部中断来做, 就用SysTick每1ms读一下状态, 然后加上去抖就可以了
回复

使用道具 举报

1

主题

12

帖子

0

精华

高级会员

Rank: 4

积分
953
金钱
953
注册时间
2020-4-16
在线时间
81 小时
发表于 2021-7-14 16:38:23 | 显示全部楼层
消抖还是有必要的,你的KEY0和KEY1是下降沿触发中断,WAKE_UP是上升沿触发中断,对应的消抖部分也是不一样的。最好做一下按下消抖和松开消抖两部分。
回复

使用道具 举报

4

主题

54

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
254
金钱
254
注册时间
2019-4-9
在线时间
79 小时
发表于 2021-7-15 17:04:35 | 显示全部楼层
外部中断初始化过程不对啊,没有EXTI_InitStructure.EXTI_LineCmd=ENABLE;//使能中断,EXTI_GenerateSWInterrupt(EXTI_Line0);  //EXTI_Line1中断允许
这2句话
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-24 00:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表