M!U 2022-02-27 21:23 采纳率: 0%
浏览 52

stm32编程(标准库)根据正点原子的例程想将RTC与按键外部中断结合做一个功能,但按键无反应

问题遇到的现象和发生背景 :

昨天看了正点原子RTC实验的教程,想在原子提供的例程上增加一些功能:实时调整时间
第一步:想用按键的外部中断去改变一些变量的值,以此选定需要实时调整的对象
但现在按键按了之后没反应
其他功能就没法继续写下去

问题相关代码,请勿粘贴截图

这是main函数的代码

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"    
#include "usmart.h"     
#include "rtc.h" 
#include "exti.h"
     u8 t=0;    
     u8 change=0;
     u8 subject=1;
     u8 add=0;
     u8 blink=0;
     u8 flag=0;
 
int main(void)
 {     
    uart_init(115200);
    delay_init();             //延时函数初始化      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
    uart_init(115200);         //串口初始化为115200
     LED_Init();                 //LED端口初始化
    LCD_Init();                 
    usmart_dev.init(SystemCoreClock/1000000);    //初始化USMART    
    RTC_Init();                  //RTC初始化
    POINT_COLOR=RED;//设置字体为红色 
    //LCD_ShowString(60,50,200,16,16,"Elite STM32");    
    //LCD_ShowString(60,70,200,16,16,"RTC TEST");    
    //LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
    //LCD_ShowString(60,110,200,16,16,"2015/1/14");        
    //显示时间
    POINT_COLOR=BLUE;//设置字体为蓝色
    LCD_ShowString(60,130,200,16,16,"    -  -  ");       
    LCD_ShowString(60,170,200,16,16,"  :  :  ");    
    //KEY_Init();
    EXTIX_Init();
    while(1)
    {    
            t=calendar.sec;
            if(~(blink&&(subject==6)))    LCD_ShowNum(60,130,calendar.w_year,4,16);                                      
            if(~(blink&&(subject==5)))    LCD_ShowNum(97,130,calendar.w_month,2,16);                                      
            if(~(blink&&(subject==4)))    LCD_ShowNum(124,130,calendar.w_date,2,16);     
            switch(calendar.week)
            {
                case 0:
                    LCD_ShowString(60,148,200,16,16,"Sunday   ");
                    break;
                case 1:
                    LCD_ShowString(60,148,200,16,16,"Monday   ");
                    break;
                case 2:
                    LCD_ShowString(60,148,200,16,16,"Tuesday  ");
                    break;
                case 3:
                    LCD_ShowString(60,148,200,16,16,"Wednesday");
                    break;
                case 4:
                    LCD_ShowString(60,148,200,16,16,"Thursday ");
                    break;
                case 5:
                    LCD_ShowString(60,148,200,16,16,"Friday   ");
                    break;
                case 6:
                    LCD_ShowString(60,148,200,16,16,"Saturday ");
                    break;  
            }
            if(~(blink&&(subject==3)))    LCD_ShowNum(60,170,calendar.hour,2,16);                                      
            if(~(blink&&(subject==2)))    LCD_ShowNum(84,170,calendar.min,2,16);                                      
            if(~(blink&&(subject==1)))    LCD_ShowNum(108,170,calendar.sec,2,16);
            //LED0=!LED0;
            if(change)blink=!blink;
            
            printf("change:%d subject:%d blink:%d \r\n" ,change,subject,blink);
        delay_ms(1000);                                  
    };  
 }

这是外部中断函数的代码,只改变了中断的优先级(使其高于rtc秒中断的优先级)和中断函数里的相关函数

#include "exti.h"
#include "led.h"
#include "key.h"
#include "delay.h"
#include "usart.h"
//#include "beep.h"

extern u8 change;
extern u8 subject;
extern u8 add;
extern u8 blink;

//外部中断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 = 0x00;    //抢占优先级0, 
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                    //子优先级1
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
      NVIC_Init(&NVIC_InitStructure); 

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

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

//外部中断0服务程序 
void EXTI0_IRQHandler(void)//按下WK_UP,开启调时模式
{
    delay_ms(10);//消抖
    if(WK_UP==1)          //WK_UP按键
    {                 
        change=!change;
        LED1=!LED1;    
        subject=1;
    }
    EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位  
}
 

//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
    delay_ms(10);//消抖
    if(KEY1==0)     //按键KEY1
    {                 
        
    }         
    EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE3上的中断标志位  
}

void EXTI4_IRQHandler(void)//按下KEY_0,切换调整对象
{
    delay_ms(10);//消抖
    if(KEY0==0)     //按键KEY0
    {
        subject=subject+1;    //subject    6    5    4    3    2    1
        LED0=!LED0;    //调整对象    年    月    日    时    分    秒
        if(subject>6)
        {
            subject=1;
        }
    }         
    EXTI_ClearITPendingBit(EXTI_Line4);  //清除LINE4上的中断标志位  
}

运行结果及报错内容

我设想是按下WK_UP(PA.0)键后,变量change变成1并且LED1翻转,表示开启调时功能
按下KEY0(PE.4)键后,变量subject+1并且LED0翻转,改变调时的对象
但现在按下按键之后,变量没有反应,串口打印结果如下

img


不论怎么按键,变量都没反应,LED也没反应

我想要达到的结果

按下按键后,变量能随之改变。
另:请问用ST-LINK debugger的时候,按下板上的按键,keil里正在debug的程序能接收到按键被按下的信息吗。

这是所有的工程文件
链接:https://pan.baidu.com/s/1o5vo90_dVQN23iLhdjmSAw?pwd=j3kx
提取码:j3kx

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-07 16:47
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 修改了问题 2月27日
  • 创建了问题 2月27日

悬赏问题

  • ¥15 使用MATLAB进行余弦相似度计算加速
  • ¥15 服务器安装php5.6版本
  • ¥15 我想用51单片机和数码管做一个从0开始的计数表 我写了一串代码 但是放到单片机里面数码管只闪烁一下然后熄灭
  • ¥20 系统工程中,状态空间模型中状态方程的应用。请猛男来完整讲一下下面所有问题
  • ¥15 我想在WPF的Model Code中获取ViewModel Code中的一个参数
  • ¥15 arcgis处理土地利用道路 建筑 林地分类
  • ¥20 使用visual studio 工具用C++语音,调用openslsx库读取excel文件的sheet问题
  • ¥100 寻会做云闪付tn转h5支付链接的技术
  • ¥15 DockerSwarm跨节点无法访问问题
  • ¥15 使用dify通过OpenAI 的API keys添加OpenAI模型时报了“Connection Error”错误