1.实验环境
(1)Keil uVision5
(2)STM32F407ZGT6
2.实验内容
(1)用定时器3中断方式控制LED0和LED1的闪烁频率;
(2)KEY0、 KEY1和KEY2工作于中断方式;
(3)用按键KEY0控制LED0启动闪烁,再按一次则LED0停止闪烁,熄灭;
(4)用按键KEY1控制LED1启动闪烁,再按一次则LED1停止闪烁,熄灭;
(5)如果LED0或LED1在闪烁,按KEY2点亮LED0或LED1,原来闪烁的停止,这时按KEY0或KEY1不发生任何改变;再按下KEY2后,恢复原来的状态,即闪烁的继续闪烁,熄灭的依然熄灭。
3.实验代码
【exti.c】
int flag_led0=0;
int flag_led1=0;
int lock_key2=0;//标志位
int f_temp0;//加锁的时候暂存标志位
int f_temp1;
//外部中断2服务程序
void EXTI2_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY2==0)
{
if(lock_key2==1)//已加锁
{
lock_key2=0;//解除对key0,key1的锁
TIM_Cmd(TIM3,ENABLE); //使能定时器3
flag_led0=f_temp0;//恢复原状态
flag_led1=f_temp1;
}
else if(lock_key2==0) //
{
if(flag_led0==1||flag_led1==1)//当有一个led在闪烁时:加锁,常亮
{
lock_key2=1;//加锁
if(flag_led0==1){
f_temp0=flag_led0;LED0=0;}//LED0亮//保存原状态
if(flag_led1==1){
f_temp1=flag_led1;LED1=0;}//LED1亮
TIM_Cmd(TIM3,DISABLE); //失能定时器3
}
else //两个灯都熄灭时,仅加锁
{
lock_key2=1;//加锁
f_temp0=flag_led0;
f_temp1=flag_led1;//保存原状态
TIM_Cmd(TIM3,DISABLE); //失能定时器3
}
}
}
EXTI_ClearITPendingBit(EXTI_Line2);//清除LINE2上的中断标志位
}
//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY1==0)
{
if(flag_led1==1) {
flag_led1=0;}//闪烁->熄灭
else flag_led1=1;//熄灭->闪烁
}
EXTI_ClearITPendingBit(EXTI_Line3); //清除LINE3上的中断标志位
}
//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
delay_ms(10); //消抖
if(KEY0==0)
{
if(flag_led0==1) {
flag_led0=0;}//闪烁->熄灭
else flag_led0=1;//熄灭->闪烁
}
EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中断标志位
}
【timer.c】
//定时器3中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
if(lock_key2==0)
{
if(flag_led0==1) LED0=!LED0;//DS0翻转
else LED0=1;
if(flag_led1==1) LED1=!LED1;//DS1翻转
else LED1=1;
}
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}
【main.c】
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "key.h"
#include "exti.h"
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
LED_Init(); //初始化LED端口
delay_ms(100); //延时
EXTIX_Init(); //中断初始化
TIM3_Int_Init(5000-1,8400-1); //定时器时钟84M,分频系数8400,所以84M/8400=10Khz的计数频率,计数5000次为500ms
while(1)
{
}
}
4.注意事项
(1)代码未解决的问题:不能实现异步闪烁锁定后开启还是异步闪烁。