问题遇到的现象和发生背景 :
昨天看了正点原子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翻转,改变调时的对象
但现在按下按键之后,变量没有反应,串口打印结果如下
不论怎么按键,变量都没反应,LED也没反应
我想要达到的结果
按下按键后,变量能随之改变。
另:请问用ST-LINK debugger的时候,按下板上的按键,keil里正在debug的程序能接收到按键被按下的信息吗。
这是所有的工程文件
链接:https://pan.baidu.com/s/1o5vo90_dVQN23iLhdjmSAw?pwd=j3kx
提取码:j3kx