蓝桥杯之单片机设计与开发(6)——独立按键和流水灯

2019-04-15 12:12发布

用独立按键控制LED流水灯 main.c /******************************************************************************* * 文件名:main.c * 描 述: 1.按下S7,8个LED从中间到两端对称点亮两个,时间间隔1s 2.按下S6,8个LED从两端到中间对称点亮两个,时间间隔1s 3.按下S5,8个LED从左往右轮流点亮,时间间隔1s 4.按下S4,8个LED从右往左每隔两个灯点亮,时间间隔1s * 作 者:小默haa * 版本号:v1.0 * 日 期: 2019年1月27日 * 备 注:独立按键控制LED流水灯 * *******************************************************************************/ #include #include "sys.h" #define u16 unsigned int #define u8 unsigned char u8 Led_flag = 0; u8 Led_dat; //led显示状态 u8 KeySta[4] = {1,1,1,1}; //当前按键状态 u8 Key_backup[4] = {1,1,1,1}; //按键状态备份,保存前一次的按键值 void main(void) { u8 i; All_Init(); Time0_Init(); Led_dat = 0xfe; while(1) { for(i = 0;i < 4;i++) { if(Key_backup[i] != KeySta[i]) { if(Key_backup[i] != 0) Key_Deal(); Key_backup[i] = KeySta[i]; } } } } key.c #include "sys.h" //按键扫描 void Key_Scan(void) { u16 i; static u8 keybuff[] = {0xff,0xff,0xff,0xff}; keybuff[0] = (keybuff[0] << 1) | s4; keybuff[1] = (keybuff[1] << 1) | s5; keybuff[2] = (keybuff[2] << 1) | s6; keybuff[3] = (keybuff[3] << 1) | s7; for(i = 0;i < 4;i ++) { if(keybuff[i] == 0xff) //连续扫描8次都是1,16ms内都是弹起状态,按键已松开 { KeySta[i] = 1; } else if(keybuff[i] == 0x00) //连续扫描8次都是0,16ms内都是按下状态,按键已按下 { KeySta[i] = 0; } else //其他状态键值不稳定,不作处理 {} } } //按键处理 void Key_Deal(void) { u8 i; for(i = 0;i < 4;i ++) { if(KeySta[i] == 0) { switch(i) { case 0:Led_dat = 0xfe;Led_flag = 0;break; case 1:Led_dat = 0x7f;Led_flag = 1;break; case 2:Led_flag = 2;break; case 3:Led_flag = 3;break; } } } } led.c #include "sys.h" //点亮LED void Led_illume(u8 dat) { P2 = (P2 & 0x1f) | 0x80; //打开Y4C(LED) P0 = dat; //关闭LED P2 = P2 & 0x1f; } sys.c #include "sys.h" //关闭所有外设 void All_Init(void) { P2 = (P2 & 0x1f) | 0x80; //打开Y4C(LED) P0 = 0xff; //关闭LED P2 = (P2 & 0x1f) | 0xe0; //打开Y7C(数码管) P0 = 0xff; //关闭数码管 P2 = (P2 & 0x1f) | 0xa0; //打开Y5C P0 = 0x00; //关闭蜂鸣器、继电器 } //定时器0初始化 void Time0_Init(void) { AUXR |= 0x80; //定时器时钟1T模式 TMOD &= 0xF0; //设置定时器模式 TL0 = 0x9a; //设置定时初值2ms TH0 = 0xa9; //设置定时初值2ms TF0 = 0; //清除TF0标志 ET0 = 1; //允许定时器0中断 TR0 = 1; //定时器0开始计时 EA = 1; //开总中断 } //定时器0程序 void Time0(void) interrupt 1 { static u16 t0 = 0,m = 0,n = 0; t0 ++; Key_Scan(); if(t0 == 500) { if(Led_flag == 0) Led_dat = _cror_(Led_dat,1); else if(Led_flag == 1) Led_dat = _crol_(Led_dat,1); else if(Led_flag == 2) { switch(m) { case 0:Led_dat = 0x7e;break; case 1:Led_dat = 0xbd;break; case 2:Led_dat = 0xdb;break; case 3:Led_dat = 0xe7;break; } m ++; m = m & 3; //m到4清零 } else if(Led_flag == 3) { switch(n) { case 0:Led_dat = 0xe7;break; case 1:Led_dat = 0xdb;break; case 2:Led_dat = 0xbd;break; case 3:Led_dat = 0x7e;break; } n ++; n = n & 3; //n到4清零 } Led_illume(Led_dat); t0 = 0; } } sys.h #ifndef _SYS_H_ #define _SYS_H_ #ifndef u16 #define u16 unsigned int #endif #ifndef u8 #define u8 unsigned char #endif #include #include //全局变量定义 #define FOSC 11059200L //系统时钟 //外部变量 extern u8 Led_flag; extern u8 Led_dat; extern u8 KeySta[4],Key_backup[4]; //sys.c void All_Init(void); void Time0_Init(void); //led.c void Led_illume(u8 dat); //key.c sbit s4 = P3^3; sbit s5 = P3^2; sbit s6 = P3^1; sbit s7 = P3^0; void Key_Scan(void); void Key_Deal(void); #endif