如果你觉得我写得好,一定要顶我一下吆!
今天,我们来做霓虹灯.什么是霓虹灯,就是一个灯闪来闪去就是了.有人说,我会做我会做:
for(;;)
{
P0^0=!P0^0;
delay();
}
这样就解决了嘛.对,你说的对,这样的确就达到霓虹灯的效果了.不过,我们今天的霓虹灯可不要用延时(以上程序中的delay()函数)来完成,今天的霓虹灯我们要用定时计数器来完成.
对于很多地方,定时/计数器还是作用巨大的.可以说,定时计数器是单片机的精华之一.比如说计数,定时,甚至PWM,串行通信等等.都来不开定时计数器.
相信大家看这方面的东西都看烦了,那剩下的,就把课本扔掉,我们开始做吧!
首先,我们来看看查询模式下的定时计数器使用:
#include <reg51.h>
void main()
{
TMOD=0x01; //定时器0工作在方式1--16位计数器
TL0=0; //定时器初值设定为0
TH0=0;
TR0=1; //定时器0开始运行--Timer0 Run.
for(;;)
{
if(TF0==1) //如果定时器0发生溢出
{
P0=~P0;
TF0=0;
}
}
}
上面这个是采用的查询方式,就是在主循环里面不断的查询,计数器从0开始计数,有没有超过65536而溢出,一旦溢出,溢出标志位TF0就会被置1,通过这样的方法,可以起到定时作用.有人问,如果我要定时的时间更短,我怎么设定呢,很简单,51单片机的定时计数器是累加计数器.你给他一个初值,他就会一直作累加运算.现在的初值是0.那你如果把初值设置成30000,那么,是不是计数器就从30000开始计数,到65536溢出,是不是时间就变了?你需要多长时间你都可以算的出来.有人又有问题了,那如果我需要的时间比从0开始的计数时间都要长,我怎么办?那怎么不好办?你把你的这个长时间分成多个小时间块,让计数器计数这些小时间块,你只要数到规定的个数就触发一次自己的事件不就OK.给你举个例子:
unsigned char Count ;//申请一个变量用来计数.
for(;;)
{
if(TF0==1) //如果定时器0发生溢出
{
Count++;
if(Count= =10)
{
//在这里放置你的代码.
Count="0"; //不要忘了清零Count,继续下一个周期.
}
TF0=0;
}
}
好了,相信到这里,大家对计数器有了一点了解了.我们再继续吧,开始中断模式下的霓虹灯:
#include <reg51.h>
void main()
{
TMOD="0x01"; //定时器0工作在方式1--16位计数器
TL0=0; //定时器初值设定为0
TH0=0;
EA=1; //CPU开中断,CPU允许中断.
ET0=1; //定时器0允许中断
TR0=1; //定时器0开始运行--Timer0 Run.
for(;;){}
}
void TimerOverflow() interrupt 1 //中断处理子程序
{
P0=~P0;
TF0=0; //不要忘了清除标志位.
}
相信这个程序大家看起来也不会难,就是有一点可能有疑问,就是中断处理子程序的格式:
voide Timer() interrupt 1
前面和普通的函数一样的写,没有任何区别,爱起什么名字就什么名字.但是后面的interrupt 1确实固定的.1是中断号,代表着定时计数器0的中断:
0 外部中断0
1 定时器0 溢出
2 外部中断1
3 定时器1 溢出
4 串行口中断
5 定时器2 溢出
在写不同的中断函数时候,只要在interrupt 后面写上不同的中断号就可以实现不同功能中段函数的编写.
由于运行后的结果太简单了,就是和P0接口连接的发光二极管不停的闪烁,所以就不做视频了.祝大家好运吧!
用户767405 2008-11-29 12:48