標題:
昨天發(fā)的多功能小車程序
[打印本頁]
作者:
LGX123
時間:
2018-5-29 08:30
標題:
昨天發(fā)的多功能小車程序
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define u8 unsigned char
#define u16 unsigned int
uchar num;
unsigned char irtime; //紅外用全局變量
unsigned char IRcord[4]; //紅外按鍵對應(yīng)碼值選對應(yīng)功能的數(shù)組
unsigned char irdata[33]; //存儲電平持續(xù)的時間的數(shù)組
u16 EchoCnt;
bit irpro_ok,irok; //位定義,用于判斷操作是否完成
sbit in1=P1^0; //電機引腳定義
sbit in2=P1^1;
sbit in3=P1^2;
sbit in4=P1^3;
sbit IR=P3^2; //將IR位定義為P3.2引腳紅外模塊引腳
sbit XUNJI0 =P2^2; //循跡模塊
sbit XUNJI1 =P2^3;
sbit Trig = P3^6; //超聲波模塊
sbit Echo = P3^7;
sbit XUNGUANG0 = P2^0; // 紅外尋光接口定義
sbit XUNGUANG1 = P2^1;
typedef enum
{
FORWARD=0,
BACKUP,
LEFT,
RIGHT,
STOP,
ZHUANHUAN,
XUNJI,
BIZHANG,
XUNGUANG,
}MOTOR_DIR;
void qianjin();
void houtui();
void zuozhuan();
void youzhuan();
void tingzhi();
void DelayMs(u16 t); //延時函數(shù)
void DelayUs(u16 i);
void DcMotorContorl(MOTOR_DIR dir, u8 speed); // 小車直流電機控制,dir為方向,speed為速度
void TIM0init(); //定時器0初始化
void Ircordpro();
void Ir_work();
void HC04_Init();
void HC04_Loop();
void hongwaiyaokong(); //紅外遙控函數(shù)
void lanya(); //藍牙遙控函數(shù)
void xunji(); //循跡函數(shù)
void bizhang(); //壁障函數(shù)
void xunguang(); //尋光函數(shù)
void init_t1() //初始化函數(shù)
{
TMOD=0x20; //設(shè)置定時器1為工作方式2
TH1=0xfd; //波特率初始值
TL1=0xfd;
TR1=1; //定時器打開
REN=1; //允許串行接受
SM0=0; //串行口工作方式設(shè)置為1
SM1=1;
EA=1; //打開總中斷
ES=1;
}
void main() //主函數(shù)
{
init_t1();
while(1)
{
lanya();
}
}
void EX0init(void) // 外部中斷初始化
{
IT0 = 1; //指定外部中斷0下降沿觸發(fā),INT0 (P3.2)
EX0 = 1; //允許外部中斷0
EA = 1; //開總中斷
}
void ex0_isr (void) interrupt 0 using 0 //外部中斷0服務(wù)函數(shù)
{
static unsigned char i; //接收紅外信號處理
static bit startflag; //是否開始處理標志位
if(startflag)
{
if(irtime<63&&irtime>=33)//引導(dǎo)碼 TC9012的頭碼,9ms低電平+4.5ms高電平
i=0;
irdata[i]=irtime;//存儲每個電平的持續(xù)時間,用于以后判斷是0還是1
irtime=0;
i++;
if(i==33)
{
irok=1;
i=0;
}
}
else
{irtime=0;
startflag=1;
}
}
void tim0_isr (void) interrupt 1 using 1//定時器0中斷服務(wù)函數(shù)
{
irtime++; //用于計數(shù)2個下降沿之間的時間
}
void TIM0init(void)//定時器0初始化
{
TMOD=0x02;//定時器0工作方式2,TH0是重裝值,TL0是初值
TH0=0x00; //重載值
TL0=0x00; //初始化值
ET0=1; //開中斷允許位
TR0=1; //開啟定時器功能
}
void t1() interrupt 4//中斷服務(wù)函數(shù)
{
if(RI)
{
RI=0;
num=SBUF-48; //將接收到的碼值轉(zhuǎn)換為十進制整數(shù)以選擇對應(yīng)功能
}
}
void HC04_Init(void) //初始化超聲波模塊
{
Trig = 0;
Echo = 0;
TMOD &=0X0f;
TMOD |=0X10; //使用模式1,16位定時器1;
TH1=0; //裝初值
TL1=0;
EA=1; //開總中斷
ET1=1; //開定時器1中斷
TR1=0; //定時器1
}
void HC04_Loop(void) //數(shù)據(jù)處理函數(shù)計算前方物體和小車的距離
{
Trig = 1;
DelayUs(20);
Trig = 0;
while(Echo == 0);
TH1=0;
TL1=0;
TR1=1;
while(Echo == 1);
EchoCnt = (TH1*256 + TL1)*1.7/100;
}
void lanya()
{
while(1)
{
switch(num)
{
case 1: qianjin();break; //前進
case 2: zuozhuan();break; //左轉(zhuǎn)
case 3: tingzhi();break; //停止
case 4: youzhuan();break; //右轉(zhuǎn)
case 5: houtui();break; //后退
case 6: hongwaiyaokong();break; //啟動紅外遙控
case 7: xunji();break; //啟動循跡功能
case 8: bizhang();break; //啟動壁障功能
case 9: xunguang();break; //啟動尋光功能
default:break;
}
}
}
/*藍牙遙控電機程序*/
void qianjin()
{
in1=1;
in2=0;
in3=1;
in4=0;
}
void houtui()
{
in1=0;
in2=1;
in3=0;
in4=1;
}
void zuozhuan()
{
in1=1;
in2=0;
in3=0;
in4=0;
}
void youzhuan()
{
in1=0;
in2=0;
in3=1;
in4=0;
}
void tingzhi()
{
in1=0;
in2=0;
in3=0;
in4=0;
}
void hongwaiyaokong() // 紅外遙控函數(shù)
{
TIM0init();
EX0init();
while(1)
{
if(irok) //如果接收好了進行紅外處理 紅外解碼
{
Ircordpro();
irok=0;
}
if(irpro_ok) //如果處理好后進行工作處理,執(zhí)行對應(yīng)功能
{
Ir_work();
}
}
}
void xunji() // 循跡函數(shù)
{
DelayMs(1000); // 默認延時,等待系統(tǒng)穩(wěn)定
while(1)
{
DcMotorContorl(FORWARD, 10);
if((XUNJI0 == 1) && (XUNJI1 == 0)) // 尋跡右邊紅外檢測到黑線
{
DcMotorContorl(RIGHT, 14); // 小車往右邊走
}
else if((XUNJI0 == 0) && (XUNJI1 == 1)) // 小車左邊紅外檢測到黑線
{
DcMotorContorl(LEFT, 14); // 小車往左邊走
}
else if((XUNJI0 == 0) && (XUNJI1 == 0)) // 小車左右都沒有檢測到黑線
{
DcMotorContorl(FORWARD, 10); // 小車直走
}
}
}
void bizhang(void) //壁障函數(shù)
{
HC04_Init();
while(1)
{
HC04_Loop(); //調(diào)用數(shù)據(jù)處理函數(shù)
if(EchoCnt < 25) // 距離小于25CM
{
DcMotorContorl(STOP, 20); // 小車停止
DcMotorContorl(RIGHT, 20); //小車右轉(zhuǎn)
DelayUs(1500);
if(EchoCnt < 25)
{
DcMotorContorl(STOP, 20); // 小車停止
DcMotorContorl(RIGHT, 25); //小車右轉(zhuǎn)
}
else
{
DcMotorContorl(FORWARD, 20); // 小車前進
}
}
else
{
DcMotorContorl(FORWARD, 20); // 小車前進
}
}
}
void xunguang(void) //尋光函數(shù)
{
DelayMs(1000); // 延時,等待系統(tǒng)穩(wěn)定
while(1)
{
if((XUNGUANG0 == 1) && (XUNGUANG1 == 0)) // 尋光右邊紅外檢測到光線
{
DcMotorContorl(RIGHT, 15); // 小車往右邊走
}
else if((XUNGUANG0 == 0) && (XUNGUANG1 == 1)) // 小車左邊紅外檢測到光線
{
DcMotorContorl(LEFT, 15); // 小車往左邊走
}
else if((XUNGUANG0 == 0) && (XUNGUANG1 == 0)) // 小車左右都有檢測到光線
{
DcMotorContorl(FORWARD, 20); // 小車直走
}
}
}
/*紅外遙控電機程序*/
void DcMotorContorl(MOTOR_DIR dir,u8 speed)
{
switch(dir)
{
case FORWARD: // 前進
in1 = 1;
in2 = 0;
in3 = 1;
in4 = 0;
break;
case BACKUP: // 后退
in1 = 0;
in2 = 1;
in3 = 0;
in4 = 1;
break;
case LEFT: // 左轉(zhuǎn)
in1 = 0;
in2 = 1;
in3 = 1;
in4 = 0;
break;
case RIGHT: // 右轉(zhuǎn)
in1 = 1;
in2 = 0;
in3 = 0;
in4 = 1;
break;
case STOP: // 停止
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
break;
case ZHUANHUAN: //轉(zhuǎn)換功能
lanya();
break;
case XUNJI: //循跡功能
xunji();
break;
case BIZHANG: //壁障功能
bizhang();
break;
case XUNGUANG: //尋光功能
xunguang();
break;
default: // 其他
in1 = 0;
in2 = 0;
in3 = 0;
in4 = 0;
break;
}
DelayMs(speed); // speed的值越大,速度越快
in1 = 1;
in2 = 1;
in3 = 1;
in4 = 1;
DelayMs(25 - speed); // speed的值越大,延時時間越短,速度越快
}
void DelayMs(u16 t)
{
u16 i,j;
for(i=0; i<t; i++)
for(j=0; j<120; j++);
}
void DelayUs(u16 i)
{
while(--i);
}
void Ir_work(void) //紅外鍵值處理,紅外鍵值轉(zhuǎn)程序
{
switch(IRcord[2]) //判斷第三個數(shù)碼值
{
case 0x0c: // 數(shù)字1 //轉(zhuǎn)換為藍牙
DcMotorContorl(ZHUANHUAN, 0);
break;
case 0x18: // 數(shù)字2
DcMotorContorl(FORWARD, 20); // 小車直行
break;
case 0x5e: // 數(shù)字3
DcMotorContorl(XUNJI, 0); //循跡功能
break;
case 0x08: // 數(shù)字4
DcMotorContorl(LEFT, 20); // 小車左轉(zhuǎn)
break;
case 0x1c: // 數(shù)字5
DcMotorContorl(STOP, 20); // 小車停止
break;
case 0x5a: // 數(shù)字6
DcMotorContorl(RIGHT, 20); // 小車右轉(zhuǎn)
break;
case 0x42: // 數(shù)字7
DcMotorContorl(BIZHANG, 0); //壁障功能
break;
case 0x52: // 數(shù)字8
DcMotorContorl(BACKUP, 20); // 小車后退
break;
case 0x4a: // 數(shù)字9
DcMotorContorl(XUNGUANG, 0); //尋光功能
break;
case 0x16: // 數(shù)字0
break;
case 0x46: // Mode
DcMotorContorl(FORWARD, 20); // 小車直行
break;
case 0x40: // <-
DcMotorContorl(STOP, 20); // 小車停止
break;
case 0x44: // >||
DcMotorContorl(LEFT, 20); // 小車左轉(zhuǎn)
break;
case 0x43: //->
DcMotorContorl(RIGHT, 20); // 小車右轉(zhuǎn)
break;
case 0x15: // VOL-
DcMotorContorl(BACKUP, 20); // 小車后退
break;
default:
break;
}
//irpro_ok=0;//處理完成標志
}
void Ircordpro(void) //紅外解碼碼值處理函數(shù)
{
unsigned char i, j, k;
unsigned char cord,value;
k=1;
for(i=0;i<4;i++) //處理4個字節(jié)
{
for(j=1;j<=8;j++) //處理1個字節(jié)8位
{
cord=irdata[k];
if(cord>7) //大于某值為1,這個和晶振有絕對關(guān)系,此值可以有一定誤差
{
value=value|0x80;
}
else
{
value=value;
}
if(j<8)
{
value=value>>1;
}
k++;
}
IRcord[i]=value;
value=0;
}
irpro_ok=1; //處理完畢標志位置1
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1