|
一、基本要求:
使用8051,要求系统电路含有16个led灯和按键,按键控制灯的不同闪烁方式(跑马灯),按键使用中断方式,使用定时器T1方式1实现一个心跳灯,中断方式,在Proteus上仿真实现。
二 、具体功能:
1.选择两个I/O端口控制16个LED流水灯。
2.设置四个按键K1~K4,按下K1跑马灯,K2鸳鸯戏水,K3双流水灯,K4则循环三种控制方式。
3.跑马灯:共16个LED逐次点亮,每隔10ms点亮一个LED,点亮10ms后关闭,然后继续上次操作。
4.鸳鸯戏水灯:第一次单数灯点亮,延时10ms,关闭,然后双数灯点亮,延时10ms,关闭,然后继续上次操作。
5.双流水灯:16个LED依次向中间点亮,间隔10ms,再依次向两边扩散点亮,间隔10ms,然后继续上次操作。
三、控制电路介绍
16个发光二极管L1-L16分别接在单片机P0.0-P0.7,P2.0-P2.7。输出“0”,发光二极管亮。
四、系统程序
#include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit K1 = P1 ^0;//按钮
sbit K2 = P1 ^1;
sbit K3 = P1 ^2;
sbit K4 = P1 ^3;
sbit XTD = P3 ^3; //P3.3引脚作为心跳灯的控制信号
u8 mode = 0;//模式。0跑马灯、1鸳鸯灯、2双流水灯
u8 time = 0;//
u8 done = 0;
u8 time1 = 0;//
u8 times = 0;//计数
u8 flag = 0;//鸳鸯灯标志
void delay(u16 i) // delay延时函数 i=1时,大约延时10us
{
while (i--);
}
/*******************************************************************************
* 函 数 名 : Timer1Init
* 函数功能 : 定时器1初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer1Init() {
TMOD |= 0X10;//选择为定时器1模式,工作方式1,仅用TR1打开启动。
TH1 = 0XD8; //给定时器赋初值,定时10ms
TL1 = 0XF0;
ET1 = 1;//打开定时器1中断允许
EA = 1;//打开总中断
TR1 = 1;//打开定时器
}
/*******************************************************************************
* 函 数 名 : main
* 函数功能 : 主函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void main() {
Timer1Init(); //定时器1初始化
while (1) {
if (!K1)//跑马灯
{
mode = 0;
times = 0;
while (!K1);
}
if (!K2)//鸳鸯灯
{
mode = 1;
times = 0;
while (!K2);
}
if (!K3)//双流水灯
{
mode = 2;
times = 0;
while (!K3);
}
if (!K4)//轮询
{
while (!K4) {
while (!done) mode = 0;
done = 0;
while (!done) mode = 1;
done = 0;
while (!done) mode = 2;
done = 0;
}
}
}
}
/*******************************************************************************
* 函 数 名 : void Timer1() interrupt 3
* 函数功能 : 定时器0中断函数
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void Timer1() interrupt 3 {
TH1 = 0XD8; //给定时器赋初值,定时10ms
TL1 = 0XF0;
if (time1 < 60) {
time1++;
} else {
time1 = 0;
XTD = ~XTD;
}
if (time < 30)//300ms
{
time++;
} else {
time = 0;
if (times < 17)
times++;
else{
times = 0;
done = 1;
}
switch (mode) {
case 0: //跑马灯
if ((times > 0) && (times < 9)) {
P0 = ~(1 << (times - 1));
P2 = 0xff;
}
if ((times > 8) && (times < 17)) {
P2 = ~(1 << (times - 9));
P0 = 0xff;
}
if ((times == 0) || (times == 17)) {
P0 = 0xff;
P2 = 0xff;
}
break;
case 1://鸳鸯灯
if ((times > 0) && (times < 5)) {
P0 = ~(1 << (2 * times - 2));
P2 = 0xff;
}
if ((times > 4) && (times < 9)) {
P2 = ~(1 << (2 * (times - 4) - 2));
P0 = 0xff;
}
if ((times > 9) && (times < 14)) {
P0 = ~(1 << (2 * (times - 9) - 1));
P2 = 0xff;
}
if ((times > 13) && (times < 18)) {
P2 = ~(1 << (2 * (times - 13) - 1));
P0 = 0xff;
}
if ((times == 0) || (times == 9)) {
P0 = 0xff;
P2 = 0xff;
}
break;
case 2://双流水灯
if ((times > 0) && (times < 9)) {
P0 = ~(1 << (times - 1));
P2 = ~(0x80 >> (times - 1));
}
if ((times > 9) && (times < 18)) {
P2 = ~(1 << (times - 9));
P0 = ~(0x80 >> (times - 9));
}
if (times == 0) {
P0 = 0xff;
P2 = 0xff;
}
}
}
}
//void Timer0Init() //定时器0初始化
//{
// TMOD|=0X10; //选择为定时器1模式,工作方式1,仅用TR1打开启动。
// TH0=0XFC; //系统为=采用33MHZ晶振,分频系数为12,则定时脉冲周期为0.363636……us
// TL0=0X18; //1ms=2750*0.363636……us则给定时器赋初值655536-2750=62786=F542H,定时1ms
//
// EA=1; //打开总中断
// ET0=1; //打开定时器1中断允许
// TF0=1; //打开定时器1溢出标志位,产生溢出后,会向CPU申请中断
// TR0=1; //打开定时器
//
//}
//void timer0() interrupt 0 //定时器1中断函数
//{
// TH0=0XFC; //由于方式1不会自动重装,因此要在溢出后重装
// TL0=0X18;
// XTD=~XTD;
// delay(20000);
//}
|
|