給女朋友調的循跡車。。。
/********************************************************************************* 檔案名稱:main.c* 描 述:尋跡小車* 作 者:劉悅* 版本號碼:v1.2* 日 期: 2018年5月11日* 備 註:注意了,所有的左右都是感應器位於自己前方看的。********************************************************************************/#include <stc12.h>//關於尋跡、藍芽,取消哪個宏定義表示選擇哪項模式#define TRACE#define BLUETOOTH//電機引腳定義sbit MotorRight_P = P1^0;//右電機正相sbit MotorRight_N = P1^1;//右電機反相sbit MotorLeft_P = P1^2;//左電機正相sbit MotorLeft_N = P1^3;//左電機反相//紅外感應器檢測引腳定義//左右的序號分別從中間往兩邊開始1.2sbit Left1 = P1^7;sbit Left2 = P1^4;sbit Right1 = P1^6; sbit Right2 = P1^5;//資料類型定義typedef unsigned char u8;typedef unsigned int u16;typedef unsigned long u32;//電機運動相關的宏定義#define MotorLeft_Go() {MotorLeft_P =1; MotorLeft_N =0;}//左電機正轉#define MotorLeft_Back() {MotorLeft_P =0; MotorLeft_N =1;}//左電機反轉#define MotorLeft_Stop() {MotorLeft_P =0; MotorLeft_N =0;}//左電機停止#define MotorRight_Go() {MotorRight_P=1; MotorRight_N=0;}//右電機正轉#define MotorRight_Back() {MotorRight_P=0; MotorRight_N=1;}//右電機反轉#define MotorRight_Stop() {MotorRight_P=0; MotorRight_N=0;}//右電機停止//函式宣告void GoStaright();void Back();void TurnAdvanceLeft();void TurnAdvanceRight();void TurnNormalLeft();void TurnNormalRight();void Stop();void Timer0Init(void);void UartInit(void);void main(){ u8 TypeFlag=2; //左強拐-0 左普拐-1 直走-2 右普拐-3 右強拐-4 char ch; EA = 1; Timer0Init(); UartInit(); while(1) { //藍芽模式 #ifdef BLUETOOTH//藍芽 if(RI) { RI = 0; ch = SBUF; } if(ch == 'g') GoStaright(); else if(ch == 'b') Back(); else if(ch == 'l') TurnNormalLeft(); else if(ch == 'r') TurnNormalRight();// else Stop(); #endif//尋跡模式#ifdef TRACE //另一種方案 else if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==1)) //if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==1)) { TurnNormalRight(); TypeFlag = 3; } //直行 else if((Left2==0)&&(Left1==1)&&(Right1==1)&&(Right2==0)) { GoStaright(); TypeFlag = 2; } else if((Left2==0)&&(Left1==0)&&(Right1==1)&&(Right2==0)) { GoStaright(); TypeFlag = 2; } else if((Left2==0)&&(Left1==1)&&(Right1==0)&&(Right2==0)) { GoStaright(); TypeFlag = 2; } //左轉 else if((Left2==1)&&(Left1==1)&&(Right1==1)&&(Right2==0)) { TurnAdvanceLeft(); TypeFlag = 0; } else if((Left2==1)&&(Left1==0)&&(Right1==0)&&(Right2==0)) { TurnAdvanceLeft(); TypeFlag = 0; } else if((Left2==1)&&(Left1==1)&&(Right1==0)&&(Right2==0)) { TurnNormalLeft(); TypeFlag = 1; } else if((Left2==1)&&(Left1==0)&&(Right1==1)&&(Right2==0)) { TurnAdvanceLeft(); TypeFlag = 0; } //右轉 else if((Left2==0)&&(Left1==1)&&(Right1==1)&&(Right2==1)) { TurnAdvanceRight(); TypeFlag = 4; } else if((Left2==0)&&(Left1==0)&&(Right1==0)&&(Right2==1)) { TurnAdvanceRight(); TypeFlag = 4; } else if((Left2==0)&&(Left1==1)&&(Right1==0)&&(Right2==1)) { TurnAdvanceRight(); TypeFlag = 4; } else if((Left2==0)&&(Left1==0)&&(Right1==1)&&(Right2==1)) { TurnNormalRight(); TypeFlag = 3; } //都沒檢測到時,為防止車抖動,可繼續執行上次的動作 else if((Left2==0)&&(Left1==0)&&(Right1==0)&&(Right2==0)) { if(TypeFlag == 0) { TurnAdvanceLeft(); } else if(TypeFlag == 1) { TurnNormalLeft(); } else if(TypeFlag == 2) { GoStaright(); } else if(TypeFlag == 3) { TurnNormalRight(); } else if(TypeFlag == 4) { TurnAdvanceRight(); } } //其餘所有情況均直行 else { GoStaright(); }#endif }}void UartInit(void) //4800bps@12.000MHz{ PCON |= 0x80; //使能傳輸速率倍速位SMOD SCON = 0x50; //8位元據,可變傳輸速率// AUXR &= 0xBF; //定時器1時鐘為Fosc/12,即12T// AUXR &= 0xFE; //串口1選擇定時器1為傳輸速率發生器 TMOD &= 0x0F; //清除定時器1模式位 TMOD |= 0x20; //設定定時器1為8位自動重裝方式 TL1 = 0xF3; //設定定時初值 TH1 = 0xF3; //設定定時器重裝值 ET1 = 0; //禁止定時器1中斷 TR1 = 1; //啟動定時器1}void Timer0Init(void) //10微秒@12.000MHz{// AUXR &= 0x7F; //定時器時鐘12T模式 TMOD &= 0xF0; //設定定時器模式 TMOD |= 0x01; //設定定時器模式 TL0 = 0xF6; //設定定時初值 TH0 = 0xFF; //設定定時初值 TF0 = 0; //清除TF0標誌 ET0 = 1; //關閉定時器0中斷 TR0 = 1; //定時器0開始計時}void GoStaright(){ static unsigned char Clck = 0; u16 OutPWM_L=12,OutPWM_R=15; TL0 = 0xF6; //設定定時初值 TH0 = 0xFF; //設定定時初值 if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次 if(Clck<OutPWM_L) { MotorLeft_Go(); } else { MotorLeft_Stop(); } if(Clck<OutPWM_R) { MotorRight_Go(); } else { MotorRight_Stop(); } }void Back(){ static unsigned char Clck = 0; u16 OutPWM_L=12,OutPWM_R=15; TL0 = 0xF6; //設定定時初值 TH0 = 0xFF; //設定定時初值 if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次 if(Clck<OutPWM_L) { MotorLeft_Back(); } else { MotorLeft_Stop(); } if(Clck<OutPWM_R) { MotorRight_Back(); } else { MotorRight_Stop(); } }void TurnAdvanceRight(){ static unsigned char Clck = 0; u16 OutPWM_L=15,OutPWM_R=15; TL0 = 0xF6; //設定定時初值 TH0 = 0xFF; //設定定時初值 if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次 if(Clck<OutPWM_L) { MotorLeft_Go(); } else { MotorLeft_Stop(); } if(Clck<OutPWM_R) { MotorRight_Back(); } else { MotorRight_Stop(); }}void TurnAdvanceLeft(){ static unsigned char Clck = 0; u16 OutPWM_L=15,OutPWM_R=15; TL0 = 0xF6; //設定定時初值 TH0 = 0xFF; //設定定時初值 if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次 if(Clck<OutPWM_L) { MotorLeft_Back(); } else { MotorLeft_Stop(); } if(Clck<OutPWM_R) { MotorRight_Go(); } else { MotorRight_Stop(); }}void TurnNormalRight(){ static unsigned char Clck = 0; u16 OutPWM_L=15,OutPWM_R=15; TL0 = 0xF6; //設定定時初值 TH0 = 0xFF; //設定定時初值 if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次 if(Clck<OutPWM_L) { MotorLeft_Go(); } else { MotorLeft_Stop(); } MotorRight_Stop(); }void TurnNormalLeft(){ static unsigned char Clck = 0; u16 OutPWM_L=15,OutPWM_R=15; TL0 = 0xF6; //設定定時初值 TH0 = 0xFF; //設定定時初值 if(Clck++ >= 100) Clck = 0;//100us +1 1ms清零一次 MotorLeft_Stop(); if(Clck<OutPWM_R) { MotorRight_Go(); } else { MotorRight_Stop(); }}void Stop(){ MotorLeft_Stop(); MotorRight_Stop();}