- #include<reg52.h>
- typedef unsigned char u8; //宏定義無符號字符型 8位
- typedef unsigned int u16; //宏定義無符號整形 16位
- sbit PWM1 = P2^6; //左電機高電平
- sbit PWM2 = P2^5; //右電機高電平
- sbit IN1 = P2^4;
- sbit IN2 = P2^3; //左電機
- sbit IN3 = P2^2;
- sbit IN4 = P2^1; //右電機
- sbit S1 = P1^1; //左紅外避障模塊
- sbit S2 = P1^2; //右紅外避障模塊
- sbit S3 = P1^3; //左紅外尋跡模塊
- sbit S4 = P1^4; //右紅外尋跡模塊
- sbit K1 = P3^2; //功能轉換按鍵
- u8 connt; //調速周期
- u8 PWM_NO; //高電平時間
- u8 COM = 0; //功能控制位
- u8 t=0; //判斷串口中斷是否執行
- void time(void) //定時計時器初始化函數
- {
- TMOD = 0x01; //中斷方式1
- TH0 = 0xfe;
- TL0 = 0x0c; //0.5ms
- EA = 1; //打開總中斷
- ET0 = 1; //打開計時器中斷
- TR0 = 1; //啟動計時器
- }
- void InitUART(void) //串口中斷初始化函數
- {
- SCON=0x50; //設置為工作方式1
- TMOD=0x20; //設置計數器工作方式2
- PCON=0x00; //波特率加倍
- TH1=0xfd; //計數器初始值設置,注意波特率是9600的
- TL1=0xfd;
- ES=1; //打開接收中斷
- EA=1; //打開總中斷
- TR1=1; //打開計數器
- }
- void delay( u16 k ) //延時大約1ms
- {
- u16 i,j;
- for(i=k;i>0;i--)
- for(j=120;j>0;j--);
- }
- void SC() //剎車
- {
- IN1 = 0;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0;
- }
- void QJ() //前進
- {
- IN1 = 1;
- IN2 = 0;
- IN3 = 1;
- IN4 = 0;
- }
- void HT() //后退
- {
- IN1 = 0;
- IN2 = 1;
- IN3 = 0;
- IN4 = 1;
- }
- void ZZ1() //左大轉
- {
- IN1 = 0;
- IN2 = 1;
- IN3 = 1;
- IN4 = 0;
- }
- void ZZ2() //左小轉
- {
- IN1 = 0;
- IN2 = 0;
- IN3 = 1;
- IN4 = 0;
- }
- void YZ1() //右大轉
- {
- IN1 = 1;
- IN2 = 0;
- IN3 = 0;
- IN4 = 1;
- }
- void YZ2() //右小轉
- {
- IN1 = 1;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0;
- }
- void HY() //后右轉
- {
- IN1 = 0;
- IN2 = 0;
- IN3 = 0;
- IN4 = 1;
- }
- void lin1() //紅外避障程序
- {
- if( S1 && S2 ) //兩探頭不反應,小車前進
- {
- QJ();
- }
- if( !S1 && S2 ) //左探頭反應,小車右轉
- {
- SC();
- delay(100);
- HT();
- delay(400);
- YZ1();
- delay(550);
- SC();
- delay(100);
- }
- if( S1 && !S2 ) //右探頭反應,小車左轉
- {
- SC();
- delay(100);
- HT();
- delay(400);
- ZZ1();
- delay(550);
- SC();
- delay(100);
- }
- if( !S1 && !S2 ) //兩探頭反應,小車后退,右轉
- {
- SC();
- delay(100);
- HT();
- delay(400);
- HY();
- delay(550);
- }
- }
- void lin2() //尋跡功能程序
- {
- if( !S3 && !S4 ) //兩探頭反應,小車前進
- {
- QJ();
- delay(150);
- SC();
- delay(90);
- }
- if( S1 && S2 ) //兩探頭反應,小車停止
- {
- SC();
- }
- if( S3 && !S4 ) //左探頭不反應,小車右轉
- {
- SC();
- delay(90);
- YZ2();
- delay(120);
- }
- if( !S3 && S4 ) //右探頭不反應,小車左轉
- {
- SC();
- delay(90);
- ZZ2();
- delay(90);
- }
- }
- void lin3() //物塊追蹤功能程序
- {
- if( S1 && S2 ) //兩探頭不反應,小車停止
- {
- SC();
- }
- if( !S1 && !S2 ) //兩探頭反應,小車前進
- {
- QJ();
- }
- if( !S1 && S2 ) //右探頭不反應,小車左轉
- {
- ZZ1();
- }
- if( S1 && !S2 ) //左探頭不反應,小車右轉
- {
- YZ1();
- }
- }
- void lin4() //魔術手功能程序
- {
- if( S1 && S2 ) //兩探頭不反應,小車前進
- {
- QJ();
- }
- if( !S1 && !S2 ) //兩探頭反應,小車后退
- {
- HT();
- }
- if( !S1 && S2 ) //左探頭反應,小車后退
- {
- HT();
- }
- if( S1 && !S2 ) //右探頭反應,小車后退
- {
- HT();
- }
- }
- void konzi() //控制位
- {
- if( K1 == 0 )
- {
- delay(10);
- if( K1 == 0 )
- {
- COM++;
- }
- while( !K1 );
- }
- if( COM == 5)
- {
- COM = 0;
- t=0;
- }
- if( COM == 0 )
- {
- PWM_NO = 14;
- }
- else
- PWM_NO = 15;
- }
- void main () //主函數
- {
- time(); //計時器初始化
- InitUART(); //串口初始化
- connt = 20; //PWM的一個周期
- PWM_NO = 14; //調速,數值越大速度越慢
- IN1 = 0;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0; //待機
- while(1)
- {
- konzi();
- switch(COM) //功能選擇區
- {
- case 0: lin1();break; //避障
- case 1: lin2();break; //尋跡
- case 2: lin3();break; //物體跟隨
- case 3: lin4();break; //魔術手
- case 4: t=1;SC();while(1);break; //跳轉到藍牙控制
- }
- }
- }
- void Timer0Interrupt(void) interrupt 1 //計時器中斷函數
- {
- u8 non;
- TH0 = 0xfe;
- TL0 = 0x0c;
- non++;
- if( non == PWM_NO )
- {
- PWM1 = 1;
- PWM2 = 1;
- }
- if( non == connt )
- {
- non = 0;
- if( PWM_NO != 0)
- {
- PWM1 = 0;
- PWM2 = 0;
- }
|