资源描述
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED=P0^0;
uchar T_Count=0;
void main()
{ TMOD=0x00; //定时器 0 工作方式 0
TH0=(8192-5000)/32; //5ms 定时
TL0=(8192-5000)%32;
IE=0x82; //允许 T0 中断
TR0=1;
while(1); } //T0 中断函数
void LED_Flash() interrupt 1 {
TH0=(8192-5000)/32; //恢复初值
TL0=(8192-5000)%32;
if(++T_Count==100) //0.5s 开关一次 LED
{
LED=~LED;
T_Count=0; } }
28 TIMER0 控制流水灯
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
void main() {
uchar T_Count=0;
P0=0xfe;
P2=0xfe;
TMOD=0x01; //定时器 0 工作方式 1
TH0=(65536-40000)/256; //40ms 定时
TL0=(65536-40000)%256;
TR0=1; //启动定时器
while(1) {
if(TF0==1)
{
TF0=0;
TH0=(65536-40000)/256; //恢复初值
TL0=(65536-40000)%256;
if(++T_Count==5)
{ P0=_crol_(P0,1);
P2=_crol_(P2,1); T_Count=0;
} } } }
29 定时器控制 4 个 LED 滚动闪烁
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit B1=P0^0;
sbit G1=P0^1;
sbit R1=P0^2;
sbit Y1=P0^3;
uint i,j,k;
//主程序
void main() {
i=j=k=0;
P0=0xff;
TMOD=0x02; //定时器 0 工作方式 2
TH0=256-200; //200us 定时
TL0=256-200;
IE=0x82;
TR0=1; //启动定时器
while(1);
}
//T0 中断函数
void LED_Flash_and_Scroll() interrupt 1
{
if(++k<35) return; //定时中断若干次后执行闪烁
k=0;
switch(i)
{
case 0: B1=~B1;break;
case 1: G1=~G1;break;
case 2: R1=~R1;break;
case 3: Y1=~Y1;break;
default:i=0;
}
if(++j<300) return; //每次闪烁持续一段时间
j=0;
P0=0xff; //关闭显示
i++; //切换到下一个 LED }
30 T0 控制 LED 实现二进制计数
#include<reg51.h>
//主程序
void main() {
TMOD=0x05; //定时器 0 为计数器,工作方式 1,最大计数值 65535
TH0=0; //初值为 0
TL0=0;
TR0=1; //启动定时器
while(1) {
P1=TH0;
P2=TL0; } }
31 TIMER0 与 TIMER1 控制条形 LED
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar tc0=0,tc1=0;
//主程序
void main()
{
P0=0xfe;
P2=0xfe;
TMOD=0x11; //定时器 0、定时器 1 均工作于方式 1
TH0=(65536-15000)/256; //定时器 0:15ms
TL0=(65536-15000)%256;
TH1=(65536-50000)/256; //定时器 1:50ms
TL1=(65536-50000)%256;
IE=0x8a;
TR0=1; //启动定时器
TR1=1;
while(1); }
//T0 中断函数
void Time0() interrupt 1 {
TH0=(65536-15000)/256; //恢复定时器 0 初值
TL0=(65536-15000)%256;
if(++tc0==10) //150ms 转换状态 {
tc0=0;
P0=_crol_(P0,1); } }
//T1 中断函数
void Time1() interrupt 3 {
TH0=(65536-50000)/256; //恢复定时器 1 初值
TL0=(65536-50000)%256;
if(++tc1==10) //500ms 转换状态 { tc1=0;
P2=_crol_(P2,1); } }
32 10s 的秒表
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit K1=P3^7;
uchar
i,Second_Counts,Key_Flag_Idx;
bit Key_State;
uchar
DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//延时
void DelayMS(uint ms) { uchar t;
while(ms--) for(t=0;t<120;t++); }
//处理按键事件
void Key_Event_Handle() {
if(Key_State==0) {
Key_Flag_Idx=(Key_Flag_Idx+1)%3;
switch(Key_Flag_Idx) {
case 1: EA=1;ET0=1;TR0=1;break;
case 2: EA=0;ET0=0;TR0=0;break;
case 0: P0=0x3f;P2=0x3f;i=0;Second_Counts=0; } } }
//主程序
void main() { P0=0x3f; //显示 00
P2=0x3f;
i=0;
Second_Counts=0;
Key_Flag_Idx=0; //按键次数(取值 0,1,2,3)
Key_State=1; //按键状态
TMOD=0x01; //定时器 0 方式 1
TH0=(65536-50000)/256; //定时器 0:50ms
TL0=(65536-50000)%256;
while(1) { if(Key_State!=K1) {
DelayMS(10);
Key_State=K1;
Key_Event_Handle(); } } }
//T0 中断函数
void DSY_Refresh() interrupt 1 {
TH0=(65536-50000)/256; //恢复定时器 0 初值
TL0=(65536-50000)%256;
if(++i==2) //50ms*2=0.1s 转换状态 { i=0;
Second_Counts++;
P0=DSY_CODE[Second_Counts/10];
P2=DSY_CODE[Second_Counts%10];
if(Second_Counts==100) Second_Counts=0; //满 100(10s)后显示 00 } }
33 用计数器中断实现 100 以内的按键计数
#include<reg51.h>
#define uchar unsigned char
#define uint unsigned int
//段码
uchar code
DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
uchar Count=0;
//主程序
void main() {
P0=0x00;
P2=0x00;
TMOD=0x06; //计数器 T0 方式 2
TH0=TL0=256-1; //计数值为 1
ET0=1; //允许 T0 中断
EX0=1; //允许 INT0 中断
EA=1; //允许 CPU 中断
IP=0x02; //设置优先级,T0 高于 INT0
IT0=1; //INT0中断触发方式为下降沿触发
TR0=1; //启动 T0
while(1)
{
P0=DSY_CODE[Count/10];
P2=DSY_CODE[Count%10];
}
}
//T0 计数器中断函数
void Key_Counter() interrupt 1
{
Count=(Count+1)%100; //因为只有两位数码管,计数控制在 100 以内(00~99)
}
//INT0 中断函数
void Clear_Counter() interrupt 0
{
Count=0;
}
34 100 000s 以内的计时程序
/* 名称:100 000s 以内的计时程序
说明:在 6 只数码管上完成 0~99 999.9s。
*/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//段码
uchar code
DSY_CODE[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//6 只数码管上显示的数字
uchar Digits_of_6DSY[]={0,0,0,0,0,0};
uchar Count;
sbit Dot=P0^7;
//延时
void DelayMS(uint ms)
{
uchar t;
while(ms--) for(t=0;t<120;t++);
}
//主程序
void main()
{
uchar i,j;
P0=0x00;
P3=0xff;
Count=0;
TMOD=0x01; //计数器 T0 方式 1
TH0=(65536-50000)/256; //50ms 定时
TL0=(65536-50000)%256;
IE=0x82;
TR0=1; //启动 T0
while(1)
{
j=0x7f;
//显示 Digits_of_6DSY[5]~Digits_of_6DSY[0]的内容
//前面高位,后面低位,循环中 i!=-1 亦可写成 i!=0xff
for(i=5;i!=-1;i--)
{
j=_crol_(j,1);
P3=j;
P0=DSY_CODE[Digits_of_6DSY[i]];
if(i==1) Dot=1; //加小数点
DelayMS(2);
}
}
}
//T0 中断函数
void Timer0() interrupt 1
{
uchar i;
TH0=(65536-50000)/256; //恢复初值
TL0=(65536-50000)%256;
if(++Count!=2) return;
Count=0;
Digits_of_6DSY[0]++; //0.1s 位累加
for(i=0;i<=5;i++) //进位处理
{
if(Digits_of_6DSY[i]==10)
{
Digits_of_6DSY[i]=0;
if(i!=5) Digits_of_6DSY[i+1]++; //如果 0~4 位则分别向高一位进位
}
else break; //若某低位没有进位,怎循环提前结束
}
}
35 定时器控制数码管动态显示
/* 名称:定时器控制数码管动态
显示
说明:8 个数码管上分两组动
态显示年月日与时分秒,本例的
位显示延时用定时器实现。
*/
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
//段码,最后一位是“-”的段码
uchar code
DSY_CODE[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf};
//待显示的数据:09-12-25 与 23-59-58(分两组显示)
uchar code Table_of_Digits[][8]={{0,9,10,1,2,10,2,5},{2,3,10,5,9,10,5,8}};
uchar i,j=0;
uint t=0;
//主程序
void main()
{
P3=0x80; //位码初值
TMOD=0x00; //计数器 T0 方式 0
TH0=(8192-4000)/32; //4ms 定时
TL0=(8192-4000)%32;
IE=0x82;
TR0=1; //启动 T0
while(1);
}
//T0 中断函数控制数码管刷新显示
void DSY_Show() interrupt 1
{
TH0=(8192-4000)/32; //恢复初值
TL0=(8192-4000)%32;
P0=0xff; //输出位码和段码
P0=DSY_CODE[Table_of_Digits[i][j]];
P3=_crol_(P3,1);
j=(j+1)%8; //数组第 i 行的下一字节索引
if(++t!=350) return; //保持刷新一段时间
t=0;
i=(i+1)%2; //数组行 i=0 时显示年月日,i=1 时显示时分秒
展开阅读全文