蓝桥杯(6)——独立按键和流水灯

版权声明:让结局不留遗憾,让过程更加完美。 https://blog.csdn.net/Xiaomo_haa/article/details/86669517

用独立按键控制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 <STC15F2K60S2.H>
#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 <stc15f2k60s2.h>
#include <intrins.h>

//全局变量定义
#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

猜你喜欢

转载自blog.csdn.net/Xiaomo_haa/article/details/86669517