实例介绍
技术要求:
1、出租车计价规则:1)起步价10元,起租里程2.5公里;2)超过2.5公里后,按2.6元/公里计费;3)营运行驶超过35公里后,计价器自动加收50%空驶费;4)出租车低速营运(时速<5公里)或应乘客要求停车等候时,按26元/小时计费。
2、计价器可显示行驶里程(公里),低速营运时长(小时:分钟),总价(元)等信息,里程和总价保留至小数点后1位显示,时长按以时:分形式显示。每行驶100米刷新计算一次。
3、计价器用按键控制开始计价及停止计价;用指示灯显示出租车空载状态。
4、计价器具备数据存储功能,可存储最近10次计费记录(行驶里程、低速营运时长、总价等),并可用按键进行浏览。
5、计价器测速单元由安装于车轮上的霍尔传感器测量,车轮每转1圈产生1个脉冲信号。本系统直接采用脉冲输入模拟车轮转动状态。设出租车轮胎直径为560mm,其周长为
1.7584m,则57圈约行驶100m,即本系统以57个脉冲计为100mo
6、系统自备独立电源。
C51 COMPILER V9.59.0.0, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN main.OBJ
COMPILER INVOKED BY: D:\keil5MDK\keil5\C51\BIN\C51.EXE main.c OPTIMIZE(8,SPEED) BROWSE DEBUG OBJECTEXTEND TABS(2)
line level source
1 #include <reg51.h> //单片机头文件
2 #include "intrins.h" //_nop_()
3
4
5
6
7
8 //宏定义
9 #define uchar unsigned char
10 #define uint unsigned int
11
12 //全局变量
13 uint startT=0;
14 uint endT=0;
15 uint sec;
16 bit flag=0;
17 uint price=0;
18 uint deng=0;
19 uchar key; //按键返回值
20 uchar dhour,dmin;
21 bit mode=0;
22 uchar tsec,tdhour,tdmin,tprice;
23 unsigned char dofly[5]; // 显示码值 1234
24
25 //单片机引脚定义
26 //DS1302引脚定义,可根据实际情况自行修改端口定义
27 sbit RST=P3^4;
28 sbit DAT=P3^5;
29 sbit CLK=P3^6;
30
31 //24C02
32 sbit sda=P2^1;
33 sbit scl=P2^0;
34
35 //DS1302地址定义
36 #define ds1302_sec_add 0x80 //秒数据地址
37 #define ds1302_min_add 0x82 //分数据地址
38 #define ds1302_hr_add 0x84 //时数据地址
39 #define ds1302_date_add 0x86 //日数据地址
40 #define ds1302_month_add 0x88 //月数据地址
41 #define ds1302_day_add 0x8a //星期数据地址
42 #define ds1302_year_add 0x8c //年数据地址
43 #define ds1302_control_add 0x8e //控制数据地址
44 #define ds1302_charger_add 0x90
45 #define ds1302_clkburst_add 0xbe
46 //初始时间定义
47 uchar time_buf[8] = {0x20,0x20,0x06,0x15,0x19,0x00,0x55,0x06};//初始时间 2020.06.15 10:04 55秒 周六
48 uchar readtime[14];//当前时间
49 uchar dis_time_buf[16]={0};
50
51
52
53 //LCD1602
54 sbit LCDRS = P2^5;
55 sbit LCDRW = P2^6;
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 2
56 sbit LCDEN = P2^7;
57 sbit D0 = P0^0;
58 sbit D1 = P0^1;
59 sbit D2 = P0^2;
60 sbit D3 = P0^3;
61 sbit D4 = P0^4;
62 sbit D5 = P0^5;
63 sbit D6 = P0^6;
64 sbit D7 = P0^7;
65
66 sbit Key1 = P1^0; //
67 sbit Key2 = P1^1; //
68 sbit Key3 = P1^2; //
69 sbit LED = P1^3; //
70 sbit Key4 = P1^4; //
71 sbit Key5 = P1^5; //
72
73
74
75 //延时函数
76 void Delay_ms(uint q)
77 {
78 1 uint i,j;
79 1 for(i=0;i<q;i )
80 1 {
81 2 for(j=0;j<110;j )
82 2 {
83 3 ;//空语句
84 3 }
85 2 }
86 1 }
87
88
89 /****************************24c02函数START*******************************/
90 void delay() //延时应大于4.7us
91 { ;;;}
92
93 void start() //开始发送数据
94 { sda=1;
95 1 delay(); //scl在高电平期间,sda由高到低
96 1 scl=1;
97 1 delay();
98 1 sda=0;
99 1 delay();
100 1 }
101
102 void stop() //停止发送数据
103 { sda=0; //scl在高电平期间,sda由高到低
104 1 delay();
105 1 scl=1;
106 1 delay();
107 1 sda=1;
108 1 delay();
109 1 }
110
111 void response()
112 { uchar i;
113 1 scl=1;
114 1 delay();
115 1 if((sda==1)&&i<250) i ; //应答sda为0,非应答为1
116 1 scl=0; //释放总线
117 1 delay();
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 3
118 1 }
119
120 void noack()
121 { scl=1;
122 1 delay();
123 1 scl=1;
124 1 delay();
125 1 scl=0;
126 1 delay();
127 1 sda=0;
128 1 delay();
129 1 }
130 void init() //初始化
131 { sda=1;
132 1 delay();
133 1 scl=1;
134 1 delay();
135 1 }
136 void write_byte(uchar date) //写一个字节
137 { uchar i,temp;
138 1 temp=date;
139 1 for(i=0;i<8;i )
140 1 { temp=temp<<1;
141 2 scl=0; //scl上跳沿写入
142 2 delay();
143 2 sda=CY; //溢出位
144 2 delay();
145 2 scl=1;
146 2 delay();
147 2 scl=0;
148 2 delay();
149 2 }
150 1 scl=0;
151 1 delay();
152 1 sda=1;
153 1 delay();
154 1 }
155 uchar read_byte()
156 { uchar i,k;
157 1 scl=0;
158 1 delay();
159 1 sda=1;
160 1 delay();
161 1 for(i=0;i<8;i )
162 1 { scl=1;
163 2 delay();
164 2 k=(k<<1)|sda;
165 2 scl=0;
166 2 delay();
167 2 }
168 1 return k;
169 1 }
170 void delay1(uchar x)
171 { uchar a,b;
172 1 for(a=x;a>0;a--)
173 1 for(b=200;b>0;b--);
174 1 }
175
176 void write_add(uchar address,uchar date)
177 { start();
178 1 write_byte(0xa0); //设备地址
179 1 response();
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 4
180 1 write_byte(address);
181 1 response();
182 1 write_byte(date);
183 1 response();
184 1 stop();
185 1 }
186
187 uchar read_add(uchar address)
188 { uchar date;
189 1 start();
190 1 write_byte(0xa0);
191 1 response();
192 1 write_byte(address);
193 1 response();
194 1 start();
195 1 write_byte(0xa1); //1表示接收地址
196 1 response();
197 1 date=read_byte();
198 1 noack();
199 1 stop();
200 1 return date;
201 1 }
202
203 /****************************24c02函数END*******************************/
204
205
206 /*--------------------------DS1302操作START--------------------------*/
207
208 //DS1302初始化函数
209 void ds1302_init(void)
210 {
211 1 RST=0; //RST脚置低
212 1 CLK=0; //SCK脚置低
213 1 }
214 //向DS1302写入一字节数据
215 void ds1302_write_byte(uchar addr, uchar d)
216 {
217 1 uchar i;
218 1 RST=1; //启动DS1302总线
219 1 //写入目标地址:addr
220 1 addr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读
221 1 for (i = 0; i < 8; i ) {
222 2 if (addr & 0x01) {
223 3 DAT=1;
224 3 }
225 2 else {
226 3 DAT=0;
227 3 }
228 2 CLK=1; //产生时钟
229 2 CLK=0;
230 2 addr = addr >> 1;
231 2 }
232 1 //写入数据:d
233 1 for (i = 0; i < 8; i ) {
234 2 if (d & 0x01) {
235 3 DAT=1;
236 3 }
237 2 else {
238 3 DAT=0;
239 3 }
240 2 CLK=1; //产生时钟
241 2 CLK=0;
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 5
242 2 d = d >> 1;
243 2 }
244 1 RST=0; //停止DS1302总线
245 1 }
246 //从DS1302读出一字节数据
247 uchar ds1302_read_byte(uchar addr) {
248 1
249 1 uchar i,temp;
250 1 RST=1; //启动DS1302总线
251 1 //写入目标地址:addr
252 1 addr = addr | 0x01; //最低位置高,寄存器0位为0时写,为1时读
253 1 for (i = 0; i < 8; i ) {
254 2 if (addr & 0x01) {
255 3 DAT=1;
256 3 }
257 2 else {
258 3 DAT=0;
259 3 }
260 2 CLK=1;
261 2 CLK=0;
262 2 addr = addr >> 1;
263 2 }
264 1 //输出数据:temp
265 1 for (i = 0; i < 8; i ) {
266 2 temp = temp >> 1;
267 2 if (DAT) {
268 3 temp |= 0x80;
269 3 }
270 2 else {
271 3 temp &= 0x7F;
272 3 }
273 2 CLK=1;
274 2 CLK=0;
275 2 }
276 1 RST=0; //停止DS1302总线
277 1 return temp;
278 1 }
279 //向DS302写入时钟数据
280 void ds1302_write_time(void)
281 {
282 1 ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护
283 1 ds1302_write_byte(ds1302_sec_add,0x80); //暂停时钟
284 1 //ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电
285 1 ds1302_write_byte(ds1302_year_add,time_buf[3]); //日
286 1 ds1302_write_byte(ds1302_month_add,time_buf[2]); //月
287 1 ds1302_write_byte(ds1302_date_add,time_buf[1]); //年
288 1 ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时
289 1 ds1302_write_byte(ds1302_min_add,time_buf[5]); //分
290 1 ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒
291 1 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周
292 1 ds1302_write_byte(ds1302_control_add,0x80); //打开写保护
293 1 }
294 //从DS302读出时钟数据
295 void ds1302_read_time(void)
296 {
297 1 // time_buf[1]=ds1302_read_byte(ds1302_year_add); //年
298 1 // time_buf[2]=ds1302_read_byte(ds1302_month_add); //月
299 1 // time_buf[3]=ds1302_read_byte(ds1302_date_add); //日
300 1 time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时
301 1 time_buf[5]=ds1302_read_byte(ds1302_min_add); //分
302 1 time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;//秒,屏蔽秒的第7位,避免超出59
303 1 // time_buf[7]=ds1302_read_byte(ds1302_day_add); //周
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 6
304 1 }
305 /*--------------------------DS1302操作END--------------------------*/
306
307
308
309 /****************************LCD1602函数START*****************************/
310 //LCD1602延时子函数
311 void Delay_LCD1602(uint z)
312 {
313 1 uint x,y;
314 1 for(x=z;x>0;x--)
315 1 {
316 2 for(y=10;y>0;y--)
317 2 {
318 3 ;//空语句
319 3 }
320 2 }
321 1 }
322 //LCD1602写一个字节
323 void WriteByte_LCD1602(uint dat)
324 {
325 1 LCDRW = 0;
326 1 if(dat&0x01)
327 1 {
328 2 D0=1;
329 2 }else
330 1 {
331 2 D0=0;
332 2 }
333 1 if(dat&0x02)
334 1 {
335 2 D1=1;
336 2 }else
337 1 {
338 2 D1=0;
339 2 }
340 1 if(dat&0x04)
341 1 {
342 2 D2=1;
343 2 }else
344 1 {
345 2 D2=0;
346 2 }
347 1 if(dat&0x08)
348 1 {
349 2 D3=1;
350 2 }else
351 1 {
352 2 D3=0;
353 2 }
354 1 if(dat&0x10)
355 1 {
356 2 D4=1;
357 2 }else
358 1 {
359 2 D4=0;
360 2 }
361 1 if(dat&0x20)
362 1 {
363 2 D5=1;
364 2 }else
365 1 {
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 7
366 2 D5=0;
367 2 }
368 1 if(dat&0x40)
369 1 {
370 2 D6=1;
371 2 }else
372 1 {
373 2 D6=0;
374 2 }
375 1 if(dat&0x80)
376 1 {
377 2 D7=1;
378 2 }else
379 1 {
380 2 D7=0;
381 2 }
382 1 }
383 //写命令
384 void Write_Com(uchar com)
385 {
386 1 LCDRS = 0;
387 1 WriteByte_LCD1602(com);
388 1 Delay_LCD1602(5);
389 1 LCDEN = 1;
390 1 Delay_LCD1602(5);
391 1 LCDEN = 0;
392 1 }
393 //写数据
394 void Write_Data(uchar dat)
395 {
396 1 LCDRS = 1;
397 1 WriteByte_LCD1602(dat);
398 1 Delay_LCD1602(5);
399 1 LCDEN = 1;
400 1 Delay_LCD1602(5);
401 1 LCDEN = 0;
402 1 }
403 //初始化LCD1602
404 void Init_LCD1602()
405 {
406 1 Write_Com(0x38); //屏幕初始化
407 1 Write_Com(0x0c); //打开显示 无光标 闪烁
408 1 Write_Com(0x06); //指针右移
409 1 Write_Com(0x01); //清屏
410 1 }
411 //设置显示位置
412 void Select_Pos(uchar x,uchar y)
413 {
414 1 if(x == 0)
415 1 {
416 2 Write_Com(0x80 y);
417 2 }else
418 1 {
419 2 Write_Com(0xc0 y);
420 2 }
421 1 }
422 void LCD_Write_String(uchar x,uchar y,uchar *s)
423 {
424 1 Select_Pos(x,y);
425 1 while(*s)
426 1 {
427 2 Write_Data(*s);
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 8
428 2 s ;
429 2 }
430 1 }
431 void LCD_Write_Char(uchar x,uchar y,uint s,uchar l)
432 {
433 1 Select_Pos(x,y);
434 1 if(l>=5)
435 1 {
436 2 Write_Data(0x30 s/10000%10);
437 2 }
438 1 if(l>=4)
439 1 {
440 2 Write_Data(0x30 s/1000%10);
441 2 }
442 1 if(l>=3)
443 1 {
444 2 Write_Data(0x30 s/100%10);
445 2 }
446 1 if(l>=2)
447 1 {
448 2 Write_Data(0x30 s/10%10);
449 2 }
450 1 if(l>=1)
451 1 {
452 2 Write_Data(0x30 s%10);
453 2 }
454 1 }
455 uint Cal(uchar sect,uchar hourt,uchar mint)
456 {
457 1 deng=(hourt*6 mint)*26;
458 1 if(sec<=25)
459 1 {
460 2 price=1000 deng;
461 2
462 2 }else if((sec>25)&&(sec<=35))
463 1 {
464 2 price=((sec-25)*26 1000 deng); //放大100倍
465 2 }else
466 1 {
467 2 price=((sec-25)*26 1000)*3/2 deng; //放大100倍
468 2 }
469 1 return price;
470 1 }
*** WARNING C280 IN LINE 455 OF main.c: 'sect': unreferenced local variable
471
472 //正常数据显示
473 void Display_LCD1602SET()
474 {
475 1 uchar i;
476 1 uchar temprice;
477 1 for(i=0;i<5;i )
478 1 {
479 2 dofly[i]=read_add(i); //低电平灯亮
480 2 }
481 1 LCD_Write_Char(0,0,dofly[0]/10,2); //显示时间
482 1 LCD_Write_String(0,2,".");
483 1 LCD_Write_Char(0,3,dofly[0]%10,1); //显示时间
484 1
485 1 LCD_Write_String(0,4," ");
486 1 LCD_Write_Char(0,5,dofly[1]/10,1);
487 1 LCD_Write_Char(0,6,dofly[1]%10,1);
488 1 LCD_Write_String(0,7,":");
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 9
489 1 LCD_Write_Char(0,8,dofly[2]/10,1);
490 1 LCD_Write_Char(0,9,dofly[2]%10,1); //显示时间
491 1 LCD_Write_String(0,10," ");
492 1 LCD_Write_Char(0,11,dofly[3],2); //显示时间
493 1 LCD_Write_String(0,13,".");
494 1 LCD_Write_Char(0,14,dofly[4],2); //显示时间
495 1 LCD_Write_String(1,0," ");
496 1 }
*** WARNING C280 IN LINE 476 OF main.c: 'temprice': unreferenced local variable
497 //正常数据显示
498 void Display_LCD1602()
499 {
500 1 ds1302_read_time(); //读取数据
501 1 dis_time_buf[14]=(time_buf[5]>>4); //读取分
502 1 dis_time_buf[15]=(time_buf[5]&0x0f);
503 1 dis_time_buf[10]=(time_buf[6]>>4); //读取秒
504 1 dis_time_buf[11]=(time_buf[6]&0x0f);
505 1
506 1 LCD_Write_String(0,0,"TIME:");
507 1 LCD_Write_Char(0,5,dhour/10,1);
508 1 LCD_Write_Char(0,6,dhour%10,1);
509 1 LCD_Write_String(0,7,":");
510 1 LCD_Write_Char(0,8,dmin/10,1);
511 1 LCD_Write_Char(0,9,dmin%10,1); //显示时间
512 1
513 1
514 1
515 1 /*
516 1 LCD_Write_String(0,0,"TIME:");
517 1 LCD_Write_Char(0,5,dis_time_buf[14],1);
518 1 LCD_Write_Char(0,6,dis_time_buf[15],1);
519 1 LCD_Write_String(0,7,":");
520 1 LCD_Write_Char(0,8,dis_time_buf[10],1);
521 1 LCD_Write_Char(0,9,dis_time_buf[11],1); //显示时间
522 1 */
523 1 LCD_Write_String(0,11,"S:");
524 1 if(flag==1)
525 1 {
526 2 LCD_Write_String(0,13,"STA");
527 2 }else
528 1 {
529 2 LCD_Write_String(0,13,"END");
530 2 }
531 1 LCD_Write_String(1,0,"S:");
532 1 LCD_Write_String(1,6,"P:");
533 1 LCD_Write_String(1,13," ");
534 1 if(start!=0)
535 1 {
536 2 if(flag!=0) //正在运行
537 2 {
538 3 endT=(dis_time_buf[14]*10 dis_time_buf[15])*60 (dis_time_buf[10]*10 dis_time_buf[11]);
539 3 }
540 2 sec=endT-startT;
541 2 LCD_Write_Char(1,2,sec/10,2); //显示时间
542 2 LCD_Write_String(1,4,".");
543 2 LCD_Write_Char(1,5,sec%10,1); //显示时间
544 2 }
545 1
546 1
547 1 LCD_Write_Char(1,8,price/100,2); //显示时间
548 1 LCD_Write_String(1,10,".");
549 1 LCD_Write_Char(1,11,price%100,2); //显示时间
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 10
550 1
551 1 }
552 /****************************LCD1602函数END*******************************/
553
554
555
556 //扫描按键
557 uchar Scan_Key(void)
558 {
559 1 static uchar key_up = 1; //按键松开标志
560 1 if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0||Key5==0))
561 1 {
562 2 Delay_ms(10); //去抖动
563 2 key_up = 0; //更改标志位
564 2 if(Key1==0)
565 2 {
566 3 return 1;
567 3 }else if(Key2==0)
568 2 {
569 3 return 2;
570 3 }else if(Key3==0)
571 2 {
572 3 return 3;
573 3 }else if(Key4==0)
574 2 {
575 3 return 4;
576 3 }else if(Key5==0)
577 2 {
578 3 return 5;
579 3 }
580 2
581 2 }else if(Key1==1&&Key2==1&&Key3==1&&Key4==1&&Key5==1)
582 1 {
583 2 key_up = 1;
584 2 }
585 1 return 0; //无按键按下
586 1 }
587
588
589
590 //主函数
591 int main(void)
592 {
593 1 uchar i;
594 1
595 1 Init_LCD1602(); //初始化LCD1602
596 1 ds1302_init(); //DS1302初始化
597 1 LED=1;
598 1 LCD_Write_String(4,0,"WELCOME");
599 1
600 1
601 1
602 1
603 1
604 1
605 1 Delay_ms(1000); //系统准备时间
606 1 while(1)
607 1 {
608 2
609 2 key = Scan_Key();
610 2 if(key==1)
611 2 {
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 11
612 3 if(mode==0)
613 3 {
614 4 flag = 1;
615 4 startT=(dis_time_buf[14]*10 dis_time_buf[15])*60 (dis_time_buf[10]*10 dis_time_buf[11]);
616 4 //LCD_Write_Char(1,2,start,4); //显示时间
617 4 LED=0;
618 4 }
619 3
620 3 }
621 2 if(key==2)
622 2 {
623 3 if(flag==1)
624 3 {
625 4 flag = 0;
626 4 LED=1;
627 4 dofly[0]=sec;
628 4 dofly[1]=dhour;
629 4 dofly[2]=dmin;
630 4 dofly[3]=price/100;
631 4 dofly[4]=price%100;
632 4 for(i=0;i<5;i )
633 4 {
634 5 write_add(i,dofly[i]); //向0单元写入数据0fH,
635 5 delay1(100);
636 5 }
637 4 }
638 3 }
639 2 if(key==3)
640 2 {
641 3 dmin =10;
642 3 if(dmin==60)
643 3 {
644 4 dmin=0;
645 4 dhour =1;
646 4 }
647 3 }
648 2 if(key==4)
649 2 {
650 3 mode=~mode;
651 3 }
652 2
653 2 if(mode==0)
654 2 {
655 3 Cal(sec,dhour,dmin);
656 3 Display_LCD1602();
657 3 }else
658 2 {
659 3 Display_LCD1602SET();
660 3 }
661 2 }
662 1 return 0;
663 1 }
*** WARNING C294 IN LINE 662 OF main.c: unreachable code
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1919 ----
CONSTANT SIZE = 55 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 61 8
IDATA SIZE = ---- ----
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 12
BIT SIZE = 2 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 3 WARNING(S), 0 ERROR(S)
1、出租车计价规则:1)起步价10元,起租里程2.5公里;2)超过2.5公里后,按2.6元/公里计费;3)营运行驶超过35公里后,计价器自动加收50%空驶费;4)出租车低速营运(时速<5公里)或应乘客要求停车等候时,按26元/小时计费。
2、计价器可显示行驶里程(公里),低速营运时长(小时:分钟),总价(元)等信息,里程和总价保留至小数点后1位显示,时长按以时:分形式显示。每行驶100米刷新计算一次。
3、计价器用按键控制开始计价及停止计价;用指示灯显示出租车空载状态。
4、计价器具备数据存储功能,可存储最近10次计费记录(行驶里程、低速营运时长、总价等),并可用按键进行浏览。
5、计价器测速单元由安装于车轮上的霍尔传感器测量,车轮每转1圈产生1个脉冲信号。本系统直接采用脉冲输入模拟车轮转动状态。设出租车轮胎直径为560mm,其周长为
1.7584m,则57圈约行驶100m,即本系统以57个脉冲计为100mo
6、系统自备独立电源。
C51 COMPILER V9.59.0.0, COMPILATION OF MODULE MAIN
OBJECT MODULE PLACED IN main.OBJ
COMPILER INVOKED BY: D:\keil5MDK\keil5\C51\BIN\C51.EXE main.c OPTIMIZE(8,SPEED) BROWSE DEBUG OBJECTEXTEND TABS(2)
line level source
1 #include <reg51.h> //单片机头文件
2 #include "intrins.h" //_nop_()
3
4
5
6
7
8 //宏定义
9 #define uchar unsigned char
10 #define uint unsigned int
11
12 //全局变量
13 uint startT=0;
14 uint endT=0;
15 uint sec;
16 bit flag=0;
17 uint price=0;
18 uint deng=0;
19 uchar key; //按键返回值
20 uchar dhour,dmin;
21 bit mode=0;
22 uchar tsec,tdhour,tdmin,tprice;
23 unsigned char dofly[5]; // 显示码值 1234
24
25 //单片机引脚定义
26 //DS1302引脚定义,可根据实际情况自行修改端口定义
27 sbit RST=P3^4;
28 sbit DAT=P3^5;
29 sbit CLK=P3^6;
30
31 //24C02
32 sbit sda=P2^1;
33 sbit scl=P2^0;
34
35 //DS1302地址定义
36 #define ds1302_sec_add 0x80 //秒数据地址
37 #define ds1302_min_add 0x82 //分数据地址
38 #define ds1302_hr_add 0x84 //时数据地址
39 #define ds1302_date_add 0x86 //日数据地址
40 #define ds1302_month_add 0x88 //月数据地址
41 #define ds1302_day_add 0x8a //星期数据地址
42 #define ds1302_year_add 0x8c //年数据地址
43 #define ds1302_control_add 0x8e //控制数据地址
44 #define ds1302_charger_add 0x90
45 #define ds1302_clkburst_add 0xbe
46 //初始时间定义
47 uchar time_buf[8] = {0x20,0x20,0x06,0x15,0x19,0x00,0x55,0x06};//初始时间 2020.06.15 10:04 55秒 周六
48 uchar readtime[14];//当前时间
49 uchar dis_time_buf[16]={0};
50
51
52
53 //LCD1602
54 sbit LCDRS = P2^5;
55 sbit LCDRW = P2^6;
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 2
56 sbit LCDEN = P2^7;
57 sbit D0 = P0^0;
58 sbit D1 = P0^1;
59 sbit D2 = P0^2;
60 sbit D3 = P0^3;
61 sbit D4 = P0^4;
62 sbit D5 = P0^5;
63 sbit D6 = P0^6;
64 sbit D7 = P0^7;
65
66 sbit Key1 = P1^0; //
67 sbit Key2 = P1^1; //
68 sbit Key3 = P1^2; //
69 sbit LED = P1^3; //
70 sbit Key4 = P1^4; //
71 sbit Key5 = P1^5; //
72
73
74
75 //延时函数
76 void Delay_ms(uint q)
77 {
78 1 uint i,j;
79 1 for(i=0;i<q;i )
80 1 {
81 2 for(j=0;j<110;j )
82 2 {
83 3 ;//空语句
84 3 }
85 2 }
86 1 }
87
88
89 /****************************24c02函数START*******************************/
90 void delay() //延时应大于4.7us
91 { ;;;}
92
93 void start() //开始发送数据
94 { sda=1;
95 1 delay(); //scl在高电平期间,sda由高到低
96 1 scl=1;
97 1 delay();
98 1 sda=0;
99 1 delay();
100 1 }
101
102 void stop() //停止发送数据
103 { sda=0; //scl在高电平期间,sda由高到低
104 1 delay();
105 1 scl=1;
106 1 delay();
107 1 sda=1;
108 1 delay();
109 1 }
110
111 void response()
112 { uchar i;
113 1 scl=1;
114 1 delay();
115 1 if((sda==1)&&i<250) i ; //应答sda为0,非应答为1
116 1 scl=0; //释放总线
117 1 delay();
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 3
118 1 }
119
120 void noack()
121 { scl=1;
122 1 delay();
123 1 scl=1;
124 1 delay();
125 1 scl=0;
126 1 delay();
127 1 sda=0;
128 1 delay();
129 1 }
130 void init() //初始化
131 { sda=1;
132 1 delay();
133 1 scl=1;
134 1 delay();
135 1 }
136 void write_byte(uchar date) //写一个字节
137 { uchar i,temp;
138 1 temp=date;
139 1 for(i=0;i<8;i )
140 1 { temp=temp<<1;
141 2 scl=0; //scl上跳沿写入
142 2 delay();
143 2 sda=CY; //溢出位
144 2 delay();
145 2 scl=1;
146 2 delay();
147 2 scl=0;
148 2 delay();
149 2 }
150 1 scl=0;
151 1 delay();
152 1 sda=1;
153 1 delay();
154 1 }
155 uchar read_byte()
156 { uchar i,k;
157 1 scl=0;
158 1 delay();
159 1 sda=1;
160 1 delay();
161 1 for(i=0;i<8;i )
162 1 { scl=1;
163 2 delay();
164 2 k=(k<<1)|sda;
165 2 scl=0;
166 2 delay();
167 2 }
168 1 return k;
169 1 }
170 void delay1(uchar x)
171 { uchar a,b;
172 1 for(a=x;a>0;a--)
173 1 for(b=200;b>0;b--);
174 1 }
175
176 void write_add(uchar address,uchar date)
177 { start();
178 1 write_byte(0xa0); //设备地址
179 1 response();
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 4
180 1 write_byte(address);
181 1 response();
182 1 write_byte(date);
183 1 response();
184 1 stop();
185 1 }
186
187 uchar read_add(uchar address)
188 { uchar date;
189 1 start();
190 1 write_byte(0xa0);
191 1 response();
192 1 write_byte(address);
193 1 response();
194 1 start();
195 1 write_byte(0xa1); //1表示接收地址
196 1 response();
197 1 date=read_byte();
198 1 noack();
199 1 stop();
200 1 return date;
201 1 }
202
203 /****************************24c02函数END*******************************/
204
205
206 /*--------------------------DS1302操作START--------------------------*/
207
208 //DS1302初始化函数
209 void ds1302_init(void)
210 {
211 1 RST=0; //RST脚置低
212 1 CLK=0; //SCK脚置低
213 1 }
214 //向DS1302写入一字节数据
215 void ds1302_write_byte(uchar addr, uchar d)
216 {
217 1 uchar i;
218 1 RST=1; //启动DS1302总线
219 1 //写入目标地址:addr
220 1 addr = addr & 0xFE; //最低位置零,寄存器0位为0时写,为1时读
221 1 for (i = 0; i < 8; i ) {
222 2 if (addr & 0x01) {
223 3 DAT=1;
224 3 }
225 2 else {
226 3 DAT=0;
227 3 }
228 2 CLK=1; //产生时钟
229 2 CLK=0;
230 2 addr = addr >> 1;
231 2 }
232 1 //写入数据:d
233 1 for (i = 0; i < 8; i ) {
234 2 if (d & 0x01) {
235 3 DAT=1;
236 3 }
237 2 else {
238 3 DAT=0;
239 3 }
240 2 CLK=1; //产生时钟
241 2 CLK=0;
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 5
242 2 d = d >> 1;
243 2 }
244 1 RST=0; //停止DS1302总线
245 1 }
246 //从DS1302读出一字节数据
247 uchar ds1302_read_byte(uchar addr) {
248 1
249 1 uchar i,temp;
250 1 RST=1; //启动DS1302总线
251 1 //写入目标地址:addr
252 1 addr = addr | 0x01; //最低位置高,寄存器0位为0时写,为1时读
253 1 for (i = 0; i < 8; i ) {
254 2 if (addr & 0x01) {
255 3 DAT=1;
256 3 }
257 2 else {
258 3 DAT=0;
259 3 }
260 2 CLK=1;
261 2 CLK=0;
262 2 addr = addr >> 1;
263 2 }
264 1 //输出数据:temp
265 1 for (i = 0; i < 8; i ) {
266 2 temp = temp >> 1;
267 2 if (DAT) {
268 3 temp |= 0x80;
269 3 }
270 2 else {
271 3 temp &= 0x7F;
272 3 }
273 2 CLK=1;
274 2 CLK=0;
275 2 }
276 1 RST=0; //停止DS1302总线
277 1 return temp;
278 1 }
279 //向DS302写入时钟数据
280 void ds1302_write_time(void)
281 {
282 1 ds1302_write_byte(ds1302_control_add,0x00); //关闭写保护
283 1 ds1302_write_byte(ds1302_sec_add,0x80); //暂停时钟
284 1 //ds1302_write_byte(ds1302_charger_add,0xa9); //涓流充电
285 1 ds1302_write_byte(ds1302_year_add,time_buf[3]); //日
286 1 ds1302_write_byte(ds1302_month_add,time_buf[2]); //月
287 1 ds1302_write_byte(ds1302_date_add,time_buf[1]); //年
288 1 ds1302_write_byte(ds1302_hr_add,time_buf[4]); //时
289 1 ds1302_write_byte(ds1302_min_add,time_buf[5]); //分
290 1 ds1302_write_byte(ds1302_sec_add,time_buf[6]); //秒
291 1 ds1302_write_byte(ds1302_day_add,time_buf[7]); //周
292 1 ds1302_write_byte(ds1302_control_add,0x80); //打开写保护
293 1 }
294 //从DS302读出时钟数据
295 void ds1302_read_time(void)
296 {
297 1 // time_buf[1]=ds1302_read_byte(ds1302_year_add); //年
298 1 // time_buf[2]=ds1302_read_byte(ds1302_month_add); //月
299 1 // time_buf[3]=ds1302_read_byte(ds1302_date_add); //日
300 1 time_buf[4]=ds1302_read_byte(ds1302_hr_add); //时
301 1 time_buf[5]=ds1302_read_byte(ds1302_min_add); //分
302 1 time_buf[6]=(ds1302_read_byte(ds1302_sec_add))&0x7f;//秒,屏蔽秒的第7位,避免超出59
303 1 // time_buf[7]=ds1302_read_byte(ds1302_day_add); //周
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 6
304 1 }
305 /*--------------------------DS1302操作END--------------------------*/
306
307
308
309 /****************************LCD1602函数START*****************************/
310 //LCD1602延时子函数
311 void Delay_LCD1602(uint z)
312 {
313 1 uint x,y;
314 1 for(x=z;x>0;x--)
315 1 {
316 2 for(y=10;y>0;y--)
317 2 {
318 3 ;//空语句
319 3 }
320 2 }
321 1 }
322 //LCD1602写一个字节
323 void WriteByte_LCD1602(uint dat)
324 {
325 1 LCDRW = 0;
326 1 if(dat&0x01)
327 1 {
328 2 D0=1;
329 2 }else
330 1 {
331 2 D0=0;
332 2 }
333 1 if(dat&0x02)
334 1 {
335 2 D1=1;
336 2 }else
337 1 {
338 2 D1=0;
339 2 }
340 1 if(dat&0x04)
341 1 {
342 2 D2=1;
343 2 }else
344 1 {
345 2 D2=0;
346 2 }
347 1 if(dat&0x08)
348 1 {
349 2 D3=1;
350 2 }else
351 1 {
352 2 D3=0;
353 2 }
354 1 if(dat&0x10)
355 1 {
356 2 D4=1;
357 2 }else
358 1 {
359 2 D4=0;
360 2 }
361 1 if(dat&0x20)
362 1 {
363 2 D5=1;
364 2 }else
365 1 {
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 7
366 2 D5=0;
367 2 }
368 1 if(dat&0x40)
369 1 {
370 2 D6=1;
371 2 }else
372 1 {
373 2 D6=0;
374 2 }
375 1 if(dat&0x80)
376 1 {
377 2 D7=1;
378 2 }else
379 1 {
380 2 D7=0;
381 2 }
382 1 }
383 //写命令
384 void Write_Com(uchar com)
385 {
386 1 LCDRS = 0;
387 1 WriteByte_LCD1602(com);
388 1 Delay_LCD1602(5);
389 1 LCDEN = 1;
390 1 Delay_LCD1602(5);
391 1 LCDEN = 0;
392 1 }
393 //写数据
394 void Write_Data(uchar dat)
395 {
396 1 LCDRS = 1;
397 1 WriteByte_LCD1602(dat);
398 1 Delay_LCD1602(5);
399 1 LCDEN = 1;
400 1 Delay_LCD1602(5);
401 1 LCDEN = 0;
402 1 }
403 //初始化LCD1602
404 void Init_LCD1602()
405 {
406 1 Write_Com(0x38); //屏幕初始化
407 1 Write_Com(0x0c); //打开显示 无光标 闪烁
408 1 Write_Com(0x06); //指针右移
409 1 Write_Com(0x01); //清屏
410 1 }
411 //设置显示位置
412 void Select_Pos(uchar x,uchar y)
413 {
414 1 if(x == 0)
415 1 {
416 2 Write_Com(0x80 y);
417 2 }else
418 1 {
419 2 Write_Com(0xc0 y);
420 2 }
421 1 }
422 void LCD_Write_String(uchar x,uchar y,uchar *s)
423 {
424 1 Select_Pos(x,y);
425 1 while(*s)
426 1 {
427 2 Write_Data(*s);
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 8
428 2 s ;
429 2 }
430 1 }
431 void LCD_Write_Char(uchar x,uchar y,uint s,uchar l)
432 {
433 1 Select_Pos(x,y);
434 1 if(l>=5)
435 1 {
436 2 Write_Data(0x30 s/10000%10);
437 2 }
438 1 if(l>=4)
439 1 {
440 2 Write_Data(0x30 s/1000%10);
441 2 }
442 1 if(l>=3)
443 1 {
444 2 Write_Data(0x30 s/100%10);
445 2 }
446 1 if(l>=2)
447 1 {
448 2 Write_Data(0x30 s/10%10);
449 2 }
450 1 if(l>=1)
451 1 {
452 2 Write_Data(0x30 s%10);
453 2 }
454 1 }
455 uint Cal(uchar sect,uchar hourt,uchar mint)
456 {
457 1 deng=(hourt*6 mint)*26;
458 1 if(sec<=25)
459 1 {
460 2 price=1000 deng;
461 2
462 2 }else if((sec>25)&&(sec<=35))
463 1 {
464 2 price=((sec-25)*26 1000 deng); //放大100倍
465 2 }else
466 1 {
467 2 price=((sec-25)*26 1000)*3/2 deng; //放大100倍
468 2 }
469 1 return price;
470 1 }
*** WARNING C280 IN LINE 455 OF main.c: 'sect': unreferenced local variable
471
472 //正常数据显示
473 void Display_LCD1602SET()
474 {
475 1 uchar i;
476 1 uchar temprice;
477 1 for(i=0;i<5;i )
478 1 {
479 2 dofly[i]=read_add(i); //低电平灯亮
480 2 }
481 1 LCD_Write_Char(0,0,dofly[0]/10,2); //显示时间
482 1 LCD_Write_String(0,2,".");
483 1 LCD_Write_Char(0,3,dofly[0]%10,1); //显示时间
484 1
485 1 LCD_Write_String(0,4," ");
486 1 LCD_Write_Char(0,5,dofly[1]/10,1);
487 1 LCD_Write_Char(0,6,dofly[1]%10,1);
488 1 LCD_Write_String(0,7,":");
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 9
489 1 LCD_Write_Char(0,8,dofly[2]/10,1);
490 1 LCD_Write_Char(0,9,dofly[2]%10,1); //显示时间
491 1 LCD_Write_String(0,10," ");
492 1 LCD_Write_Char(0,11,dofly[3],2); //显示时间
493 1 LCD_Write_String(0,13,".");
494 1 LCD_Write_Char(0,14,dofly[4],2); //显示时间
495 1 LCD_Write_String(1,0," ");
496 1 }
*** WARNING C280 IN LINE 476 OF main.c: 'temprice': unreferenced local variable
497 //正常数据显示
498 void Display_LCD1602()
499 {
500 1 ds1302_read_time(); //读取数据
501 1 dis_time_buf[14]=(time_buf[5]>>4); //读取分
502 1 dis_time_buf[15]=(time_buf[5]&0x0f);
503 1 dis_time_buf[10]=(time_buf[6]>>4); //读取秒
504 1 dis_time_buf[11]=(time_buf[6]&0x0f);
505 1
506 1 LCD_Write_String(0,0,"TIME:");
507 1 LCD_Write_Char(0,5,dhour/10,1);
508 1 LCD_Write_Char(0,6,dhour%10,1);
509 1 LCD_Write_String(0,7,":");
510 1 LCD_Write_Char(0,8,dmin/10,1);
511 1 LCD_Write_Char(0,9,dmin%10,1); //显示时间
512 1
513 1
514 1
515 1 /*
516 1 LCD_Write_String(0,0,"TIME:");
517 1 LCD_Write_Char(0,5,dis_time_buf[14],1);
518 1 LCD_Write_Char(0,6,dis_time_buf[15],1);
519 1 LCD_Write_String(0,7,":");
520 1 LCD_Write_Char(0,8,dis_time_buf[10],1);
521 1 LCD_Write_Char(0,9,dis_time_buf[11],1); //显示时间
522 1 */
523 1 LCD_Write_String(0,11,"S:");
524 1 if(flag==1)
525 1 {
526 2 LCD_Write_String(0,13,"STA");
527 2 }else
528 1 {
529 2 LCD_Write_String(0,13,"END");
530 2 }
531 1 LCD_Write_String(1,0,"S:");
532 1 LCD_Write_String(1,6,"P:");
533 1 LCD_Write_String(1,13," ");
534 1 if(start!=0)
535 1 {
536 2 if(flag!=0) //正在运行
537 2 {
538 3 endT=(dis_time_buf[14]*10 dis_time_buf[15])*60 (dis_time_buf[10]*10 dis_time_buf[11]);
539 3 }
540 2 sec=endT-startT;
541 2 LCD_Write_Char(1,2,sec/10,2); //显示时间
542 2 LCD_Write_String(1,4,".");
543 2 LCD_Write_Char(1,5,sec%10,1); //显示时间
544 2 }
545 1
546 1
547 1 LCD_Write_Char(1,8,price/100,2); //显示时间
548 1 LCD_Write_String(1,10,".");
549 1 LCD_Write_Char(1,11,price%100,2); //显示时间
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 10
550 1
551 1 }
552 /****************************LCD1602函数END*******************************/
553
554
555
556 //扫描按键
557 uchar Scan_Key(void)
558 {
559 1 static uchar key_up = 1; //按键松开标志
560 1 if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0||Key5==0))
561 1 {
562 2 Delay_ms(10); //去抖动
563 2 key_up = 0; //更改标志位
564 2 if(Key1==0)
565 2 {
566 3 return 1;
567 3 }else if(Key2==0)
568 2 {
569 3 return 2;
570 3 }else if(Key3==0)
571 2 {
572 3 return 3;
573 3 }else if(Key4==0)
574 2 {
575 3 return 4;
576 3 }else if(Key5==0)
577 2 {
578 3 return 5;
579 3 }
580 2
581 2 }else if(Key1==1&&Key2==1&&Key3==1&&Key4==1&&Key5==1)
582 1 {
583 2 key_up = 1;
584 2 }
585 1 return 0; //无按键按下
586 1 }
587
588
589
590 //主函数
591 int main(void)
592 {
593 1 uchar i;
594 1
595 1 Init_LCD1602(); //初始化LCD1602
596 1 ds1302_init(); //DS1302初始化
597 1 LED=1;
598 1 LCD_Write_String(4,0,"WELCOME");
599 1
600 1
601 1
602 1
603 1
604 1
605 1 Delay_ms(1000); //系统准备时间
606 1 while(1)
607 1 {
608 2
609 2 key = Scan_Key();
610 2 if(key==1)
611 2 {
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 11
612 3 if(mode==0)
613 3 {
614 4 flag = 1;
615 4 startT=(dis_time_buf[14]*10 dis_time_buf[15])*60 (dis_time_buf[10]*10 dis_time_buf[11]);
616 4 //LCD_Write_Char(1,2,start,4); //显示时间
617 4 LED=0;
618 4 }
619 3
620 3 }
621 2 if(key==2)
622 2 {
623 3 if(flag==1)
624 3 {
625 4 flag = 0;
626 4 LED=1;
627 4 dofly[0]=sec;
628 4 dofly[1]=dhour;
629 4 dofly[2]=dmin;
630 4 dofly[3]=price/100;
631 4 dofly[4]=price%100;
632 4 for(i=0;i<5;i )
633 4 {
634 5 write_add(i,dofly[i]); //向0单元写入数据0fH,
635 5 delay1(100);
636 5 }
637 4 }
638 3 }
639 2 if(key==3)
640 2 {
641 3 dmin =10;
642 3 if(dmin==60)
643 3 {
644 4 dmin=0;
645 4 dhour =1;
646 4 }
647 3 }
648 2 if(key==4)
649 2 {
650 3 mode=~mode;
651 3 }
652 2
653 2 if(mode==0)
654 2 {
655 3 Cal(sec,dhour,dmin);
656 3 Display_LCD1602();
657 3 }else
658 2 {
659 3 Display_LCD1602SET();
660 3 }
661 2 }
662 1 return 0;
663 1 }
*** WARNING C294 IN LINE 662 OF main.c: unreachable code
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1919 ----
CONSTANT SIZE = 55 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 61 8
IDATA SIZE = ---- ----
C51 COMPILER V9.59.0.0 MAIN 06/04/2020 19:30:23 PAGE 12
BIT SIZE = 2 ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 3 WARNING(S), 0 ERROR(S)
好例子网口号:伸出你的我的手 — 分享!
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论