?? ds1302_8bit.lst
字號:
C51 COMPILER V7.50 DS1302_8BIT 09/29/2008 13:41:16 PAGE 1
C51 COMPILER V7.50, COMPILATION OF MODULE DS1302_8BIT
OBJECT MODULE PLACED IN ds1302_8bit.OBJ
COMPILER INVOKED BY: D:\Program Files\Keil\C51\BIN\C51.EXE ds1302_8bit.c BROWSE DEBUG OBJECTEXTEND
line level source
1 #include <reg52.h>
2 #include <intrins.h>
3 #define uchar unsigned char
4 uchar Code[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff}; //共陽數碼管編碼表
5 sbit DsySelect=P3^6; //控制數碼管的74HC244所在IO口
6 uchar BitCode=0x80; //數碼管位碼初值
7 uchar DS1302[8]={0,0,0,0,0,0,0,0}; //秒,分,時,日,月,星期,年
8 uchar DateBit[8]={0,0,0,0,0,0,10,0}; //日期各位顯示的數值
9 uchar TimeBit[8]={0,0,10,0,0,10,0,0}; //時間各位顯示的數值
10 sbit DATA=P1^1; //數據傳送總線
11 sbit SCLK=P1^0; //時鐘控制總線
12 sbit RST=P1^2; //復位總線
13 sbit S1=P3^4; //S1輸入口
14 sbit S2=P3^5; //S2輸入口
15 sbit S3=P3^2; //S3輸入口
16 sbit S4=P3^3; //S4輸入口
17 uchar TimeFlag=0; //顯示日期時間標志
18 uchar EditFlag=0; //閃爍顯示標志
19 uchar S2Num=0; //S2按的次數
20 uchar num=0;
21 //向DS1302寫一字節數據,address為命令字節
22 void WriteByte(uchar Command,uchar WriteData){
23 1 uchar j,k=1;
24 1 RST=0;
25 1 SCLK=0;
26 1 RST=1;
27 1 for(j=0;j<=7;j++){
28 2 if(Command&k) DATA=1;
29 2 else DATA=0;
30 2 SCLK=1;
31 2 k<<=1;
32 2 SCLK=0;
33 2 }
34 1 k=1;
35 1 for(j=0;j<=7;j++){
36 2 if(WriteData&k) DATA=1;
37 2 else DATA=0;
38 2 SCLK=1;
39 2 k<<=1;
40 2 SCLK=0;
41 2 }
42 1 RST=0;
43 1 }
44 //讀取DS1302一字節數據,address為命令字節
45 uchar ReadByte(uchar Command){
46 1 uchar i,k=1;
47 1 RST=0;
48 1 SCLK=0;
49 1 RST=1;
50 1 for(i=0;i<8;i++){
51 2 if(Command&k) DATA=1;
52 2 else DATA=0;
53 2 SCLK=1;
54 2 k<<=1;
55 2 if(i!=7) SCLK=0;
C51 COMPILER V7.50 DS1302_8BIT 09/29/2008 13:41:16 PAGE 2
56 2 }
57 1 k=0;
58 1 for(i=0;i<8;i++){
59 2 k>>=1;
60 2 SCLK=0;
61 2 if(DATA) k|=0x80;
62 2 SCLK=1;
63 2 }
64 1 RST=0;
65 1 return(k);
66 1 }
67 //延時程序
68 void delay(uchar ms){
69 1 uchar i;
70 1 while(ms--){
71 2 for(i=0;i<125;i++);
72 2 }
73 1 }
74 //掃描顯示程序
75 void Display(){
76 1 uchar i;
77 1 for(i=0;i<8;i++){
78 2 if(EditFlag&&S2Num>0){ //判斷是否閃爍
79 3 if(TimeFlag){ //判斷日期還是時間閃爍
80 4 switch(S2Num){ //根據S2按的次數判斷日期那一位閃爍
81 5 case 1:P2=BitCode&0x3F;break;
82 5 case 2:P2=BitCode&0xCF;break;
83 5 case 3:P2=BitCode&0xF3;break;
84 5 case 4:P2=BitCode&0xFE;break;
85 5 }
86 4 }else{
87 4 switch(S2Num){ //根據S2按的次數判斷時間那一位閃爍
88 5 case 1:P2=BitCode&0x3F;break;
89 5 case 2:P2=BitCode&0xE7;break;
90 5 case 3:P2=BitCode&0xFC;break;
91 5 }
92 4 }
93 3 }else{
94 3 P2=BitCode; //輸出位碼
95 3 }
96 2 if(TimeFlag) P0=Code[DateBit[i]]; //判斷顯示時間還是日期
97 2 else
98 2 P0=Code[TimeBit[i]];
99 2 BitCode=_cror_(BitCode,1); //位碼循環右移一位
100 2 delay(1); //延時1ms
101 2 P0=0xFF;
102 2 }
103 1 }
104 //時間編輯程序
105 void TimeEdit(uchar flag){
106 1 uchar Data,NowData;
107 1 if(flag){ //判斷加1還是減1
108 2 switch(S2Num){ //判斷編輯時間的哪一位
109 3 case 1:{
110 4 Data=ReadByte(0x85); //讀取小時數據
111 4 NowData=Data+1;
112 4 if((NowData&0x0F)>9) NowData=NowData+6;
113 4 if(NowData>=0x24) NowData=0;
114 4 WriteByte(0x84,NowData); //寫入小時數據
115 4 break;
116 4 }
117 3 case 2:{
C51 COMPILER V7.50 DS1302_8BIT 09/29/2008 13:41:16 PAGE 3
118 4 Data=ReadByte(0x83); //讀取分數據
119 4 NowData=Data+1;
120 4 if((NowData&0x0F)>9) NowData=NowData+6;
121 4 if(NowData>=0x60) NowData=0;
122 4 WriteByte(0x82,NowData); //寫入分數據
123 4 break;
124 4 }
125 3 case 3:{
126 4 Data=ReadByte(0x81); //讀取秒數據
127 4 NowData=Data+1;
128 4 if((NowData&0x0F)>9) NowData=NowData+6;
129 4 if((NowData&0x7F)>=0x60) NowData=0;
130 4 WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //寫入秒數據
131 4 break;
132 4 }
133 3 }
134 2 }else{
135 2 switch(S2Num){ //判斷編輯時間的哪一位
136 3 case 1:{
137 4 Data=ReadByte(0x85); //讀取小時數據
138 4 if(Data==0){
139 5 NowData=0x23;
140 5 }else{
141 5 NowData=Data-1;
142 5 if((NowData&0x0F)>9) NowData=NowData-6;
143 5 }
144 4 WriteByte(0x84,NowData); //寫入小時數據
145 4 break;
146 4 }
147 3 case 2:{
148 4 Data=ReadByte(0x83); //讀取分數據
149 4 if(Data==0){
150 5 NowData=0x59;
151 5 }else{
152 5 NowData=Data-1;
153 5 if((NowData&0x0F)>9) NowData=NowData-6;
154 5 }
155 4 WriteByte(0x82,NowData); //寫入分數據
156 4 break;
157 4 }
158 3 case 3:{
159 4 Data=ReadByte(0x81); //讀取秒數據
160 4 if(Data==0){
161 5 NowData=0x59;
162 5 }else{
163 5 NowData=Data-1;
164 5 if((NowData&0x0F)>9) NowData=NowData-6;
165 5 }
166 4 WriteByte(0x80,(NowData&0x7F)|(Data&0x80)); //寫入秒數據
167 4 break;
168 4 }
169 3 }
170 2 }
171 1 }
172 //日期編輯程序
173 void DateEdit(uchar flag){
174 1 uchar Data,NowData;
175 1 if(flag){ //判斷加1還是減1
176 2 switch(S2Num){ //判斷編輯日期的哪一位
177 3 case 1:{ //年加1
178 4 Data=ReadByte(0x8d); //讀取年數據
179 4 NowData=Data+1; //年加1
C51 COMPILER V7.50 DS1302_8BIT 09/29/2008 13:41:16 PAGE 4
180 4 if((NowData&0x0F)>9) NowData=NowData+6; //BCD調整
181 4 if(NowData>=0xA0) NowData=0; //年>=100時,年=0
182 4 WriteByte(0x8c,NowData); //年寫入DS1302
183 4 break;
184 4 }
185 3 case 2:{
186 4 Data=ReadByte(0x89); //讀取月數據
187 4 NowData=Data+1; //月加1
188 4 if((NowData&0x0F)>9) NowData=NowData+6; //BCD調整
189 4 if(NowData>=0x13) NowData=1; //月>=13,月=1
190 4 WriteByte(0x88,NowData); //月寫入DS1302
191 4 break;
192 4 }
193 3 case 3:{
194 4 Data=ReadByte(0x87); //讀取日數據
195 4 NowData=Data+1; //日加1
196 4 if((NowData&0x0F)>9) NowData=NowData+6; //BCD調整
197 4 if(NowData>=0x32) NowData=1; //日>=32,日=1
198 4 WriteByte(0x86,NowData); //日寫入DS1302
199 4 break;
200 4 }
201 3 case 4:{
202 4 Data=ReadByte(0x8B); //讀取星期數據
203 4 NowData=Data+1; //星期加1
204 4 if(NowData>=8) NowData=1; //星期>=8,星期=1
205 4 WriteByte(0x8A,NowData); //星期寫入DS1302
206 4 break;
207 4 }
208 3 }
209 2 }else{
210 2 switch(S2Num){
211 3 case 1:{ //年減1
212 4 Data=ReadByte(0x8d); //讀取年數據
213 4 if(Data==0){
214 5 NowData=0x99; //如果年=0,減1則為99
215 5 }else{
216 5 NowData=Data-1; //年減1
217 5 if((NowData&0x0F)>9) NowData=NowData-6; //BCD調整
218 5 }
219 4 WriteByte(0x8c,NowData); //年寫入DS1302
220 4 break;
221 4 }
222 3 case 2:{
223 4 Data=ReadByte(0x89); //讀取月數據
224 4 NowData=Data-1; //月減1
225 4 if((NowData&0x0F)>9) NowData=NowData-6; //BCD調整
226 4 if(NowData==0) NowData=0x12; //月=0,月=12
227 4 WriteByte(0x88,NowData); //月寫入DS1302
228 4 break;
229 4 }
230 3 case 3:{
231 4 Data=ReadByte(0x87); //讀取日數據
232 4 NowData=Data-1; //日減1
233 4 if((NowData&0x0F)>9) NowData=NowData-6; //BCD調整
234 4 if(NowData==0) NowData=0x31; //日=0,日=31
235 4 WriteByte(0x86,NowData); //日寫入DS1302
236 4 break;
237 4 }
238 3 case 4:{
239 4 Data=ReadByte(0x8B); //讀取星期數據
240 4 NowData=Data-1; //星期減1
241 4 if(NowData==0) NowData=7; //星期=0,星期=7
C51 COMPILER V7.50 DS1302_8BIT 09/29/2008 13:41:16 PAGE 5
242 4 WriteByte(0x8A,NowData); //星期寫入DS1302
243 4 break;
244 4 }
245 3 }
246 2 }
247 1 }
248 //按鈕功能函數
249 void KeyFun(uchar key){
250 1 ET0=0;
251 1 switch(key){
252 2 case 0x0E:{ //S1按下,切換顯示日期還是時間
253 3 TimeFlag=~TimeFlag;
254 3 S2Num=0;
255 3 break;
256 3 }
257 2 case 0x0D:{ //S2按下,S2Num加1
258 3 S2Num++;
259 3 if((TimeFlag>0)&&(S2Num>=5)) S2Num=0; //如果當前編輯的是日期并且S2Num>=5,則編輯完畢,返回正常狀態
260 3 if((TimeFlag==0)&&(S2Num>=4)) S2Num=0; //如果當前編輯的是時間并且S2Num>=4,則編輯完畢,返回正常狀態
261 3 break;
262 3 }
263 2 case 0x0B:{ //S3按下,所選位加1
264 3 if(TimeFlag==0) TimeEdit(1); //判斷編輯日期還是時間
265 3 else DateEdit(1);
266 3 break;
267 3 }
268 2 case 0x07:{ //S4按下,所選位減1
269 3 if(TimeFlag==0) TimeEdit(0); //判斷編輯日期還是時間
270 3 else DateEdit(0);
271 3 break;
272 3 }
273 2 }
274 1 ET0=1;
275 1 }
276 //鍵盤掃描程序
277 uchar KeyScan(){
278 1 uchar key=0x00;
279 1 key|=S4;
280 1 key<<=1;
281 1 key|=S3;
282 1 key<<=1;
283 1 key|=S2;
284 1 key<<=1;
285 1 key|=S1;
286 1 return key;
287 1 }
288 //讀取DS1302的秒,分,時,日,月,星期,年
289 void ReadDS1302(){
290 1 uchar i;
291 1 for(i=0;i<=6;i++) DS1302[i]=ReadByte(0x80+2*i+1);
292 1 //計算時間日期的各位要顯示的數據
293 1 TimeBit[7]=DS1302[0]&0x0F;
294 1 TimeBit[6]=DS1302[0]&0x70;
295 1 TimeBit[6]>>=4;
296 1 TimeBit[4]=DS1302[1]&0x0F;
297 1 TimeBit[3]=DS1302[1]&0x70;
298 1 TimeBit[3]>>=4;
299 1 TimeBit[1]=DS1302[2]&0x0F;
300 1 TimeBit[0]=DS1302[2]&0x30;
301 1 TimeBit[0]>>=4;
302 1 DateBit[5]=DS1302[3]&0x0F;
303 1 DateBit[4]=DS1302[3]&0x30;
C51 COMPILER V7.50 DS1302_8BIT 09/29/2008 13:41:16 PAGE 6
304 1 DateBit[4]>>=4;
305 1 DateBit[3]=DS1302[4]&0x0F;
306 1 DateBit[2]=DS1302[4]&0x10;
307 1 DateBit[2]>>=4;
308 1 DateBit[7]=DS1302[5]&0x07;
309 1 DateBit[1]=DS1302[6]&0x0F;
310 1 DateBit[0]=DS1302[6]&0xF0;
311 1 DateBit[0]>>=4;
312 1 }
313 //T0中斷程序,讀取和顯示時間日期,更新閃爍標志
314 void T0Int(void) interrupt 1{
315 1 TL0=0x00;
316 1 TH0=0xb8;
317 1 num++;
318 1 if(num==15){
319 2 EditFlag=~EditFlag; //更新閃爍標志
320 2 num=0;
321 2 }
322 1 ReadDS1302();
323 1 Display();
324 1 }
325 //主函數
326 main(){
327 1 uchar key=0;
328 1 DsySelect=0; //打開數碼管
329 1 P0=0xFF; //復位P0口
330 1 P2=0xFF; //復位P2口
331 1 TMOD=0x01; //T0初始化
332 1 EA=1;
333 1 ET0=1;
334 1 TL0=0x00;
335 1 TH0=0xb8;
336 1 TR0=1;
337 1 WriteByte(0x80,ReadByte(0x81)&0x7F); //啟動DS1302
338 1 while(1){
339 2 key=KeyScan();
340 2 if(key!=0x0F){
341 3 delay(10); //隔10ms再次檢測,可以消抖動
342 3 key=KeyScan();
343 3 if(key!=0x0F){
344 4 KeyFun(key);
345 4 delay(150); //此延時可以調節鍵盤的靈敏度
346 4 }
347 3 }
348 2 }
349 1 }
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 + -