#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};
//变量
uchar Count,Number;
//延时(软件延时)
void DelayMS(uint ms)
{
uchar t;
while(ms--)
for(t=0;t<60;t++);
}
//主程序
void main()
{
P0=0xff;
Count=0;
Number=0;
TMOD=0x01;
//12MHZ晶振 C51单片机对其12分频
//实际定时器“加1”频率为1MHZ 也就是1us
//用定时器中断时间间隔 是从“开启定时器加1”到“溢出”的时间
//对于工作在模式1的定时器0来说 也就是从“开启定时器加1”到“(TH0 TL0)=(0xff 0xff)+1”的时间
//0xffff+1=65536
//如果(TH0 TL0)初始值是(65536-50000) 那么初始值到溢出需要“加1”50000次
//1次是1us 50000次就是50000us=50ms
//如果我们对定时器的中断次数进行计数,每20次算作一个时间段,那么这样的一个时间段就是20*50ms = 1000ms = 1s
//这就是利用定时器计时的原理
//因为TH0和TL0分别是高字节和低字节,所以赋初值时也要将(65536-50000)分成高低字节分别赋值给TH0和TL0
//高字节 是除以256后的到的商 低字节 是除以256后的到的余数
//另外,因为在模式1中,每次定时器溢出后,单片机不会自动对TH0和TL0重新赋值
//所以每当定时器中断,我们都要首先对TH0和TL0人工重新赋值
TH0=(65536-50000)/256;//50ms 定时
TL0=(65536-50000)%256;
ET0=1;
EA=1;
TR0=1;//启动T0
while(1)
{
//显示
P0=0xff;
P1=0x80;
//判断对应位是不是1
//是1 输出1的数码管段码
//不是1 则是0 输出0的数码管段码
if(Number&0x01) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
P0=0xff;
P1=0x40;
if(Number&0x02) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
P0=0xff;
P1=0x20;
if(Number&0x04) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
P0=0xff;
P1=0x10;
if(Number&0x08) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
P0=0xff;
P1=0x08;
if(Number&0x10) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
P0=0xff;
P1=0x04;
if(Number&0x20) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
P0=0xff;
P1=0x02;
if(Number&0x40) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
P0=0xff;
P1=0x01;
if(Number&0x80) P0=~0x06;
else P0=~0x3f;
DelayMS(10);
}
}
//T0 中断函数
void Int_T0() interrupt 1
{
//另外,因为在模式1中,每次定时器溢出后,单片机不会自动对TH0和TL0重新赋值
//所以每当定时器中断,我们都要首先对TH0和TL0人工重新赋值
TH0=(65536-50000)/256;// 恢复初值
TL0=(65536-50000)%256;
//Count每中断一次加1 以20为周期 每当等于20时候说明1s到了
if(++Count==20)
{
Count=0;
Number++;
}
}
//12MHZ晶振 C51单片机对其12分频
//实际定时器“加1”频率为1MHZ 也就是1us
//用定时器中断时间间隔 是从“开启定时器加1”到“溢出”的时间
//对于工作在模式1的定时器0来说 也就是从“开启定时器加1”到“(TH0 TL0)=(0xff 0xff)+1”的时间
//0xffff+1=65536
//如果(TH0 TL0)初始值是(65536-50000) 那么初始值到溢出需要“加1”50000次
//1次是1us 50000次就是50000us=50ms
//如果我们对定时器的中断次数进行计数,每20次算作一个时间段,那么这样的一个时间段就是20*50ms = 1000ms = 1s
//这就是利用定时器计时的原理
//因为TH0和TL0分别是高字节和低字节,所以赋初值时也要将(65536-50000)分成高低字节分别赋值给TH0和TL0
//高字节 是除以256后的到的商 低字节 是除以256后的到的余数
//另外,因为在模式1中,每次定时器溢出后,单片机不会自动对TH0和TL0重新赋值//所以每当定时器中断,我们都要首先对TH0和TL0人工重新赋值
//当数码管显示时判断对应位是不是1
//是1 输出1的数码管段码
//不是1 则是0 输出0的数
//在程序中利用Count记录中断的次数
//Count每中断一次加1 以20为周期 每当等于20时候说明1s到了
追问亲,我要的是 8盏LED灯来显示呀 不是用LCD液晶显示 呀 另外 必须用定时器方法实现 不可以有delay的延迟程序
追答
上面的程序是用LED数码管显示,因为多位数码管需要扫描显示,所以用了软件延时DelayMS()使每位数码管显示一段时间。
Number的加1操作还是按着定时器中断进行的。
如果驱动发光二极管的话,直接将Number赋值给Px口就可以了。如果用P0口直接控制发光二极管的话,要加上拉排阻。
新程序在baidu+.c里。程序里用的P1。