|
大家可以參考一下
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (21.84 KB, 下載次數(shù): 96)
下載附件
2019-7-29 16:49 上傳
單片機(jī)源程序如下:
- #include <reg52.h> //調(diào)用單片機(jī)頭文件
- #define uchar unsigned char //無(wú)符號(hào)字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無(wú)符號(hào)整型 宏定義 變量范圍0~65535
- uchar d_miao,d_fen = 0,d_shi;
- uchar flag_bai_hei; //白天的晚上的標(biāo)志位
- uchar value;
- uint bai_3l_price = 60; //白天3千米內(nèi)的單價(jià) 6元
- uint bai_3w_price = 18; //白天3千米外的單價(jià)/千米 1.8元
- uint bai_wait_price = 5; //白天等待時(shí)的單價(jià)/分鐘 0.5元
- uint wan_3l_price = 70; //晚上3千米內(nèi)的單價(jià)/千米 7元
- uint wan_3w_price = 22; //晚上3千米外的單價(jià)/千米 2.2元
- uint wan_wait_price = 10; //晚上等待時(shí)的單價(jià)/分鐘 1元
- uint distance = 0; //行使的距離
- uint zong_jia; //總的價(jià)
- bit flag_200ms = 0;
- bit flag_1s ;
- bit flag_time_en = 0;
- uchar flag_time_xs = 1; //顯示時(shí)間和等待時(shí)間切換
- uchar i;
- sbit clk = P2^0; //ds1302時(shí)鐘線定義
- sbit io = P2^1; //數(shù)據(jù)線
- sbit rst = P2^2; //復(fù)位線
- //秒 分 時(shí) 日 月 年 星期
- uchar code write_add[]={0x80,0x82,0x84,0x86,0x88,0x8c,0x8a}; //寫(xiě)地址
- uchar code read_add[] ={0x81,0x83,0x85,0x87,0x89,0x8d,0x8b}; //讀地址
- uchar code init_ds[] ={0x55,0x17,0x15,0x01,0x01,0x13,0x13};
- uchar idata miao,fen,shi,ri,yue,week,nian;
- #include "lcd1602.h"
- /***********************1ms延時(shí)函數(shù)*****************************/
- void delay_1ms(uint q)
- {
- uint i,j;
- for(i=0;i<q;i++)
- for(j=0;j<120;j++);
- }
- #include "iic.h"
- void write_iic_data()
- {
- write_24c02(0,flag_bai_hei);
- delay_1ms(10);
- write_24c02(1,bai_3l_price % 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(2,bai_3l_price / 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(3,bai_3w_price % 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(4,bai_3w_price / 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(5,bai_wait_price % 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(6,bai_wait_price / 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(7,wan_3l_price % 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(8,wan_3l_price / 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(9,wan_3w_price % 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(10,wan_3w_price / 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(11,wan_wait_price % 256); //保存數(shù)據(jù)
- delay_1ms(10);
- write_24c02(12,wan_wait_price / 256); //保存數(shù)據(jù)
- delay_1ms(10);
- }
- /****************自動(dòng)初始化保存的數(shù)據(jù)*******************/
- void zidong_chud_shifa_iic()
- {
- static uchar value;
- // value = read_24c02(100);
- value = read_24c02(100);
- if(value != 47) //新的單片機(jī)初始單片機(jī)內(nèi)問(wèn)EEPOM
- {
- value = 47;
- bai_3l_price = 60; //白天3千米內(nèi)的單價(jià) 6元
- bai_3w_price = 18; //白天3千米外的單價(jià)/千米 1.8元
- bai_wait_price = 5; //白天等待時(shí)的單價(jià)/分鐘 0.5元
-
- wan_3l_price = 70; //晚上3千米內(nèi)的單價(jià)/千米 7元
- wan_3w_price = 22; //晚上3千米外的單價(jià)/千米 2.2元
- wan_wait_price = 10; //晚上等待時(shí)的單價(jià)/分鐘 1元
- write_iic_data();
- write_24c02(100,value); //保存數(shù)據(jù)
- }
- delay_1ms(500);
- }
- /****************讀出來(lái)保存的數(shù)據(jù)**********************/
- void read_iic_data()
- {
- flag_bai_hei = read_24c02(0);
- bai_3l_price = read_24c02(2);
- bai_3l_price = bai_3l_price * 256 + read_24c02(1);
- bai_3w_price = read_24c02(4);
- bai_3w_price = bai_3w_price * 256 + read_24c02(3);
- bai_wait_price = read_24c02(6);
- bai_wait_price = bai_wait_price * 256 + read_24c02(5);
- wan_3l_price = read_24c02(8);
- wan_3l_price = wan_3l_price * 256 + read_24c02(7);
- wan_3w_price = read_24c02(10);
- wan_3w_price = wan_3w_price * 256 + read_24c02(9);
- wan_wait_price = read_24c02(12);
- wan_wait_price = wan_wait_price * 256 + read_24c02(11);
- }
- /****************獨(dú)立按鍵處理函數(shù)************************/
- uchar key_can;
- //按鍵處理函數(shù)
- sbit Key1 = P3^4;//時(shí)間清零/確定
- sbit Key2 = P3^2;//減小
- sbit Key3 = P3^0;//路程增加
- sbit Key4 = P1^7;//增加
- sbit Key5 = P1^3;//設(shè)置
- sbit Key6 = P1^5;//路程清零
- //返回按鍵值
- //mode:0,不支持連續(xù)按;1,支持連續(xù)按;
- //0,沒(méi)有任何按鍵按下
- //1,KEY0按下
- //2,KEY1按下
- //3,KEY2按下
- //4,KEY3按下 WK_UP
- //注意此函數(shù)有響應(yīng)優(yōu)先級(jí),KEY0>KEY1>KEY2>KEY3!!
- //========================================================================
- // 函數(shù): uchar Key_Scan()
- // 應(yīng)用: temp=uchar Key_Scan();
- // 描述: 按鍵掃描并返回按下的鍵值
- // 參數(shù): NONE
- // 返回: 按下的鍵值
- // 版本: VER1.0
- // 日期: 2015-05-29
- // 備注: 該函數(shù)帶松手檢測(cè),按下鍵返回一次鍵值后返回0,直至第二次按鍵按下
- //========================================================================
- uchar Key_Scan()
- {
- static uchar key_up=1;//按鍵按松開(kāi)標(biāo)志
- if(key_up&&(Key1==0||Key2==0||Key3==0||Key4==0||Key5==0||Key6==0))
- {
- delay_1ms(10);//去抖動(dòng)
- key_up=0;
- if(Key1==0) return 1;
- else if(Key2==0)return 2;
- else if(Key3==0)return 3;
- else if(Key4==0)return 4;
- else if(Key5==0)return 5;
- else if(Key6==0)return 6;
- }
- else if(Key1==1&&Key2==1&&Key3==1&&Key4==1&&Key5==1&&Key6==1)
- key_up=1;
- return 20;// 無(wú)按鍵按下
- }
- /*************寫(xiě)一個(gè)數(shù)據(jù)到對(duì)應(yīng)的地址里***************/
- void write_ds1302(uchar add,uchar dat)
- {
- rst = 1; //把復(fù)位線拿高
- for(i=0;i<8;i++)
- { //低位在前
- clk = 0; //時(shí)鐘線拿低開(kāi)始寫(xiě)數(shù)據(jù)
- io = add & 0x01;
- add >>= 1; //把地址右移一位
- clk = 1; //時(shí)鐘線拿高
- }
- for(i=0;i<8;i++)
- {
- clk = 0; //時(shí)鐘線拿低開(kāi)始寫(xiě)數(shù)據(jù)
- io = dat & 0x01;
- dat >>= 1; //把數(shù)據(jù)右移一位
- clk = 1; //時(shí)鐘線拿高
- }
- rst = 0; //復(fù)位線合低
- clk = 0;
- io = 0;
- }
- /*************從對(duì)應(yīng)的地址讀一個(gè)數(shù)據(jù)出來(lái)***************/
- uchar read_ds1302(uchar add)
- {
- uchar value,i;
- rst = 1; //把復(fù)位線拿高
- for(i=0;i<8;i++)
- { //低位在前
- clk = 0; //時(shí)鐘線拿低開(kāi)始寫(xiě)數(shù)據(jù)
- io = add & 0x01;
- add >>= 1; //把地址右移一位
- clk = 1; //時(shí)鐘線拿高
- }
- for(i=0;i<8;i++)
- {
- clk = 0; //時(shí)鐘線拿低開(kāi)始讀數(shù)據(jù)
- value >>= 1;
- if(io == 1)
- value |= 0x80;
- clk = 1; //時(shí)鐘線拿高
- }
- rst = 0; //復(fù)位線合低
- clk = 0;
- io = 0;
- return value; //返回讀出來(lái)的數(shù)據(jù)
- }
- /*************把要的時(shí)間 年月日 都讀出來(lái)***************/
- void read_time()
- {
- miao = read_ds1302(read_add[0]); //讀秒
- fen = read_ds1302(read_add[1]); //讀分
- shi = read_ds1302(read_add[2]); //讀時(shí)
- ri = read_ds1302(read_add[3]); //讀日
- yue = read_ds1302(read_add[4]); //讀月
- nian = read_ds1302(read_add[5]); //讀年
- week = read_ds1302(read_add[6]); //讀星期
- }
- /*************把要寫(xiě)的時(shí)間 年月日 都寫(xiě)入ds1302里***************/
- void write_time()
- {
- write_ds1302(0x8e,0x00); //打開(kāi)寫(xiě)保護(hù)
- write_ds1302(write_add[0],miao); //寫(xiě)秒
- write_ds1302(write_add[1],fen); //寫(xiě)分
- write_ds1302(write_add[2],shi); //寫(xiě)時(shí)
- write_ds1302(write_add[3],ri); //寫(xiě)日
- write_ds1302(write_add[4],yue); //寫(xiě)月
- write_ds1302(write_add[5],nian); //寫(xiě)星期
- write_ds1302(write_add[6],week); //寫(xiě)年
- write_ds1302(0x8e,0x80); //關(guān)閉寫(xiě)保護(hù)
- }
- /*************把數(shù)據(jù)保存到ds1302 RAM中**0-31*************/
- void write_ds1302ram(uchar add,uchar dat)
- {
- add <<= 1; //地址是從第二位開(kāi)始的
- add &= 0xfe; //把最低位清零 是寫(xiě)的命令
- add |= 0xc0; //地址最高兩位為 1
- write_ds1302(0x8e,0x00);
- write_ds1302(add,dat);
- write_ds1302(0x8e,0x80);
- }
- /*************把數(shù)據(jù)從ds1302 RAM讀出來(lái)**0-31*************/
- uchar read_ds1302ram(uchar add)
- {
- add <<= 1; //地址是從第二位開(kāi)始的
- add |= 0x01; //把最高位置1 是讀命令
- add |= 0xc0; //地址最高兩位為 1
- return(read_ds1302(add));
- }
- /**********************設(shè)置ds1302時(shí)間函數(shù)**********************/
- void set_ds1302time(uchar num,uchar *shi,uchar dat) //調(diào)時(shí)
- {
- if(num == 1)
- {
- *shi+=0x01;
- if((*shi & 0x0f) >= 0x0a)
- *shi = (*shi & 0xf0) + 0x10;
- if(*shi >= dat)
- *shi = 0;
- }
- else
- {
- if(*shi == 0x00)
- *shi = dat;
- if((*shi & 0x0f) == 0x00)
- *shi = (*shi | 0x0a) - 0x10;
- *shi -=0x01 ;
- }
- }
- /*************初始化ds1302時(shí)間***************/
- void init_ds1302()
- {
- uchar i;
- rst = 0; //第一次讀寫(xiě)數(shù)據(jù)時(shí)要把IO品拿低
- clk = 0;
- io = 0;
- i = read_ds1302ram(30);
- if(i != 3)
- {
- i = 3;
- write_ds1302ram(30,i);
- write_ds1302(0x8e,0x00); //打開(kāi)寫(xiě)保護(hù)
- for(i=0;i<7;i++)
- write_ds1302(write_add[i],init_ds[i]); //把最高位值0 允許ds1302工作
- write_ds1302(0x8e,0x80); //關(guān)寫(xiě)保護(hù)
- }
- read_time(); //讀時(shí)間
- if(miao >= 0x60)
- {
- write_ds1302(0x8e,0x00); //打開(kāi)寫(xiě)保護(hù)
- write_ds1302(write_add[0],init_ds[0]); //把最高位值0 允許ds1302工作
- write_ds1302(0x8e,0x80); //關(guān)寫(xiě)保護(hù)
-
- }
- }
- void init_ds1302_io()
- {
- rst = 0; //第一次讀寫(xiě)數(shù)據(jù)時(shí)要把IO品拿低
- clk = 0;
- io = 0;
- }
- #include "menu.h"
- /*********************對(duì)應(yīng)菜單內(nèi)的處理函數(shù)******************/
- void menu_dis()
- {
- if(menu_1 == 0)
- {
- if(key_can == 3) //按鍵模擬加里程 每按一下加0.1KM
- {
- distance ++;
- if(flag_time_xs != 0)
- write_sfm4(1,0,distance); //顯示里程
- }
- if(key_can == 6) //清零 從新計(jì)價(jià)
- {
- flag_time_en = 0;
- d_shi = 0;
- d_fen = 0;
- d_miao = 0;
- zong_jia = 0;
- distance = 0;
- }
- if(key_can == 1) //時(shí)間和等待的時(shí)間的切換
- {
- flag_time_xs ++; //為1顯示當(dāng)前時(shí)間
- if(flag_time_xs > 2)
- flag_time_xs = 0;
- if(flag_time_xs == 0) //顯示時(shí)間
- {
- write_string(1,0," : : W: ");
- write_string(2,0," 20 - - ");
- }
- if(flag_time_xs == 1)//顯示當(dāng)前時(shí)間
- {
- init_1602_dis_csf();
- }
- if(flag_time_xs == 2)//顯示等待時(shí)間
- {
- write_string(2,0," ");
- }
- }
- // write_sfm2(1,0,flag_time_xs);
- if(key_can == 2) //按鍵模擬控制停車(chē)計(jì)時(shí)
- {
- flag_time_en = ~flag_time_en;
- }
- if(flag_200ms == 1)
- {
- // flag_200ms = 0;
- if(distance <= 30)//3公里內(nèi)的價(jià)格
- {
- if(flag_bai_hei == 0)
- {
- if(d_fen <= 3)
- zong_jia = bai_3l_price;
- else
- zong_jia = bai_3l_price + (d_shi * 60 + d_fen - 3) * bai_wait_price;
- }
- else
- {
- if(d_fen <= 3)
- zong_jia = wan_3l_price;
- else
- zong_jia = wan_3l_price + (d_shi * 60 + d_fen - 3) * wan_wait_price;
- }
-
- }else //3公里外的價(jià)格
- {
- if(flag_bai_hei == 0)
- {
- if(d_fen <= 3)
- zong_jia = bai_3l_price + bai_3w_price * (distance - 30) / 10 ;
- else
- zong_jia = bai_3l_price + bai_3w_price * (distance - 30) / 10 + (d_shi * 60 + d_fen - 3) * bai_wait_price;
- }
- else
- {
- if(d_fen <= 3)
- zong_jia = wan_3l_price + wan_3w_price * (distance - 30) / 10 ;
- else
- zong_jia = wan_3l_price + wan_3w_price * (distance - 30) / 10 + (d_shi * 60 + d_fen - 3) * wan_wait_price;
- }
- }
- if(flag_time_xs == 1) //顯示當(dāng)前的時(shí)間
- {
- write_sfm2_ds1302(2,0,shi); //顯示時(shí)
- write_data(':');
- write_sfm2_ds1302(2,3,fen); //顯示時(shí)
- write_data(':');
- write_sfm2_ds1302(2,6,miao); //顯示秒
- write_sfm4(1,10,zong_jia);
- write_sfm4(1,0,distance);
- if(flag_bai_hei == 0)
- write_sfm2_dian(2,9,bai_3w_price);
- else
- write_sfm2_dian(2,9,wan_3w_price);
- write_zifu(1,15,0x5c); //¥
- write_zifu(2,12,0x5c); //¥
- }
- else if(flag_time_xs == 2) //顯示等待時(shí)間
- {
- write_sfm2(2,1,d_fen); //顯示分
- write_data(':');
- write_sfm2(2,4,d_miao); //顯示秒
- write_sfm4(1,10,zong_jia);
- write_sfm4(1,0,distance);
- if(flag_bai_hei == 0)
- write_sfm2_dian(2,9,bai_3w_price); //顯示白天每公里的價(jià)格
- else
- write_sfm2_dian(2,9,wan_3w_price); //顯示晚上每公里的價(jià)格
- write_zifu(1,15,0x5c); //¥
- write_zifu(2,12,0x5c); //¥
- }
- else //顯示當(dāng)前的時(shí)間
- {
- write_sfm2_ds1302(1,2,shi); //顯示時(shí)
- write_sfm2_ds1302(1,5,fen); //顯示分
- write_sfm2_ds1302(1,8,miao); //顯示秒
- write_sfm1(1,14,week); //顯示星期
- write_sfm2_ds1302(2,3,nian); //顯示年
- write_sfm2_ds1302(2,6,yue); //顯示月
- write_sfm2_ds1302(2,9,ri); //顯示日
-
- }
- }
- }
- }
- /*******************停車(chē)計(jì)時(shí)函數(shù) *****************/
- void jishu_chashu()
- {
- if((flag_1s == 1) && (flag_time_en == 1))
- {
- flag_1s = 0;
- d_miao++; //秒鐘加1
- if(d_miao >= 60)
- {
- d_miao = 0;
- d_fen ++; //分鐘加1
- if(d_fen >= 60)
- {
- d_fen = 0;
- d_shi++;
- if(d_shi >= 24)
- {
- d_shi = 0;
- }
- }
- }
-
- }
- }
- /*************定時(shí)器0初始化程序***************/
- void time_init()
- {
- EA = 1; //開(kāi)總中斷
- TMOD = 0X01; //定時(shí)器0、工作方式1
- ET0 = 1; //開(kāi)定時(shí)器0中斷
- TR0 = 1; //允許定時(shí)器0定時(shí)
- }
- /******************主函數(shù)*******************/
- void main()
- {
- P0 = P1 = P2 = P3 = 0XFF; //讓IO口全部輸出高電平
- init_1602(); //初始化1602液晶
- init_1602_dis_csf(); //初始化1602液晶顯示
- zidong_chud_shifa_iic();
- read_iic_data(); //把保存的數(shù)據(jù)讀出來(lái)
- time_init(); //定時(shí)器初始化
- init_menu(); //菜單程序
- init_ds1302_io();
- init_ds1302(); //ds1302初始化
- while(1)
- {
- key_can=Key_Scan(); //按鍵程序
- menu_dis();
- if(key_can < 20)
- key_with();
- jishu_chashu(); //停車(chē)計(jì)時(shí)函數(shù)
- if(flag_200ms == 1)
- {
- flag_200ms = 0;
- if(menu_1 == 0)
- read_time(); //讀時(shí)間
- if((shi >= 0x22) || (shi <= 8))
- flag_bai_hei = 1; //晚上模式
- else
- flag_bai_hei = 0; //白天模式
- }
- }
- }
- /*************定時(shí)器0中斷服務(wù)程序***************/
- void time0_int() interrupt 1
- {
- static uchar value;
- TH0 = 0x3c;
- TL0 = 0xb0; // 50ms
- value ++;
- if(value % 4 == 0)
- flag_200ms = 1;
- if(value >= 20)
- {
- flag_1s = 1;
- value = 0;
- }
- }
復(fù)制代碼
所有資料51hei提供下載:
出租車(chē)計(jì)價(jià)器的設(shè)計(jì).zip
(190.06 KB, 下載次數(shù): 72)
2019-7-29 11:39 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評(píng)分
-
查看全部評(píng)分
|