习题:
练习题1:
对于标准型的51单片机,它有两个定时器即定时器0和定时器1。
关于定时器的原理如下:
OSC即为时钟振荡信号,连接后面的即为对时钟进行分频。它的意义是在标准51单片机系统中,一个机器周期为12个时钟周期。而一个机器周期的意义为单片机的CPU执行一条汇编指令所需要的时间。 Tn脚为单片机的另一种功能,该功能常用来测量外部信号的脉冲宽度,这是定时器的一个额外功能,暂不讨论。这两种模式的切换,对应着定时器模式寄存器的值的不同。
对于后面的控制的开关,即对应着定时器的控制寄存器,用来控制定时器的开关。
后面的TLn和THn分别为定时器的数值寄存器,即每过一个机器周期,数值寄存器就会加1。
TFn为溢出标志位,如果两个数值寄存器发生溢出,则该标志位为置1。该标志位不会影响数值寄存器。该溢出标志位可以通过定时器中断或者软件置0来进行改变。
练习题2:
上图即为,定时器的几种不同的工作模式。可以结合技术手册里面的逻辑门电路进行细致的分析,在此不详细阐述。
练习题3:
本题通过实现间隔为1s的流水灯程序来感受定时器的功能。
如何设置TH0和TL0的值实现定时1ms的功能:
该单片机的频率为11.0592MHz,且周期为频率的倒数,所以周期为1/11059200秒,要去判断需要增加多少个机器周期,才能达到1s的间隔,需要将1除以指令周期(时钟周期*12),结果为921600,而使用定时器为两个八位的定时器(TH0和TL0)从0开始需要走65536个机器周期才能溢出。即对于本单片机来讲一次溢出无法实现间隔1s的操作,需要多次溢出才能实现。
具体的次数为:14次(921600/65536=14余数4096)
需要设置TH0和TL0的值:(高八位)TH0=F0 (低八位)TL0=00
代码如下
#include <reg52.h>//包含特殊功能寄存器的头文件
sbit LED=P0^0; //I/O口的位定义
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
unsigned char cnt=0; //流水灯左右移动变量
unsigned char count=0; //定时器溢出计数变量
bit sign=0; //判断是否达到1S的间隔
bit RL=0; //判断左右移动的变量
void main()
{
ENLED=0; //下面这些语句使能3-8译码器,并且打开对应的LED流水灯的总开关
ADDR3=1;
ADDR2=1;
ADDR1=1;
ADDR0=0;
P0=0xff; //使得LED灯全部熄灭
TMOD=0x01; //设置寄存器模式寄存器
TH0=0xf0; //设置寄存器数值寄存器高八位
TL0=0x00; //设置寄存器数值寄存器低八位
TR0=1; //打开寄存器0开关
while(1)
{
if(TF0==1){
TF0=0;
count++;
if(count==15){
sign=1;
count=0;
TH0=0XF0;TL0=0X00;
}else{
TH0=0x0;TL0=0x00;
}
}
if(sign){
sign=0;
if(RL==0){ //左移的变量
P0=~(0x01<<cnt);cnt++;
if(cnt==8){cnt=0;RL=~RL;}
}else{
P0=~(0x80>>cnt);cnt++; //右移的变量
if(cnt==8){cnt=0;RL=~RL;}
}
}
}
}
效果:
流水灯_定时器
练习题4:
以上的图为数码管的原理图,通过分析数码管的内部结构示意图,即可以通过I/O口的位的大小,来改变八段数码管是否发光,来进行显示。具体真值表的计算,可以看原理图来得到点亮哪几个小灯来实现数码管的显示。
练习题5:
具体的代码如下:
#include <reg52.h>//包含特殊功能寄存器的头文件
unsigned char LedChar[]={ //数码管的真值表
0xC0,0XF9,0XA4,0XB0,0X99,
0X92,0X82,0XF8,0X80,0X90
};
sbit LED=P0^0; //I/O口的位定义
sbit ADDR0=P1^0;
sbit ADDR1=P1^1;
sbit ADDR2=P1^2;
sbit ADDR3=P1^3;
sbit ENLED=P1^4;
unsigned char count=0; //定时器溢出计数变量
signed char cnt=9;
bit sign=0; //判断是否达到1S的间隔
void main()
{
ENLED=0; //下面这些语句使能3-8译码器,并且打开对应的LED流水灯的总开关
ADDR3=1;
ADDR2=0;
ADDR1=0;
ADDR0=0;
P0=0xff; //使得数码管的灯全部熄灭
TMOD=0x01; //设置寄存器模式寄存器
TH0=0xf0; //设置寄存器数值寄存器高八位
TL0=0x00; //设置寄存器数值寄存器低八位
TR0=1; //打开寄存器0开关
while(1)
{
if(TF0==1){ //定时器功能,定时1S
TF0=0;
count++;
if(count==15){
sign=1;
count=0;
TH0=0XF0;TL0=0X00;
}else{
TH0=0x0;TL0=0x00;
}
}
if(sign){ //间隔1S进行更换数码管
sign=0;
P0=LedChar[cnt];cnt--;
if(cnt==-1)cnt=9;
}
}
}
效果:
数码管静态显示倒计时