C51 动态扫描和定时器
因为迟迟开不了学,只能在家自己学习一点感兴趣的东西。51单片机是本科学过的课程,当时蛮喜欢这门课,还记得当时用的是汇编语言(忘干净了)。如今,有时间,打算用C语言来重新认识单片机和嵌入式。
【C51】单片机定时器介绍
C51中的定时器和计数器是同一个硬件电路支持的,通过寄存器配置不同,就可以将他当做定时器或者计数器使用。定时器和计数器区别是致使他们背后的计数存储器加1的信号不同。当配置为定时器使用时,每经过1个机器周期,计数存储器的值就加1。而当配置为计数器时,每来一个负跳变信号(信号从P3.4 或者P3.5引脚输入),就加1,以此达到计数的目的。
- 时钟周期与机器周期
定时器的本质原理就是:每经过1个机器周期,计数存储器的值就加1。因此当使用定时器时,就必须掌握时钟周期和机器周期的关系。
时钟周期 :晶振频率的倒数。如果使用的是11.0592M的晶振,那么就是 1 / (11.0592x10^6) 秒
机器周期 :标准51下,机器周期 =12倍的时钟周期。即:12 / (11.0592x10^6) 秒 。有的增强51单片机,1个机器周期等于4倍的时钟周期,还有的更短。
经典例题:
利用动态扫描和定时器1在数码管上显示从765432开始以1/10秒的速度往下递减直至765398并保持现实此数,与此同时利用定时器0以500ms速度进行流水灯从上至下移动,当数码管减到停止,试验板流水灯也停止然后开始闪烁,3秒后(T0定时),流水灯全部关闭、数码管上显示HELLO。
1 #include<reg52.h>
2 #include<intrins.h> //_crol_函数
3 typedef unsigned int uint;
4 typedef unsigned char uchar;
5 sbit wela=P2^7;
6 sbit dula=P2^6;
7 uchar code table[]={0x3f,0x06,0x5b,0x4f,
8 0x66,0x6d,0x7d,0x07,
9 0x7f,0x6f,0x77,0x7c,
10 0x39,0x5e,0x79,0x71,
11 0x76,0x79,0x38,0x3f,0};
12 uchar temp,t0,t1,flag,flag1,bai,shi,ge;
13 uint shu;
14
15 void init() ////初始化函数
16 {
17 TMOD=0x11;//定时器工作方式
18 temp=0xfe;//11111110
19 P1=temp;
20 shu=432;
21 TH0=(65536-50000)/256; //50ms中断一次
22 TL0=(65536-50000)%256;
23 TH1=(65536-50000)/256;
24 TL1=(65536-50000)%256;
25 EA=1;
26 ET0=1;
27 ET1=0;
28 TR0=1;
29 TR1=1;
30 }
31 void delay(uint z) //延迟函数
32 {
33 uint x,y;
34 for(x=z;x>0;x--)
35 {
36 for(y=110;y>0;y--);
37 }
38 }
39 void display(uchar aa,uchar bb,uchar cc,uchar bai,uchar shi,uchar ge)
40 {
41 dula=1;
42 P0=table[aa];
43 dula=0;
44 P0=0xff; //送位选数据前关闭所有显示,防止打开位选锁存时原段选数据通过位选锁存器造成混乱
45 wela=1;
46 P0=0xfe;
47 wela=0;
48 delay(5); //延时
49
50 dula=1;
51 P0=table[bb];
52 dula=0;
53 P0=0xff;
54 wela=1;
55 P0=0xfd;
56 wela=0;
57 delay(5);
58
59 dula=1;
60 P0=table[cc];
61 dula=0;
62 P0=0xff;
63 wela=1;
64 P0=0xfb;
65 wela=0;
66 delay(5);
67
68 dula=1;
69 P0=table[bai];
70 dula=0;
71 P0=0xff;
72 wela=1;
73 P0=0xf7;
74 wela=0;
75 delay(5);
76
77 dula=1;
78 P0=table[shi];
79 dula=0;
80 P0=0xff;
81 wela=1;
82 P0=0xef;
83 wela=0;
84 delay(5);
85
86 dula=1;
87 P0=table[ge];
88 dula=0;
89 P0=0xff;
90 wela=1;
91 P0=0xdf;
92 wela=0;
93 delay(5);
94 }
95 int main()
96 {
97 init();
98 while(1)
99 {
100 if(flag1!=1)
101 {
102 display(7,6,5,bai,shi,ge);
103 }
104 else
105 {
106 display(16,17,18,18,19,20);
107 }
108 }
109
110 return 0;
111 }
112 void timer0() interrupt 1 //定时器0
113 {
114 TH0=(65536-50000)/256; //重装初值
115 TL0=(65536-50000)%256;
116 t0++;
117 if(flag!=1)
118 {
119 if(t0==10)
120 {
121 t0= 0;
122 temp=_crol_(temp,1); //左移,流水灯移动
123 P1=temp;
124 }
125 }
126 else
127 {
128 if(t0%4==0)
129 P1=~P1; //取反,流水灯闪烁
130 if(t0==60) //3s后关闭流水灯
131 {
132 TR0=0;
133 P1=0xff;
134 flag1=1;
135 }
136 }
137
138
139 }
140
141 void timer1() interrupt 3 //定时器1
142 {
143 TH1=(65536-50000)/256;
144 TL1=(65536-50000)%256;
145 t1++;
146 if(t1==2)
147 {
148 shu--;
149 bai=shu/100;
150 shi=shu%100/10;
151 ge=shu%10;
152 if(shu==398)
153 {
154 TR0=0;
155 P1=0xff;
156 TH0=(65536-50000)/256;
157 TL0=(65536-50000)%256;
158 TR0=1;
159 flag=1;
160 t0=0;
161 TR1=0;
162 }
163 }
164
165
166 }
单片机显示效果图: