- #include<reg52.h> //調用單片機頭文件
- #include "DS18B20.h"
- #include <stdio.h>
- #define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
- #include "Data.h"
- #include "DS1302.h"
- #include "AT24C02.h"
- sbit COUNT_IN=P3^2; //脈沖輸入端口
- //定義1602相關管腳
- sbit rs=P1^4; //寄存器選擇信號 H:數據 L:指令
- sbit en=P1^0; //片選信號 下降沿觸發
- //鍵盤定義
- sbit K1=P3^4; //設置時間
- sbit K3=P3^6; //減按鍵
- sbit K2=P3^5; //加按鍵
- sbit K4=P3^7; //設置半徑安全距離
- sbit BEEP=P3^0; //蜂鳴器外接端口
- uint count;
- unsigned long Velocity,Mileage;
- uchar code tab1[]={" / / : "}; //時間 年 月 日 時 分 星期
- uchar code tab2[]={" 0.000km 00 "}; //里程 速度
- uchar code tab3[]={"Wheel Radius cm"}; // 半徑
- uchar code tab4[]={"Safe Speed km/h"}; // 安全速度
- uchar code tab5[]={"Sec : "}; // 在按鍵設置的時候會顯示秒
- uchar Display_Buff[30]; //顯示
-
- uchar Mode=0;
- uchar bike_set=0;
- uchar a;
- char RADIUS,SAFE_SPEED;
- bit LED_SEC;
- uchar before_sec;
- //自定義字符RAM
- uchar code num[]={
- 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//1
- 0x1f,0x01,0x01,0x1f,0x10,0x10,0x1f,0x00,//2
- 0x1f,0x01,0x01,0x1f,0x01,0x01,0x1f,0x00,//3
- 0x11,0x11,0x11,0x1f,0x01,0x01,0x01,0x00,//4
- 0x1f,0x10,0x10,0x1f,0x01,0x01,0x1f,0x00,//5
- 0x1f,0x10,0x10,0x1f,0x11,0x11,0x1f,0x00,//6
- 0x1f,0x01,0x01,0x01,0x01,0x01,0x01,0x00,//7 顯示星期 依次為周一到周日
- };
- void READS();
- void SETS();
- void delay(uint x)
- {
- uint i,j;
- for(i=0;i<x;i++)
- for(j=0;j<110;j++);
- }
- void init()
- {
- IT0=1; //INT0負跳變觸發
- TMOD=0x01;//定時器工作于方式1
- TH0=0x3c; //50ms
- TL0=0xb0;
- EA=1; //CPU開中斷總允許
- ET0=1;//開定時中斷
- EX0=1;//開外部INTO中斷
- TR0=1;//啟動定時
- }
- /********液晶寫入指令函數與寫入數據函數,以后可調用**************/
- void write_1602com(uchar com)//****液晶寫入指令函數****
- {
- rs=0;//把寄存器置為指令
- P0=com;//送入數據
- delay(1);
- en=1;//拉高使能端,為制造有效的下降沿做準備
- delay(1);
- en=0;//en由高變低,產生下降沿,液晶執行命令
- }
- void write_1602dat(uchar dat)//***液晶寫入數據函數****
- {
- rs=1;//把寄存器置為數據
- P0=dat;//送入數據
- delay(1);
- en=1; //en置高電平,為制造下降沿做準備
- delay(1);
- en=0; //en由高變低,產生下降沿,液晶執行命令
- }
- void write_1602_Str(uchar *Str)
- {
- uchar i = 0;
-
- while (Str[i])
- {
- write_1602dat(Str[i++]);
- }
- }
- //自定義字符集
- void Lcd_ram() // 液晶寫數據。
- {
- uchar i,j,k=0;
- uchar temp=0x40;//設定CGRAM地址指令01000000(DB5~DB0含義)
- for(i=0;i<7;i++) //自定義7個字符
- {
- for(j=0;j<8;j++)
- {
- write_1602com(temp+j);
- write_1602dat(num[k]); //分別寫入CGRAM的字模
- k++;
- }
- temp=temp+8;
- }
- }
- void lcd_init()//***液晶初始化函數****
- {
- Lcd_ram();
- write_1602com(0x38);//設置液晶8位數據工作模式,2行,5×7
- write_1602com(0x0c);//整體顯示、開光標、不閃爍
- write_1602com(0x06);//設定輸入方式屏不移位
- write_1602com(0x01);//清除屏幕顯示
- write_1602com(0x80);//顯示固定符號從第一行第1個位置之后開始顯示
- for(a=0;a<16;a++)
- {
- write_1602dat(tab1[a]);//向液晶屏寫固定符號部分
- }
- write_1602com(0x80+0x40);//顯示固定符號寫入位置,從第2個位置后開始顯示
- for(a=0;a<16;a++)
- {
- write_1602dat(tab2[a]);//寫顯示固定符號
- }
- }
- void display() //液晶顯示部分
- {
- if(Mode==0&&bike_set==0)
- {
- //讀時間
- Ds1302_Read_Time();
- //顯示時間
- write_1602com(0x80);
- write_1602dat(0x30+time_buf1[1]/10); //顯示設置
- write_1602dat(0x30+time_buf1[1]%10);
- write_1602com(0x80+3);
- write_1602dat(0x30+time_buf1[2]/10);
- write_1602dat(0x30+time_buf1[2]%10);
- write_1602com(0x80+6);
- write_1602dat(0x30+time_buf1[3]/10);
- write_1602dat(0x30+time_buf1[3]%10);
- write_1602com(0x80+9);
- write_1602dat(0x30+time_buf1[4]/10);
- write_1602dat(0x30+time_buf1[4]%10);
- write_1602com(0x80+12);
- write_1602dat(0x30+time_buf1[5]/10);
- write_1602dat(0x30+time_buf1[5]%10);
- write_1602com(0x80+15);
- write_1602dat(time_buf1[7]-1);
-
-
- if(before_sec!=time_buf1[6])
- {
- before_sec=time_buf1[6];
- write_1602com(0x80+11);
- write_1602dat(':');
- LED_SEC=1;
- }
- if(LED_SEC==0)
- {
- write_1602com(0x80+11);
- write_1602dat(' ');
- }
- write_1602com(0x80+0x40);
- if(Mileage/1000000==0)
- write_1602dat(' ');
- else
- write_1602dat(0x30+Mileage/1000000);//數字+0x30得到該數字的LCD1602顯示碼
- if(Mileage%1000000/100000==0)
- write_1602dat(' ');
- else
- write_1602dat(0x30+Mileage%1000000/100000);//數字+0x30得到該數字的LCD1602顯示碼
- write_1602dat(0x30+Mileage%1000000%100000/10000);//數字+0x30得到該數字的LCD1602顯示碼
- write_1602com(0x80+0x40+4);
- write_1602dat(0x30+Mileage%1000000%100000%10000/1000);//數字+30得到該數字的LCD1602顯示碼
- write_1602dat(0x30+Mileage%1000000%100000%10000%1000/100);//數字+30得到該數字的LCD1602顯示碼
- write_1602dat(0x30+Mileage%1000000%100000%10000%1000%100/10);//數字+30得到該數字的LCD1602顯示碼
- SETS();
-
- write_1602com(0x80+0x40+10);
- write_1602dat(0x30+Velocity/10);
- write_1602dat(0x30+Velocity%10);//數字+30得到該數字的LCD1602顯示碼
-
- write_1602com(0x80+0x40+13);
- sprintf(Display_Buff, "%dC", Temperature);
- write_1602_Str(Display_Buff);
- }
- else if(Mode!=0)
- {
- switch(Mode)
- {
- case 1:
- write_1602com(0x80+0x40);//顯示固定符號寫入位置
- for(a=0;a<16;a++)
- {
- write_1602dat(tab5[a]);//寫顯示固定符號
- }
- write_1602com(0x80+0x40+14);
- write_1602dat(0x30+time_buf1[6]/10);
- write_1602dat(0x30+time_buf1[6]%10);
- write_1602com(0x0F); //打開閃爍
- write_1602com(0x80+1);
- break;
- case 2:
- write_1602com(0x80+4);
- break;
- case 3:
- write_1602com(0x80+7);
- break;
- case 4:
- write_1602com(0x80+10);
- break;
- case 5:
- write_1602com(0x80+13);
- break;
- case 6:
- write_1602com(0x80+0x40+15);
- break;
- case 7:
- write_1602com(0x80+15);
- break;
- case 8:
- write_1602com(0x0c);
- write_1602com(0x80);//顯示固定符號從第一行第1個位置之后開始顯示
- for(a=0;a<16;a++)
- {
- write_1602dat(tab1[a]);//向液晶屏寫固定符號部分
- }
- write_1602com(0x80+0x40);//顯示固定符號寫入位置,從第2個位置后開始顯示
- for(a=0;a<16;a++)
- {
- write_1602dat(tab2[a]);//寫顯示固定符號
- }
- break;
- }
- }
- else if(bike_set!=0)
- {
- switch(bike_set)
- {
- case 1:
- write_1602com(0x80);//顯示固定符號寫入位置
- for(a=0;a<16;a++)
- {
- write_1602dat(tab3[a]);//寫顯示固定符號
- }
- write_1602com(0x80+0x40);//顯示固定符號寫入位置
- for(a=0;a<16;a++)
- {
- write_1602dat(tab4[a]);//寫顯示固定符號
- }
- write_1602com(0x80+12);
- write_1602dat(0x30+RADIUS/10); //車輪半徑
- write_1602dat(0x30+RADIUS%10);
- write_1602com(0x80+0x40+10);
- write_1602dat(0x30+SAFE_SPEED/10); //安全速度
- write_1602dat(0x30+SAFE_SPEED%10);
- write_1602com(0x0F); //打開光標閃爍
- write_1602com(0x80+13);
- break;
- case 2:
- write_1602com(0x80+0x40+11);
- break;
- case 3:
- write_1602com(0x0c);
- write_1602com(0x80);//顯示固定符號從第一行第1個位置之后開始顯示
- for(a=0;a<16;a++)
- {
- write_1602dat(tab1[a]);//向液晶屏寫固定符號部分
- }
- write_1602com(0x80+0x40);//顯示固定符號寫入位置,從第2個位置后開始顯示
- for(a=0;a<16;a++)
- {
- write_1602dat(tab2[a]);//寫顯示固定符號
- }
- break;
- }
- }
- }
- void KEY()
- {
- if(bike_set==0&&K1==0) //按鍵部分與蜂鳴器
- {
- delay(20);
- if(bike_set==0&&K1==0)
- {
- BEEP=0;
- delay(50);
- BEEP=1;
- Mode++;
- display();
- if(Mode>=8)
- {
- Mode=0;
- Ds1302_Write_Time();
- }
- }
- while(bike_set==0&&K1==0);
- }
- if(K4==0&&Mode==0)
- {
- delay(20);
- if(K4==0&&Mode==0)
- {
- BEEP=0;
- delay(50);
- BEEP=1;
- bike_set++;
- display();
- if(bike_set>=3)
- {
- bike_set=0;
- SETS();
- }
- }
- while(Mode==0&&K4==0);
- }
- //+
- if(K2==0&&(Mode!=0||bike_set!=0))
- {
- delay(20);
- //調時
- if(K2==0&&(Mode!=0||bike_set!=0))
- {
- BEEP=0;
- delay(50);
- BEEP=1;
- switch(Mode)
- {
- case 1:
- time_buf1[1]++;
- if(time_buf1[1]>=100)
- time_buf1[1]=0;
- write_1602com(0x80);
- write_1602dat(0x30+time_buf1[1]/10);
- write_1602dat(0x30+time_buf1[1]%10);
- write_1602com(0x80+1);
- break;
- case 2:
- time_buf1[2]++;
- if(time_buf1[2]>=13)
- time_buf1[2]=1;
- write_1602com(0x80+3);
- write_1602dat(0x30+time_buf1[2]/10);
- write_1602dat(0x30+time_buf1[2]%10);
- write_1602com(0x80+4);
- break;
- case 3:
- time_buf1[3]++;
- if(time_buf1[3]>=YDay(time_buf1[1],time_buf1[2])+1)
- time_buf1[3]=1;
- write_1602com(0x80+6);
- write_1602dat(0x30+time_buf1[3]/10);
- write_1602dat(0x30+time_buf1[3]%10);
- write_1602com(0x80+7);
- break;
- case 4:
- time_buf1[4]++;
- if(time_buf1[4]>=24)
- time_buf1[4]=0;
- write_1602com(0x80+9);
- write_1602dat(0x30+time_buf1[4]/10);
- write_1602dat(0x30+time_buf1[4]%10);
- write_1602com(0x80+10);
- break;
- case 5:
- time_buf1[5]++;
- if(time_buf1[5]>=60)
- time_buf1[5]=0;
- write_1602com(0x80+12);
- write_1602dat(0x30+time_buf1[5]/10);
- write_1602dat(0x30+time_buf1[5]%10);
- write_1602com(0x80+13);
- break;
- case 6:
- time_buf1[6]++;
- if(time_buf1[6]>=60)
- time_buf1[6]=0;
- write_1602com(0x80+0x40+14);
- write_1602dat(0x30+time_buf1[6]/10);
- write_1602dat(0x30+time_buf1[6]%10);
- write_1602com(0x80+0x40+15);
- break;
- case 7:
- time_buf1[7]++;
- if(time_buf1[7]>=8)
- time_buf1[7]=1;
- write_1602com(0x80+15);
- write_1602dat(time_buf1[7]-1);
- write_1602com(0x80+15);
- break;
- }
- switch(bike_set)
- {
- case 1:
- RADIUS++;
- if(RADIUS>=71)
- RADIUS=0;
- write_1602com(0x80+12);
- write_1602dat(0x30+RADIUS/10);
- write_1602dat(0x30+RADIUS%10);
- write_1602com(0x80+13);
- break;
- case 2:
- SAFE_SPEED++;
- if(SAFE_SPEED>=100)
- SAFE_SPEED=0;
- write_1602com(0x80+0x40+10);
- write_1602dat(0x30+SAFE_SPEED/10);
- write_1602dat(0x30+SAFE_SPEED%10);
- write_1602com(0x80+0x40+11);
- break;
- }
- }
- while(K2==0);
- }
- //-
- if(K3==0&&(Mode!=0||bike_set!=0))
- {
- delay(20);
- //調時
- if(K3==0&&(Mode!=0||bike_set!=0))
- {
- BEEP=0;
- delay(50);
- BEEP=1;
- switch(Mode)
- {
- case 1:
- time_buf1[1]--;
- if(time_buf1[1]<0)
- time_buf1[1]=99;
- write_1602com(0x80);
- write_1602dat(0x30+time_buf1[1]/10);
- write_1602dat(0x30+time_buf1[1]%10);
- write_1602com(0x80+1);
- break;
- case 2:
- time_buf1[2]--;
- if(time_buf1[2]<=0)
- time_buf1[2]=12;
- write_1602com(0x80+3);
- write_1602dat(0x30+time_buf1[2]/10);
- write_1602dat(0x30+time_buf1[2]%10);
- write_1602com(0x80+4);
- break;
- case 3:
- time_buf1[3]--;
- if(time_buf1[3]<=0)
- time_buf1[3]=YDay(time_buf1[1],time_buf1[2]);
- write_1602com(0x80+6);
- write_1602dat(0x30+time_buf1[3]/10);
- write_1602dat(0x30+time_buf1[3]%10);
- write_1602com(0x80+7);
- break;
- case 4:
- time_buf1[4]--;
- if(time_buf1[4]<0)
- time_buf1[4]=23;
- write_1602com(0x80+9);
- write_1602dat(0x30+time_buf1[4]/10);
- write_1602dat(0x30+time_buf1[4]%10);
- write_1602com(0x80+10);
- break;
- case 5:
- time_buf1[5]--;
- if(time_buf1[5]<0)
- time_buf1[5]=59;
- write_1602com(0x80+12);
- write_1602dat(0x30+time_buf1[5]/10);
- write_1602dat(0x30+time_buf1[5]%10);
- write_1602com(0x80+13);
- break;
- case 6:
- time_buf1[6]--;
- if(time_buf1[6]<0)
- time_buf1[6]=59;
- write_1602com(0x80+0x40+14);
- write_1602dat(0x30+time_buf1[6]/10);
- write_1602dat(0x30+time_buf1[6]%10);
- write_1602com(0x80+0x40+15);
- break;
- case 7:
- time_buf1[7]--;
- if(time_buf1[7]<1)
- time_buf1[7]=7;
- write_1602com(0x80+15);
- write_1602dat(time_buf1[7]-1);
- write_1602com(0x80+15);
- break;
- }
- switch(bike_set)
- {
- case 1:
- RADIUS--;
- if(RADIUS<0)
- RADIUS=70;
- write_1602com(0x80+12);
- write_1602dat(0x30+RADIUS/10);
- write_1602dat(0x30+RADIUS%10);
- write_1602com(0x80+13);
- break;
- case 2:
- SAFE_SPEED--;
- if(SAFE_SPEED<0)
- SAFE_SPEED=99;
- write_1602com(0x80+0x40+10);
- write_1602dat(0x30+SAFE_SPEED/10);
- write_1602dat(0x30+SAFE_SPEED%10);
- write_1602com(0x80+0x40+11);
- break;
- }
- }
- while(K3==0);
- }
- if(K2==0&&K3==0&&Mode==0&bike_set==0)
- {
- BEEP=0;
- delay(100);
- BEEP=1;
- delay(100);
- BEEP=0;
- delay(100);
- BEEP=1;
- delay(100);
- Mileage=0;
- SETS();
- while(K2==0&&K3==0);
- }
- }
- void BJ_SAFE()
- {
- if(Velocity>SAFE_SPEED)
- {
- BEEP=0; //蜂鳴器響
- }
- else
- {
- BEEP=1; //蜂鳴器不響
- }
- }
- void main()
- {
- //初始化
- Ds1302_Init();
- lcd_init();
- initeeprom();
- //讀取初始參數
- READS();
- //定時器初始化
- // InitTimer0();
- init();
- lcd_init();
- before_sec=time_buf1[6];
-
- Temp_Get(); // 第一次采集是錯誤數據
- delay(200);
- Temp_Get(); // 第一次采集是錯誤數據
- delay(200);
- Temp_Get(); // 第一次采集是錯誤數據
- delay(200);
- Temp_Get(); // 第一次采集是錯誤數據
- delay(200);
- Temp_Get(); // 第一次采集是錯誤數據
-
- while(1) //等待定時器中斷
- {
- if(Mode==0&&bike_set==0)
- {
- display();
- BJ_SAFE();
- }
- KEY();
-
- Temp_Handle();
- }
- }
- void EXINT0() interrupt 0
- {
- count++;
- }
- void time0() interrupt 1
- {
- uchar m,n;
- TH0=0x3c;
- TL0=0xb0; //50ms
- m++;
- if(LED_SEC==1)
- {
- n++;
- if(n>=10)
- {
- n=0;
- LED_SEC=0;
- }
- }
- if(m>=10)
- {
- m=0;
-
- Mileage=Mileage+count*2*3.14*RADIUS/20/10;//里程數mileage=里程+記數值*輪周長/脈沖數/10
- Velocity=count*2*3.14*RADIUS/100000*3600*2/20;//總定時500ms
- count=0;
-
- }
- } // 處理數據,并顯示里程和速度
- //讀初值
- void READS()
- {
- uchar Mileage_H,Mileage_M,Mileage_L;
- delay(10);
- RADIUS=read_add(0x01);
- delay(10);
- SAFE_SPEED=read_add(0x02);
- delay(10);
- Mileage_H=read_add(0x03);
- delay(10);
- Mileage_M=read_add(0x04);
- delay(10);
- Mileage_L=read_add(0x05);
- Mileage=Mileage_H*100000+Mileage_M*1000+Mileage_L*10;
- }
- //寫初值
- void SETS()
- {
- delay(10);
- write_add(0x01,RADIUS);
- delay(10);
- write_add(0x02,SAFE_SPEED);
- /* Mileage_H=Mileage/10000; //123.4560
- Mileage_M=Mileage%10000/100;
- Mileage_L=Mileage%10000%100; */
- delay(10);
- write_add(0x03,Mileage/100000);
- delay(10);
- write_add(0x04,Mileage%100000/1000);
- delay(10);
- write_add(0x05,Mileage%100000%1000/10);
- }
復制代碼
這是主程序,這個程序主要用來測速,用的是光電傳感器,通過定時記脈沖來進行測速,用了一個外部存儲器,就是這里不怎么懂,希望大佬幫下忙,謝謝 |