1.設計目的
設計并制作一個測量模擬小車(如模擬自行車、摩托車等)的行駛速度及距離的裝置,且能分別顯示其行駛速度和行駛距離值。
2.方案簡介
硬件:
主控:stc89c52rc最小系統板
測速模塊:槽式光電測速傳感器,20柵格編碼盤
顯示:LCD12864
輸入:4*4鍵盤
電機:5v直流電機
電機驅動:L298N
報警模塊:放大電路、蜂鳴器、發光二極管
電源:單片機、LCD、傳感器供電由最小系統版供電;
電機驅動由3節3.7v鋰電池供電(電機驅動要和單片機共地)
因為都是用的模塊,除了信號放大電路,其他都是杜邦線連接單片機與各個模塊。
軟件:
大致思路是定時器T0輸出PWM波改變電機轉速,模擬小車轉動。外部中斷INT0記脈沖(下降沿)。測速方法為M法。有能力的可以嘗試改為M/T法,
單片機的定時器TI已經特意留出來了,具體程序見附件。
1.png (2.5 KB, 下載次數: 39)
下載附件
2019-1-11 20:00 上傳
單片機源程序如下:
- #include <reg52.h>
- #include <12864.c>
- #define T 500 //PWM波 周期50us
- typedef unsigned int u32;
- typedef unsigned short u16;
- typedef unsigned char u8 ;
- uchar key=0; //鍵值
- u8 speed_high=5; //最高速度設置
- u8 actual_speed=0; //實際速度
- u8 temp=0; //按鍵掃描中間值
- uchar key_flag=0;//按鍵標志
- unsigned int num_flag=0; // 按鍵次數標志
- unsigned char flag_h=0;
- unsigned char us500 = 0;//500us定時次數計數器
- unsigned char ms100_flag=0; //100ms定時到標志
- unsigned char s1_flag=0; //500ms標志
- unsigned char Time1L=0,Time1H=0,Time0L=0,Time0H=0;//PWM波定時器占空比高,低電平時間變量
- unsigned char maichong_count=0; //電機轉數脈沖計數器
- char NextState=1; //定時器高,低電平轉換標志
- double CurrentWaves = 0;
- double distance=0;
- u16 distant=0;
- u16 PWM_a=300;//占空比初值
- sbit IN1=P2^6;
- sbit IN2=P2^7;
- sbit PWM=P2^5; //PWM波輸出端口
- sbit bee=P3^7;
- uchar code Code[]="123A456B789C*0#D"; //鍵值碼
- uchar code Buff[]="0123456789"; //顯示字形碼
- uchar Buff1[4]={'0','0',' ','0'}; //第一行顯示緩沖區
- uchar Buff2[4]={'0','0',' ','0'}; // 第二行顯示緩沖區
- uchar Buff3[4]={'0','0',' ','0'}; // 第三行顯示緩沖區
- uchar Buff4[4]={'0','0',' ','0'}; // 第四行顯示緩沖區
- void keydown(void);
- void keyscan(void);
- void keyjudge(void);
- void disp(void);
- void a_count(void);
- void rnu(void);
- void stop(void);
- /**********************************************************/
- //延時一毫秒子程序
- void mDelay(uint Delay)
- { uint i;
- for(;Delay > 0;Delay--)
- for(i = 0;i < 110;i++);
- }
- /**********************************************************/
- //定時計數器0初始化
- void Init_T0()
- {
- TMOD=0x01; //定時器0模式設置
- Time1H=(65536-PWM_a)/256; //定時器0初值1
- Time1L=(65536-PWM_a)%256; // 定時器0初值1
- Time0H=(65536+PWM_a-T)/256; // 定時器0初值2
- Time0L=(65536+PWM_a-T)%256;// 定時器0初值2
- TH0=Time1H;
- TL0=Time1L;
- ET0=1;
- TR0=1;
- EX0=1; //外中斷0允許
- IT0=1; //外部中斷邊沿觸發方式
- NextState=1;
- PWM=1;
- }
- /**********************************************************/
- //電機啟動
- void run(void)
- {
- IN1=1;
- IN2=0;
- EA=0;
- Init_T0();
- EA=1;
- IN1=1;
- IN2=0;
- }
- /**********************************************************/
- //電機停止
- void stop()
- {
- IN1=0;
- IN2=0;
- PWM=0;
- ET0=0;
- TR0=0;
- EA=0;
- }
- /*************************************************************/
- //判斷鍵是否按下
- void keydown(void)
- {
- P1=0xF0;
- if(P1!=0xF0)
- {
- mDelay(20);
- keyscan();
- }
- }
- /**********************************************************/
- // 鍵掃描子程序
- void keyscan(void)
- {
- P1=0xF0; //行線為輸入,列線為輸出,并置列線輸出全為0
- temp=P1; //讀P1口
- temp=temp&0xF0;
- temp=~((temp>>4)|0xF0);
- if(temp==1)
- key=0;
- else if(temp==2)
- key=1;
- else if(temp==4)
- key=2;
- else if(temp==8)
- key=3;
- P1=0x0F; //列線為輸入,行線為輸出,并置行線輸出全為0
- temp=P1; //讀P1口
- temp=temp&0x0F;
- temp=~(temp|0xF0);
- if(temp==1)
- key=key+0;
- else if(temp==2)
- key=key+4;
- else if(temp==4)
- key=key+8;
- else if(temp==8)
- key=key+12;
- P1=0xF0;
- while(P1!=0XF0);
- {
- mDelay(5);
- }
- keyjudge(); //判斷按鍵功能
- }
- /*************************************************************/
- //按鍵功能判斷
- void keyjudge(void)
- {
- uchar a=Code[key];
- a=a-0x30;
- if(key==3)
- { Buff1[2]='>'; //按鍵指示A 顯示
- Buff2[2]=' '; //按鍵指示B 取消顯示
- Buff3[2]=' '; //按鍵指示C 取消顯示
- key_flag='A';
- num_flag=0;
- }
- else if(key==7)
- {
- Buff3[2]=' '; //按鍵指示C 取消顯示
- Buff1[2]=' '; //按鍵指示A取消顯示
- Buff2[2]='>'; //按鍵指示B 顯示
- key_flag='B';
- num_flag=0;
- }
- else if(key==11)
- {
-
- Buff1[2]=' '; //按鍵指示A 取消顯示
- Buff2[2]=' '; //按鍵指示B 取消顯示
- Buff3[2]='>'; //按鍵指示C 顯示
- run();
- }
- else if(key==15)
- { Buff1[2]=' ';
- Buff2[2]=' ';
- Buff3[2]=' ';
- stop();
- actual_speed=0;
- CurrentWaves=0;
- disp();
- }
- else if(key==14) //#############
- {
- //PWM_a-=10;
- run();
- stop();
- distant=0;
- disp();
- }
- else if(key==12) //***********
- {
- //PWM_a+=10;
- run();
- stop();
- distance=0;
- distant=0;
- actual_speed=0;
- CurrentWaves=0;
- disp();
- }
- else
- {
- if (key_flag=='A') //輸入設定轉速
- {
- if(num_flag==1)
- {
- Buff1[1]=a+0x30;
- PWM_a=PWM_a+a;
- num_flag=0;
- }
- else if (num_flag==0)
- {
- Buff1[0]=a+0x30;
- PWM_a=a*10;
- num_flag++;
- }
- disp();
- }
- else if(key_flag=='B')
- {
- if(num_flag==1)
- {
- Buff2[1]=a+0x30;
- speed_high=speed_high+a;
- num_flag=0;
- }
- else if (num_flag==0)
- {
- Buff2[0]=a+0x30;
- speed_high=a*10;
- num_flag++;
- }
- disp();
- }
-
- else
- {
- num_flag=0;
- key_flag=0;
- }
- }
- }
- /*****************速度距離計算*************/
- void a_count(void)
- {
- actual_speed=CurrentWaves*3.6; //實際轉速計算
-
- distant=distance/10;
- }
- /*******************顯示***************************/
- void disp(void)
- {
- write_12864com(0x80+3); //12864LCD第一行顯示 設置參數指示顯示位置
- write_12864data(Buff1[2]);
- write_12864com(0x80+4); //12864LCD第一行顯示
- write_12864data(Buff1[0]);
- write_12864com(0x80+5);
- write_12864data(Buff1[1]);
- Display_string(6,0,"per");
- write_12864com(0x90+3); //12864LCD第二行顯示 設置參數指示顯示位置
- write_12864data(Buff2[2]);
- write_12864com(0x90+4); //12864LCD第二行顯示
- write_12864data(Buff2[0]);
- write_12864com(0x90+5);
- write_12864data(Buff2[1]);
- Display_string(6,1,"km/h");
- write_12864com(0x88+3); //12864LCD第三行顯示 設置參數指示顯示位置
- write_12864data(Buff3[2]);
- Buff3[0]=Buff[ actual_speed/10]; //占空比十位
- write_12864com(0x88+4); //12864LCD第三行顯示
- write_12864data(Buff3[0]);
- Buff3[1]=Buff[ actual_speed%10]; // 占空比個位
- write_12864com(0x88+5);
- write_12864data(Buff3[1]);
- Display_string(6,2,"km/h");
-
- write_12864com(0x98+3); //12864LCD第四行顯示 設置參數指示顯示位置
- write_12864data(Buff4[0]);
- Buff4[0]=Buff[distant/100]; //占空比十位
- write_12864com(0x98+4); //12864LCD第三行顯示
- write_12864data(Buff4[1]);
- Buff4[1]=Buff[(distant/10)%10]; // 占空比個位
- write_12864com(0x98+5);
- write_12864data(Buff4[2]);
- Buff4[2]=Buff[distant%10];
- Display_string(6,3,"m");
- }
- /*****************報警*************/
- void warn(void)
- {
- if(actual_speed>speed_high||actual_speed==speed_high)
- {
- bee=0;
- }
- else
- {
- bee=1;
- }
- }
- /**********************************************************/
- //T0中斷服務程序
- void time0(void) interrupt 1
- {
- EX0=0; //關閉INT0中斷
- PWM=~PWM; //取反
- if( NextState )
- {
- TL0=Time0L;
- TH0=Time0H;
- NextState=0;
- }
- else
- {
- TL0=Time1L;
- TH0=Time1H;
- NextState=1;
- us500++;
- }
- if( us500 > 199 ) //定時100ms到否
- {
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
51測速測距12864.zip
(47.96 KB, 下載次數: 114)
2019-1-11 20:07 上傳
點擊文件名下載附件
uv4工程 下載積分: 黑幣 -5
|