- <避障小車的問題,在實物中小車不動
- #include<reg52.h> //此文件中定義了單片機的一些特殊功能寄存器
- #include"lcd.h"
- #include<intrins.h>
- #define uchar unsigned char //無符號字符型 宏定義 變量范圍0~255
- #define uint unsigned int //無符號整型 宏定義 變量范圍0~65535
- /***************超聲波**I/O口******************/
- sbit Trig = P2^3; //超聲波測距模塊Trig
- sbit Echo = P2^4; //超聲波測距模塊Echo
- /*****************蜂鳴器******************/
- sbit beep = P2^7; //蜂鳴器
- /*****************舵機******************/
- sbit SG_PWM = P3^7; //舵機
- /****************電機驅動**IO口******************/
- /*使能端*/
- sbit ENA = P2^5; //左下電機pwm信號端
- sbit ENB = P2^6; //右下電機pwm信號端
- sbit ENC = P3^0; //左上電機pwm信號端
- sbit END = P3^1; //右上電機pwm信號端
- /*電機口*/
- sbit IN1 = P1^0;
- sbit IN2 = P1^1;
- sbit IN3 = P1^2;
- sbit IN4 = P1^3;
- sbit IN5 = P1^4;
- sbit IN6 = P1^5;
- sbit IN7 = P1^6;
- sbit IN8 = P1^7;
- /***************定義全局變量******************/
- static unsigned char DisNum = 0; //顯示用指針
- unsigned char table[]="Distance:";
- unsigned char code ASCII[13] = {'0','1','2','3','4','5','6','7','8','9','.','-','M',};
- unsigned int time=0; //用于存放定時器時間的值
- unsigned long S=0; //用于存放距離的值
- unsigned long S1=0;
- unsigned long S2=0;
- unsigned long S3=0;
- unsigned int timer=10000; //延時基準變量
- bit flag =0; //超聲波超出量程溢出標志位
- unsigned char disbuff[4] = { 0,0,0,0,}; //用于存放距離的值0.1mm、mm、cm和m的值
- unsigned char pwm_val_left1 = 0; //左下電機變量定義
- unsigned char pwm_val_right1 =0; //右下電機變量定義
- unsigned char pwm_val_left2 = 0; //左上電機變量定義
- unsigned char pwm_val_right2 = 0; //右下電機變量定義
- unsigned char push_val_left1 = 0; //左下電機占空比N/20
- unsigned char push_val_right1 =0; //右下電機占空比N/20
- unsigned char push_val_left2 = 0; //左上電機占空比N/20
- unsigned char push_val_right2 = 0; //右下電機占空比N/20
- unsigned char count=0; //0.2ms次數標識
- unsigned char PWM_count=5; //舵機歸中
- /******************************************************************************
- * 函 數 名 : Delay1ms
- * 函數功能 : 延時函數,延時1ms
- *******************************************************************************/
- void Delay1ms(uint j)
- {
- uchar k;
- while(j--)
- {
- for(k = 120; k > 0; k--);
- }
- }
- /******************************************************************************
- * 函 數 名 : feng
- * 函數功能 : 報警函數
- *******************************************************************************/
- void feng()
- {
- if(S<=40)
- {
- beep=~beep;
- Delay1ms(50);
- }
- else
- beep=1;
- }
- void StartModule() //啟動模塊
- {
- Trig=1; //啟動一次模塊
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- Trig=0;
- }
- //計算距離
- void Conut(void)
- {
- TH0=0;
- TL0=0;
- while(!Echo); //當RX為零時等待
- TR0=1; //開啟計數
- while(Echo); //當RX為1計數并等待
- TR0=0; //關閉計數
- time=TH0*256+TL0;
- TH0=0;
- TL0=0;
-
- S=(time*1.7)/100; //算出來是CM
- if((S>=450)||flag==1) //超出測量范圍顯示“-”
- {
- flag=0;
-
- DisplayOneChar(10, 0, ASCII[11]);
- DisplayOneChar(11, 0, ASCII[10]); //顯示點
- DisplayOneChar(12, 0, ASCII[11]);
- DisplayOneChar(13, 0, ASCII[11]);
- DisplayOneChar(14, 0, ASCII[12]); //顯示M
- }
- else
- {
- disbuff[0]=S%1000/100;
- disbuff[1]=S%1000%100/10;
- disbuff[2]=S%1000%10 %10;
- DisplayOneChar(10, 0, ASCII[disbuff[0]]);
- DisplayOneChar(11, 0, ASCII[10]); //顯示點
- DisplayOneChar(12, 0, ASCII[disbuff[1]]);
- DisplayOneChar(13, 0, ASCII[disbuff[2]]);
- DisplayOneChar(14, 0, ASCII[12]); //顯示M
- }
- }
- void Timer0() interrupt 1 //T0中斷用來計數器溢出,超過測距范圍
- {
- flag=1; //中斷溢出標志
- }
- void run(void) //前進
- {
- push_val_left1 = 10; //PWM 調節參數1-20 1為最慢,20是最快 改這個值可以改變其速度
- push_val_right1 = 10;
- push_val_left2 = 10;
- push_val_right2 = 10;
- IN1 = 1;
- IN2 = 0;
- IN3 = 1;
- IN4 = 0;
- IN5 = 1;
- IN6 = 0;
- IN7 = 1;
- IN8 = 0;
- }
- void backrun(void) //后退
- {
- push_val_left1 = 8; //PWM 調節參數1-20 1為最慢,20是最快 改這個值可以改變其速度
- push_val_right1 = 8;
- push_val_left2 = 8;
- push_val_right2 = 8;
- IN1 = 0;
- IN2 = 1;
- IN3 = 0;
- IN4 = 1;
- IN5 = 0;
- IN6 = 1;
- IN7 = 0;
- IN8 = 1;
- }
- void leftrun(void) //左轉
- {
- push_val_left1 = 7; //PWM 調節參數1-20 1為最慢,20是最快 改這個值可以改變其速度
- push_val_right1 = 7;
- push_val_left2 = 7;
- push_val_right2 = 7;
- IN1 = 0;
- IN2 = 0;
- IN3 = 1;
- IN4 = 0;
- IN5 = 0;
- IN6 = 0;
- IN7 = 1;
- IN8 = 0;
- }
- void rightrun(void) //右轉
- {
- push_val_left1 = 7; //PWM 調節參數1-20 1為最慢,20是最快 改這個值可以改變其速度
- push_val_right1 = 7;
- push_val_left2 = 7;
- push_val_right2 = 7;
- IN1 = 1;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0;
- IN5 = 1;
- IN6 = 0;
- IN7 = 0;
- IN8 = 0;
- }
- void stop(void) //停止
- {
- IN1 = 0;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0;
- IN5 = 0;
- IN6 = 0;
- IN7 = 0;
- IN8 = 0;
- }
- //pwm控制電機速度
- void pwm_out_left1_moto(void) //左下電機
- {
- if(pwm_val_left1<=push_val_left1)
- ENA=1;
- else
- ENA=0;
- if(pwm_val_left1>=20)
- pwm_val_left1=0;
- else
- ENA=0;
- }
- void pwm_out_right1_moto(void) //右下電機
- {
- if(pwm_val_right1<=push_val_right1)
- ENB=1;
- else
- ENB=0;
- if(pwm_val_right1>=20)
- pwm_val_right1=0;
- else
- ENB=0;
- }
- void pwm_out_left2_moto(void) //左上電機
- {
- if(pwm_val_left2<=push_val_left2)
- ENC=1;
- else
- ENC=0;
- if(pwm_val_left2>=20)
- pwm_val_left2=0;
- else
- ENC=0;
- }
- void pwm_out_right2_moto(void) //右上電機
- {
- if(pwm_val_right2<=push_val_right2)
- END=1;
- else
- END=0;
- if(pwm_val_right2>=20)
- pwm_val_right2=0;
- else
- END=0;
- }
- void timer1 () interrupt 3 //中斷產生pwm信號
- {
- TH1=0xFC;
- TL1=0x18; //1ms延時
- pwm_val_left1++;
- pwm_val_right1++;
- pwm_val_left2++;
- pwm_val_right2++;
- pwm_out_left1_moto();
- pwm_out_right1_moto();
- pwm_out_left2_moto();
- pwm_out_right2_moto();
- }
- //舵機控制方向函數
- void COMM(void)
- {
- count=1; //舵機向左轉90度
- Delay1ms(1000); //延時1000ms讓舵機轉到位置
- StartModule(); //啟動測距
- Conut();
- S2=S; //得到左邊距離
- count=9; //舵機右轉
- Delay1ms(1000); //延時1000ms讓舵機轉到位置
- StartModule(); //啟動測距
- Conut();
- S3=S; //得到右邊距離
- count=5; //舵機歸中
- Delay1ms(1000); //延時1000ms讓舵機轉到位置
- StartModule(); //啟動測距
- Conut();
- S1=S; //得到中間距離
- if((S2<10)||(S3<10)) //只要左右各有距離小于10CM小車后退
- {
- backrun();
- Delay1ms(1000);
- }
- if(S2>S3) //車的左邊比車的右邊距離小右轉
- {
- rightrun();
- Delay1ms(1000);
- }
- else //車的左邊比車的右邊距離大 左轉
- {
- leftrun();
- Delay1ms(1000);
- }
- }
- void Timer2() interrupt 5
- {
- TF2=0;
- TH2=(65536-200)>>8;
- TL2=(65536-200);
- count=count+1;
-
- if(count >100)
- {
-
- count = 0;
- }
- if(count<=compare)
- {
- SG_PWM=1;
- }
- else
- {
- SG_PWM=0;
- } //次數始終保持為40即保持周期為20ms
- }
- /***************初始化定時器************/
- void init_T0()
- {
- TMOD=0x01; //設T0為方式1,GATE=1;
- TH0=0;
- TL0=0;
- ET0=1; //允許T0中斷
- EA=1; //開啟總中斷
- }
- void init_T1()
- {
- TMOD=0x11; //設T1為方式1,GATE=1;
- TH1=0xFC;
- TL1=0x18; //1ms延時
- ET1=1; //允許T1中斷
- EA=1; //開啟總中斷
- TR1=1; //t1開啟及時
- }
- void init_T2()
- {
- T2CON=0;
- TH2=0xfe;
- TL2=0x0c; //0.5ms
- ET2=1; //允許T1中斷
- EA=1; //開啟總中斷
- TR2=1; //t2開啟及時
- }
- void main()
- {
- init_T0();
- init_T1();
- init_T2();
-
- LcdInit();
- LcdShowStr(0,0,table);
- Delay1ms(5);
- count=5;
- while(1)
- {
- StartModule();
- Conut();
- feng();
- if(S<=10)
- {
- stop();
- COMM();
- }
- else
- {
- run();
- }
- }
- }
復制代碼
|