|
從網上買了一個能夠循跡,避障,紅外的小車,自己加入了能夠調速的程序,本來能按下按鍵功能能循環(huán)的,加入調速的程序后就不循環(huán)了。(新人第一次做小車,程序是拿別人的拼出來的,但感覺邏輯上沒什么大問題),程序如下,希望大神們能幫忙指出問題(第三個紅外的相關程序因不需要已經刪除)#include <REGX52.H> //包含51單片機相關的頭文件
#include <intrins.h>
sbit LeftLed=P2^0; //定義前方左側指示燈端口
sbit RightLed=P0^7; //定義前方右側指示燈端口
sbit FontLled=P1^7;
sbit LeftIR=P3^5; //定義前方左側紅外探頭端口
sbit RightIR=P3^6; //定義前方右側紅外探頭端口
sbit FontIR=P3^7; //定義前方正前方紅外探頭端口
sbit M1A=P0^0; //定義左側電機驅動A端
sbit M1B=P0^1; //定義左側電機驅動B端
sbit M2A=P0^2; //定義右側電機驅動A端
sbit M2B=P0^3; //定義右側電機驅動B端
sbit B1=P0^4; //定義語音識識別傳感器端口
sbit SB1=P0^6; //定義蜂鳴器端口
sbit IRIN=P3^3; //定義紅外接收端口
unsigned char code LedShowData[]={0x03,0x9F,0x25,0x0D,0x99, //定義數碼管顯示數據
0x49,0x41,0x1F,0x01,0x19};//0,1,2,3,4,5,6,7,8,9
unsigned char code RecvData[]={0x19,0x46,0x15,0x43,0x44,0x40,0x0D,0x0E,0x00,0x0F};
unsigned char IRCOM[7];
static unsigned int LedFlash; //定義閃動頻率計數變量
bit EnableLight=0; //定義指示燈使能位
#define ShowPort P2 //定義數碼管顯示端口
unsigned char temp = 1;
unsigned char timer1;
void tingzhi()
{
M1A=0; //將M1電機A端初始化為0
M1B=0; //將M1電機B端初始化為0
M2A=0; //將M2電機A端初始化為0
M2B=0;
}
void qianjin()
{
M1A=1;
M1B=0;
M2A=1;
M2B=0;
}
void houtui()
{
M1A=0;
M1B=1;
M2A=0;
M2B=1;
}
void zuozhuan()
{
M1A=0;
M1B=1;
M2A=1;
M2B=0;
}
void youzhuan()
{
M1A=1;
M1B=0;
M2A=0;
M2B=1;
}
void Delay1ms(unsigned int i)
{
unsigned char j,k;
do{
j = 10;
do{
k = 50;
do{
_nop_();
}while(--k);
}while(--j);
}while(--i);
}
void delay_nus(unsigned int i) //延時:i>=12 ,i的最小延時單12 us
{
i=i/10;
while(--i);
}
void delay_nms(unsigned int n) //延時n ms
{
n=n+1;
while(--n)
delay_nus(900); //延時 1ms,同時進行補償
}
void delayms(unsigned char x) //0.14mS延時程序
{
unsigned char i; //定義臨時變量
while(x--) //延時時間循環(huán)
{
for (i = 0; i<13; i++) {} //14mS延時
}
}
void Delay() //定義延時子程序
{
unsigned int DelayTime=30000; //定義延時時間變量
while(DelayTime--); //開始進行延時循環(huán)
return; //子程序返回
}
void ControlCar(unsigned char ConType) //定義電機控制子程序
{
tingzhi();
switch(ConType) //判斷用戶設定電機形式
{
case 1: //前進 //判斷用戶是否選擇形式1
{
//tingzhi(); //進入前進之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
//Delay1ms(50);
LeftLed = 0 ;
qianjin();
break;
}
case 2: //后退 //判斷用戶是否選擇形式2
{
// tingzhi(); //進入后退之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
// Delay1ms(50);
LeftLed = 1 ;
houtui(); //M2電機反轉
break;
}
case 3: //左轉 //判斷用戶是否選擇形式3
{
//tingzhi(); //進入左轉之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
// Delay1ms(50);
zuozhuan(); //M2電機正轉
break;
}
case 4: //右轉 //判斷用戶是否選擇形式4
{
// tingzhi(); //進入右轉之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
// Delay1ms(50);
youzhuan(); //M1電機正轉
//M2電機反轉
break;
}
case 8: //停止 //判斷用戶是否選擇形式8
{
tingzhi();
break; //退出當前選擇
}
}
}
void ControlCar_yaokong(unsigned char ConType) //定義電機控制子程序 (紅外遙控單獨設置一個 switch case 語句 )
{
tingzhi();
switch(ConType) //判斷用戶設定電機形式
{
case 1: //前進 //判斷用戶是否選擇形式1
{
tingzhi(); //進入前進之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
Delay1ms(150);
LeftLed = 0 ;
qianjin();
break;
}
case 2: //后退 //判斷用戶是否選擇形式2
{
tingzhi(); //進入后退之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
Delay1ms(150);
LeftLed = 1 ;
houtui(); //M2電機反轉
break;
}
case 3: //左轉 //判斷用戶是否選擇形式3
{
tingzhi(); //進入左轉之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
Delay1ms(150);
zuozhuan(); //M2電機正轉
break;
}
case 4: //右轉 //判斷用戶是否選擇形式4
{
tingzhi(); //進入右轉之前 先停止一段時間 防止電機反向電壓沖擊主板 導致系統(tǒng)復位
Delay1ms(150);
youzhuan(); //M1電機正轉 //M2電機反轉
break;
}
case 8: //停止 //判斷用戶是否選擇形式8
{
tingzhi();
break; //退出當前選擇
}
}
}
void Robot_Avoidance() //機器人避障子程序
{
LeftLed=LeftIR; //前方左側指示燈指示出前方左側紅外探頭狀態(tài)
RightLed=RightIR; //前方右側指示燈指示出前方右側紅外探頭狀態(tài)
FontLled= FontIR;
SB1=FontIR;
if(FontIR == 0) //如果前面避障傳感器檢測到障礙物
{
ControlCar(8); //停止
delay_nms (300); //停止300MS 防止電機反相電壓沖擊 導致系統(tǒng)復位
ControlCar(2); //后退
delay_nms (1000); //后退1500MS
ControlCar(3); //
delay_nms (1800);
}
else
{
ControlCar(1); //右側沒有信號時,開始向左轉一定的角度
delay_nms (10);
}
ControlCar(1);
}
//機器人循跡子程序
void Robot_Traction() //機器人循跡子程序
{
LeftLed=LeftIR; //前方左側指示燈指示出前方左側紅外探頭狀態(tài)
RightLed=RightIR; //前方右側指示燈指示出前方右側紅外探頭狀態(tài)
FontLled= FontIR;
SB1=LeftIR;
if(LeftIR == 0 && RightIR == 0) //三個紅外檢測到黑線,就前進
{
ControlCar(1); //左側沒有信號時,開始向右轉一定的角度
delay_nms (10);
}
else if(LeftIR == 0 && RightIR == 1)
{
ControlCar(3); //右側沒有信號時,開始向左轉一定的角度
delay_nms (10);
}
else if(LeftIR == 1 && RightIR == 0)
{
ControlCar(4); //右側沒有信號時,開始向左轉一定的角度
delay_nms (10);
}
ControlCar(8);
}
/*******************************************************************************
* 函 數 名 : Time1
* 函數功能 : 定時器1的中斷函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Time1Config();
void RobotV1() //機器人循跡子程序
{
Time1Config();
while (temp==4)
{
if(timer1>100) //PWM周期為100*0.5ms
{
timer1=0;
}
if(timer1 <50) //改變30這個值可以改變直流電機的速度
{
M1A=1;
M2A=1;
}
else
{
M1A=0;
M2A=0;
}
}
}
/*******************************************************************************
* 函 數 名 : Time1Config
* 函數功能 : 設置定時器
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Time1Config()
{
TMOD|= 0x10; //設置定時計數器工作方式1為定時器
//--定時器賦初始值,12MHZ下定時0.5ms--//
TH1 = 0xFE;
TL1 = 0x0C;
ET1 = 1; //開啟定時器1中斷
EA = 1;
TR1 = 1; //開啟定時器
}
/*******************************************************************************
* 函 數 名 : Time1
* 函數功能 : 定時器1的中斷函數
* 輸 入 : 無
* 輸 出 : 無
*******************************************************************************/
void Time1(void) interrupt 3 //3 為定時器1的中斷號 1 定時器0的中斷號 0 外部中斷1 2 外部中斷2 4 串口中斷
{
TH1 = 0xFE; //重新賦初值
TL1 = 0x0C;
timer1++;
}
void main() //主程序入口
{
bit RunFlag=0; //定義小車運行標志位
LedFlash=3000; //對閃燈數據進行初始化
ControlCar(8);
while(1) //程序主循環(huán)
{
if(P3_2 == 0)
{
delay_nms(10);
if(P3_2 == 0)
{
temp++;
while(!P3_2);
}
}
if(temp > 4)
{
temp = 1;
}
switch(temp)
{
case 1: ShowPort = LedShowData[1];Robot_Traction();break;
case 2: ShowPort = LedShowData[2];Robot_Avoidance();break;
case 3: ShowPort = LedShowData[3];break;
case 4: ShowPort = LedShowData[4];RobotV1();break;
}
}
}
|
|