用独立按键控制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