📄 ds1302.lst
字号:
C51 COMPILER V7.20 DS1302 01/17/2007 01:01:13 PAGE 1
C51 COMPILER V7.20, COMPILATION OF MODULE DS1302
OBJECT MODULE PLACED IN DS1302.OBJ
COMPILER INVOKED BY: d:\Keil\C51\BIN\C51.EXE DS1302.C BROWSE DEBUG OBJECTEXTEND
line level source
1 /***************************************************************
2
3 DS1302实时时钟实验
4 网址:http://www.kaifaban.com
5
6 功能:在数码管上显示从DS1302读取的时间日期星期数据
7 时间格式:时-分-秒
8 日期格式:年月日-星期
9 S1:选择显示时间还是日期
10 S2:循环选择所要编辑的位
11 S3:编辑的位的数值加1
12 S4:编辑的位的数值减1
13
14
15 ****************************************************************/
16 #include <reg52.h>
17 #include <intrins.h>
18 #define uchar unsigned char
19 uchar Code[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; //共阳数码管编码表
20 sbit DsySelect=P3^6; //控制数码管的74HC244所在IO口
21 uchar BitCode=0x80; //数码管位码初值
22 uchar DS1302[8]={0,0,0,0,0,0,0,0}; //秒,分,时,日,月,星期,年
23 uchar DateBit[8]={0,0,0,0,0,0,10,0}; //日期各位显示的数值
24 uchar TimeBit[8]={0,0,10,0,0,10,0,0}; //时间各位显示的数值
25 sbit DATA=P1^1; //数据传送总线
26 sbit SCLK=P1^0; //时钟控制总线
27 sbit RST=P1^2; //复位总线
28 sbit S1=P3^4; //S1输入口
29 sbit S2=P3^5; //S2输入口
30 sbit S3=P3^2; //S3输入口
31 sbit S4=P3^3; //S4输入口
32 uchar TimeFlag=0; //显示日期时间标志
33 uchar EditFlag=0; //闪烁显示标志
34 uchar S2Num=0; //S2按的次数
35 uchar num=0;
36 //向DS1302写一字节数据,address为命令字节
37 void WriteByte(uchar Command,uchar WriteData){
38 1 uchar j,k=1;
39 1 RST=0;
40 1 SCLK=0;
41 1 RST=1;
42 1 for(j=0;j<=7;j++){
43 2 if(Command&k) DATA=1;
44 2 else DATA=0;
45 2 SCLK=1;
46 2 k<<=1;
47 2 SCLK=0;
48 2 }
49 1 k=1;
50 1 for(j=0;j<=7;j++){
51 2 if(WriteData&k) DATA=1;
52 2 else DATA=0;
53 2 SCLK=1;
54 2 k<<=1;
55 2 SCLK=0;
C51 COMPILER V7.20 DS1302 01/17/2007 01:01:13 PAGE 2
56 2 }
57 1 RST=0;
58 1 }
59 //读取DS1302一字节数据,address为命令字节
60 uchar ReadByte(uchar Command){
61 1 uchar i,k=1;
62 1 RST=0;
63 1 SCLK=0;
64 1 RST=1;
65 1 for(i=0;i<8;i++){
66 2 if(Command&k) DATA=1;
67 2 else DATA=0;
68 2 SCLK=1;
69 2 k<<=1;
70 2 if(i!=7) SCLK=0;
71 2 }
72 1 k=0;
73 1 for(i=0;i<8;i++){
74 2 k>>=1;
75 2 SCLK=0;
76 2 if(DATA) k|=0x80;
77 2 SCLK=1;
78 2 }
79 1 RST=0;
80 1 return(k);
81 1 }
82 //延时程序
83 void delay(uchar ms){
84 1 uchar i;
85 1 while(ms--){
86 2 for(i=0;i<125;i++);
87 2 }
88 1 }
89 //扫描显示程序
90 void Display(){
91 1 uchar i;
92 1 for(i=0;i<8;i++){
93 2 if(EditFlag&&S2Num>0){ //判断是否闪烁
94 3 if(TimeFlag){ //判断日期还是时间闪烁
95 4 switch(S2Num){ //根据S2按的次数判断日期那一位闪烁
96 5 case 1:P2=BitCode&0x3F;break;
97 5 case 2:P2=BitCode&0xCF;break;
98 5 case 3:P2=BitCode&0xF3;break;
99 5 case 4:P2=BitCode&0xFE;break;
100 5 }
101 4 }else{
102 4 switch(S2Num){ //根据S2按的次数判断时间那一位闪烁
103 5 case 1:P2=BitCode&0x3F;break;
104 5 case 2:P2=BitCode&0xE7;break;
105 5 case 3:P2=BitCode&0xFC;break;
106 5 }
107 4 }
108 3 }else{
109 3 P2=BitCode; //输出位码
110 3 }
111 2 if(TimeFlag) P0=Code[DateBit[i]]; //判断显示时间还是日期
112 2 else
113 2 P0=Code[TimeBit[i]];
114 2 BitCode=_cror_(BitCode,1); //位码循环右移一位
115 2 delay(1); //延时1ms
116 2 P0=0xFF;
117 2 }
C51 COMPILER V7.20 DS1302 01/17/2007 01:01:13 PAGE 3
118 1 }
119 //时间编辑程序
120 void TimeEdit(uchar flag){
121 1 uchar Data,NowData;
122 1 if(flag){ //判断加1还是减1
123 2 switch(S2Num){ //判断编辑时间的哪一位
124 3 case 1:{
125 4 Data=ReadByte(0x85); //读取小时数据
126 4 NowData=Data+1;
127 4 if((NowData&0x0F)>9) NowData=NowData+6;
128 4 if(NowData>=0x24) NowData=0;
129 4 WriteByte(0x84,NowData); //写入小时数据
130 4 break;
131 4 }
132 3 case 2:{
133 4 Data=ReadByte(0x83); //读取分数据
134 4 NowData=Data+1;
135 4 if((NowData&0x0F)>9) NowData=NowData+6;
136 4 if(NowData>=0x60) NowData=0;
137 4 WriteByte(0x82,NowData); //写入分数据
138 4 break;
139 4 }
140 3 case 3:{
141 4 Data=ReadByte(0x81); //读取秒数据
142 4 NowData=Data+1;
143 4 if((NowData&0x0F)>9) NowData=NowData+6;
144 4 if((NowData&0x7F)>=0x60) NowData=0;
145 4 WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //写入秒数据
146 4 break;
147 4 }
148 3 }
149 2 }else{
150 2 switch(S2Num){ //判断编辑时间的哪一位
151 3 case 1:{
152 4 Data=ReadByte(0x85); //读取小时数据
153 4 if(Data==0){
154 5 NowData=0x23;
155 5 }else{
156 5 NowData=Data-1;
157 5 if((NowData&0x0F)>9) NowData=NowData-6;
158 5 }
159 4 WriteByte(0x84,NowData); //写入小时数据
160 4 break;
161 4 }
162 3 case 2:{
163 4 Data=ReadByte(0x83); //读取分数据
164 4 if(Data==0){
165 5 NowData=0x59;
166 5 }else{
167 5 NowData=Data-1;
168 5 if((NowData&0x0F)>9) NowData=NowData-6;
169 5 }
170 4 WriteByte(0x82,NowData); //写入分数据
171 4 break;
172 4 }
173 3 case 3:{
174 4 Data=ReadByte(0x81); //读取秒数据
175 4 if(Data==0){
176 5 NowData=0x59;
177 5 }else{
178 5 NowData=Data-1;
179 5 if((NowData&0x0F)>9) NowData=NowData-6;
C51 COMPILER V7.20 DS1302 01/17/2007 01:01:13 PAGE 4
180 5 }
181 4 WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //写入秒数据
182 4 break;
183 4 }
184 3 }
185 2 }
186 1 }
187 //日期编辑程序
188 void DateEdit(uchar flag){
189 1 uchar Data,NowData;
190 1 if(flag){ //判断加1还是减1
191 2 switch(S2Num){ //判断编辑日期的哪一位
192 3 case 1:{ //年加1
193 4 Data=ReadByte(0x8d); //读取年数据
194 4 NowData=Data+1; //年加1
195 4 if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整
196 4 if(NowData>=0xA0) NowData=0; //年>=100时,年=0
197 4 WriteByte(0x8c,NowData); //年写入DS1302
198 4 break;
199 4 }
200 3 case 2:{
201 4 Data=ReadByte(0x89); //读取月数据
202 4 NowData=Data+1; //月加1
203 4 if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整
204 4 if(NowData>=0x13) NowData=1; //月>=13,月=1
205 4 WriteByte(0x88,NowData); //月写入DS1302
206 4 break;
207 4 }
208 3 case 3:{
209 4 Data=ReadByte(0x87); //读取日数据
210 4 NowData=Data+1; //日加1
211 4 if((NowData&0x0F)>9) NowData=NowData+6; //BCD调整
212 4 if(NowData>=0x32) NowData=1; //日>=32,日=1
213 4 WriteByte(0x86,NowData); //日写入DS1302
214 4 break;
215 4 }
216 3 case 4:{
217 4 Data=ReadByte(0x8B); //读取星期数据
218 4 NowData=Data+1; //星期加1
219 4 if(NowData>=8) NowData=1; //星期>=8,星期=1
220 4 WriteByte(0x8A,NowData); //星期写入DS1302
221 4 break;
222 4 }
223 3 }
224 2 }else{
225 2 switch(S2Num){
226 3 case 1:{ //年减1
227 4 Data=ReadByte(0x8d); //读取年数据
228 4 if(Data==0){
229 5 NowData=0x99; //如果年=0,减1则为99
230 5 }else{
231 5 NowData=Data-1; //年减1
232 5 if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整
233 5 }
234 4 WriteByte(0x8c,NowData); //年写入DS1302
235 4 break;
236 4 }
237 3 case 2:{
238 4 Data=ReadByte(0x89); //读取月数据
239 4 NowData=Data-1; //月减1
240 4 if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整
241 4 if(NowData==0) NowData=0x12; //月=0,月=12
C51 COMPILER V7.20 DS1302 01/17/2007 01:01:13 PAGE 5
242 4 WriteByte(0x88,NowData); //月写入DS1302
243 4 break;
244 4 }
245 3 case 3:{
246 4 Data=ReadByte(0x87); //读取日数据
247 4 NowData=Data-1; //日减1
248 4 if((NowData&0x0F)>9) NowData=NowData-6; //BCD调整
249 4 if(NowData==0) NowData=0x31; //日=0,日=31
250 4 WriteByte(0x86,NowData); //日写入DS1302
251 4 break;
252 4 }
253 3 case 4:{
254 4 Data=ReadByte(0x8B); //读取星期数据
255 4 NowData=Data-1; //星期减1
256 4 if(NowData==0) NowData=7; //星期=0,星期=7
257 4 WriteByte(0x8A,NowData); //星期写入DS1302
258 4 break;
259 4 }
260 3 }
261 2 }
262 1 }
263 //按钮功能函数
264 void KeyFun(uchar key){
265 1 ET0=0;
266 1 switch(key){
267 2 case 0x0E:{ //S1按下,切换显示日期还是时间
268 3 TimeFlag=~TimeFlag;
269 3 S2Num=0;
270 3 break;
271 3 }
272 2 case 0x0D:{ //S2按下,S2Num加1
273 3 S2Num++;
274 3 if((TimeFlag>0)&&(S2Num>=5)) S2Num=0; //如果当前编辑的是日期并且S2Num>=5,则编辑完毕,返回正常状态
275 3 if((TimeFlag==0)&&(S2Num>=4)) S2Num=0; //如果当前编辑的是时间并且S2Num>=4,则编辑完毕,返回正常状态
276 3 break;
277 3 }
278 2 case 0x0B:{ //S3按下,所选位加1
279 3 if(TimeFlag==0) TimeEdit(1); //判断编辑日期还是时间
280 3 else DateEdit(1);
281 3 break;
282 3 }
283 2 case 0x07:{ //S4按下,所选位减1
284 3 if(TimeFlag==0) TimeEdit(0); //判断编辑日期还是时间
285 3 else DateEdit(0);
286 3 break;
287 3 }
288 2 }
289 1 ET0=1;
290 1 }
291 //键盘扫描程序
292 uchar KeyScan(){
293 1 uchar key=0x00;
294 1 key|=S4;
295 1 key<<=1;
296 1 key|=S3;
297 1 key<<=1;
298 1 key|=S2;
299 1 key<<=1;
300 1 key|=S1;
301 1 return key;
302 1 }
303 //读取DS1302的秒,分,时,日,月,星期,年
C51 COMPILER V7.20 DS1302 01/17/2007 01:01:13 PAGE 6
304 void ReadDS1302(){
305 1 uchar i;
306 1 for(i=0;i<=6;i++) DS1302[i]=ReadByte(0x80+2*i+1);
307 1 //计算时间日期的各位要显示的数据
308 1 TimeBit[7]=DS1302[0]&0x0F;
309 1 TimeBit[6]=DS1302[0]&0x70;
310 1 TimeBit[6]>>=4;
311 1 TimeBit[4]=DS1302[1]&0x0F;
312 1 TimeBit[3]=DS1302[1]&0x70;
313 1 TimeBit[3]>>=4;
314 1 TimeBit[1]=DS1302[2]&0x0F;
315 1 TimeBit[0]=DS1302[2]&0x30;
316 1 TimeBit[0]>>=4;
317 1 DateBit[5]=DS1302[3]&0x0F;
318 1 DateBit[4]=DS1302[3]&0x30;
319 1 DateBit[4]>>=4;
320 1 DateBit[3]=DS1302[4]&0x0F;
321 1 DateBit[2]=DS1302[4]&0x10;
322 1 DateBit[2]>>=4;
323 1 DateBit[7]=DS1302[5]&0x07;
324 1 DateBit[1]=DS1302[6]&0x0F;
325 1 DateBit[0]=DS1302[6]&0xF0;
326 1 DateBit[0]>>=4;
327 1 }
328 //T0中断程序,读取和显示时间日期,更新闪烁标志
329 void T0Int(void) interrupt 1{
330 1 TL0=0x00;
331 1 TH0=0xb8;
332 1 num++;
333 1 if(num==15){
334 2 EditFlag=~EditFlag; //更新闪烁标志
335 2 num=0;
336 2 }
337 1 ReadDS1302();
338 1 Display();
339 1 }
340 //主函数
341 main(){
342 1 uchar key=0;
343 1 DsySelect=0; //打开数码管
344 1 P0=0xFF; //复位P0口
345 1 P2=0xFF; //复位P2口
346 1 TMOD=0x01; //T0初始化
347 1 EA=1;
348 1 ET0=1;
349 1 TL0=0x00;
350 1 TH0=0xb8;
351 1 TR0=1;
352 1 WriteByte(0x80,ReadByte(0x81)&0x7F); //启动DS1302
353 1 while(1){
354 2 key=KeyScan();
355 2 if(key!=0x0F){
356 3 delay(10); //隔10ms再次检测,可以消抖动
357 3 key=KeyScan();
358 3 if(key!=0x0F){
359 4 KeyFun(key);
360 4 delay(150); //此延时可以调节键盘的灵敏度
361 4 }
362 3 }
363 2 }
364 1 }
C51 COMPILER V7.20 DS1302 01/17/2007 01:01:13 PAGE 7
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1183 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 41 ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -