一、仿真环境
- Proteus8.9
- Keil5
二、Proteus模型搭建
具体过程参考上一篇:
三、软件代码
#include <reg51.h>
#define uchar unsigned char
bit ldelay = 0; // 长定时溢出标记
uchar t = 0; // 定时溢出次数
time0() interrupt 1 // T0中断函数
{
if(++t == 20)
{
t = 0;
ldelay = 1; // 刷新长定时溢出标记
}
TH0 = 0x3c; // 重置T0初值
TL0 = 0xb0;
}
void main()
{
uchar code ledp[8] = {0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f};
uchar ledi; // 指示显示顺序
TMOD = 0x01; // T0,定时器方式,16位
TH0 = 0x3c; // 溢出20次 = 1s(12MHz晶振)
TL0 = 0xb0;
TR0 = 1; // 启动计数
EA = ET0 = 1; // 开T0中断
while(1)
{
if(ldelay) // 发现有时间溢出标记,进入处理
{
ldelay = 0; // 清除标记
P1 = ledp[ledi]; // 读出一个值到P2口
ledi ++; // 指向下一个
if(ledi == 8) // 到最后一个灯后换到第一个
{
ledi = 0;
}
}
}
}
PS:另一种写法:
#include <reg51.h>
#define uchar unsigned char
bit ldelay = 0; // 长定时溢出标记
uchar t = 0; // 定时溢出次数
time0() interrupt 1 // T0中断函数
{
if(++t == 20)
{
t = 0;
ldelay = 1; // 刷新长定时溢出标记
}
TH0 = 0x3c; // 重置T0初值
TL0 = 0xb0;
}
void main()
{
uchar LED = 0xfe;
TMOD = 0x01; // T0,定时器方式,16位
TH0 = 0x3c; // 溢出20次 = 1s(12MHz晶振)
TL0 = 0xb0;
TR0 = 1; // 启动计数
EA = ET0 = 1; // 开T0中断
while(1)
{
if(ldelay) // 发现有时间溢出标记,进入处理
{
ldelay = 0; // 清除标记
LED = (LED >> 7) | (LED << 1); // 可以实现流水灯右移的效果
// LED = (LED >> 1) | (LED << 7); // 可以实现流水灯左移的效果
P0 = LED;
}
}
}
实现流水灯效果还有很多其他方法,这里面只使用两种。
四、仿真结果
1、搭建好的模型:
2、运行效果
test02_LED - Proteus 8.9