我们采用定时器实现流水灯的程序设计。
/*************************************/
//定时器初始化 ,50000微秒中断
/*************************************/
void Timer0_Init( )
{
TMOD = TMOD | 0x01;
TH0 = 0x3C;
TL0 = 0xB0;
EA =1;
ET0 =1;
TR0 =1;
}
/*************************************/
//定时器串口中断程序
/*************************************/
void Timer0_isr( ) interrupt 1
{
static unsigned count=0;
static unsigned i=0;
TH0 = 0x3C;
TL0 = 0xB0;
count ;
if(count>=20)
{
i ;
if(i==8)
i=0;
P1 = 1<<i;< p="">
count =0;
}
}
}
ledRunCount ;
if(ledRunCount>1000)
{
LED1=~LED1;
ledRunCount=0;
}
}
void main()
{
Timer0_Init( );
while(1)
{
}
}
以上代码未经测试,我们希望完成一流水灯实验。在 函数Timer0_Init( )执行结束后即完成了定时器的初始化。TH0 = 0x3C; TL0 = 0xB0;向定时器的计数寄存器赋写初值。寄存器TH0、TL0每个指令周期增加1,如果我们使用12M晶振作为。一个指令周期刚好是1微妙。我们将定时器的中断周期设计为50微秒。所以应该是65536-50000=15536。转换为16进制是0x3CB0。每次进入中断程序后我们都将TH0、TL0赋为初值。以保证下次再次进入中断程序时间间隔是50微秒。
在中断程序中count是一个静态,每次进入中断程序count都会假1,当count等于20时都会改变P1端口电平,也就流水灯的显示。也就没进入20次中断改变一次LED的显示。20*50毫秒=1秒。也就每1秒改变一次流水灯显示。
使用定时器来实现流水灯的好处是定时非常准确。因为定时器依据时钟。而且我们看到主程序是空的。也就是说在主程序可以完成其他事情。
因为流水灯代码非常少,所以直接写在了定时器中断程序中。一般在中断程序中尽量乣写太多代码。以免在程序在中断程序中过多的停留。造成串口丢失数据。如果任务太多。一般在中断程序中置一个标志位。主程序通过标志位判断是否执行任务。