|
包含以下功能:1、人工操作(前進(jìn)、后退、左轉(zhuǎn)、右轉(zhuǎn))
2、超聲波避障(包含距離的顯示)
3、紅外避障
源碼:
/*******************************XB-4WD 智能小車(chē)參考程序****************************************
* 平臺(tái):XB-4WD + Keil4 + STC89C52
* 名稱:小車(chē)超聲波避障
* 日期:2014-5-18
* QQ : 61924336
**********************************************************************************************/
/**********************************************************************************************
** 智能小車(chē)接線說(shuō)明
**********************************************************************************************/
/**********************************************************************************************
電池盒 XB-L293D驅(qū)動(dòng)板上的電池輸入端子(藍(lán)色)
***********************************************************************************************
紅線(+) ------------------------------- 藍(lán)色輸入端子(+)
黑線(-) ------------------------------- 藍(lán)色輸入端子(-)
***********************************************************************************************
/**********************************************************************************************
XB-L293D驅(qū)動(dòng)板上的5V電源輸出排針 XB-1A主板上的+5V電源輸入排針
***********************************************************************************************
VCC ------------------------------- +5V
GND ------------------------------- GND
***********************************************************************************************
/**********************************************************************************************
XB-1A主板 XB-L293D驅(qū)動(dòng)板(輸入) * XB-L293D驅(qū)動(dòng)板(輸出) 電機(jī)
***********************************************************************************************
P1.0 --------- IN1 * OUT1 --------- 左上電機(jī)(+)
P1.1 --------- IN2 * OUT2 --------- 左上電機(jī)(-)
*********************************************************************************************** *
P1.2 --------- IN3 * OUT3 --------- 左下電機(jī)(+)
P1.3 --------- IN4 * OUT4 --------- 左下電機(jī)(-)
***********************************************************************************************
P1.4 --------- IN5 * OUT5 --------- 右上電機(jī)(+)
P1.5 --------- IN6 * OUT6 --------- 右上電機(jī)(-)
***********************************************************************************************
P1.6 --------- IN7 * OUT7 --------- 右下電機(jī)(+)
P1.7 --------- IN8 * OUT8 --------- 右下電機(jī)(-)
***********************************************************************************************/
/***********************************************************************************************
舵機(jī)模塊 XB-1A主板
************************************************************************************************
紅色線(電源正) -------------------------- JPW(+5V)
棕色線(電源負(fù)) -------------------------- JPW(GND)
橙色線(信號(hào)線) -------------------------- P2.7
************************************************************************************************
/***********************************************************************************************
超聲波模塊 XB-1A主板
************************************************************************************************
VCC -------------------------------------- JPW(+5V)
TRIG -------------------------------------- P2.1
ECHO -------------------------------------- P2.0
GND -------------------------------------- JPW(GND)
************************************************************************************************
/***********************************************************************************************
** 頭文件
***********************************************************************************************/
#include<AT89x51.H>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
/**********************************************************************************************
** 舵機(jī)信號(hào)線(橙色)
**********************************************************************************************/
#define Sevro_moto_pwm P2_7
/**********************************************************************************************
** 超聲波控制線
**********************************************************************************************/
#define ECHO P2_5 //超聲波接口定義 P2.1
#define TRIG P2_6 //超聲波接口定義 P2.0
#define Left_moto_pwm1 P2_0 //PWM信號(hào)端
#define Left_moto_pwm2 P2_1 //PWM信號(hào)端
#define Right_moto_pwm1 P2_2 //PWM信號(hào)端
#define Right_moto_pwm2 P2_3 //PWM信號(hào)端
#define Left_1_led P3_4 //左傳感器
#define Right_1_led P3_5 //右傳感器
/**********************************************************************************************
** 蜂鳴器接口定義
**********************************************************************************************/
sbit FM = P3^6; //蜂鳴器接口
sbit Speed=P3^7; //控制外部中斷
/******************************************************************
** 接線定義
******************************************************************/
#define Left_moto_go {P1_0=1,P1_1=0,P1_2=1,P1_3=0;} //左邊兩個(gè)電機(jī)向前走
#define Left_moto_back {P1_0=0,P1_1=1,P1_2=0,P1_3=1;} //左邊兩個(gè)電機(jī)向后轉(zhuǎn)
#define Left_moto_Stop {P1_0=0,P1_1=0,P1_2=0,P1_3=0;} //左邊兩個(gè)電機(jī)停轉(zhuǎn)
#define Right_moto_go {P1_4=1,P1_5=0,P1_6=1,P1_7=0;} //右邊兩個(gè)電機(jī)向前走
#define Right_moto_back {P1_4=0,P1_5=1,P1_6=0,P1_7=1;} //右邊兩個(gè)電機(jī)向前走
#define Right_moto_Stop {P1_4=0,P1_5=0,P1_6=0,P1_7=0;} //右邊兩個(gè)電機(jī)停轉(zhuǎn)
/******************************************************************
** 紅外遙控器的相關(guān)定義
******************************************************************/
#define Imax 14000 //此處為晶振為11.0592時(shí)的取值,
#define Imin 8000 //如用其它頻率的晶振時(shí),
#define Inum1 1450 //要改變相應(yīng)的取值。
#define Inum2 700
#define Inum3 3000
/**********************************************************************************************
** 變量定義
**********************************************************************************************/
uchar disbuff[4] ={ 0,0,0,0,};
uchar posit=0;
uchar pwm_val_steering = 0; //變量定義
uchar push_val_steering =14; //舵機(jī)歸中,產(chǎn)生約,1.5MS 信號(hào)
uchar pwm_val_left =0; //變量定義
uchar push_val_left =0; //左電機(jī)占空比N/20
uchar pwm_val_right =0;
uchar push_val_right=0; //右電機(jī)占空比N/20
bit Right_moto_stop=1;
bit Left_moto_stop =1;
ulong S=0;
ulong S1=0;
ulong S2=0;
ulong S3=0;
ulong S4=0;
uint time=0; //時(shí)間變量
uint timer=0; //延時(shí)基準(zhǔn)變量
uchar timer1=0; //掃描時(shí)間變量
uint num = 3;
uchar f=0;
uchar Im[4]={0x00,0x00,0x00,0x00};
uchar show[2]={0,0};
ulong m,Tc;
uchar IrOK;
bit flag;
uint shu[9]={1,2,3,4,5,6, 7,8,9};
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //0~9 共陽(yáng)極數(shù)碼管
uchar code chose[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //共陰極數(shù)碼管
void ultrasonic( void ); //超聲波避障
void artificial( void ); //人工操作小車(chē)
void control_menu(void ); //主控菜單
/**********************************************************************************************
** 延時(shí)函數(shù)
**********************************************************************************************/
void delay(unsigned int k) //延時(shí)函數(shù)
{
unsigned int x,y;
for(x=0;x<k;x++)
for(y=0;y<2000;y++);
}
void delayms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=99;y>0;y--);
}
/**********************************************************************************************
** 啟動(dòng)測(cè)距信號(hào)
**********************************************************************************************/
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;
}
/******************************************************************
** 小車(chē)前進(jìn)
******************************************************************/
void run(void)
{
push_val_left=8;
push_val_right=8;
Left_moto_go ; //左電機(jī)往前走
Right_moto_go ; //右電機(jī)往前走
}
/******************************************************************
** 小車(chē)后退
******************************************************************/
void backrun(void)
{
push_val_left=8;
push_val_right=8;
Left_moto_back ; //左電機(jī)后退
Right_moto_back ; //右電機(jī)后退
}
/******************************************************************
** 小車(chē)左轉(zhuǎn)
******************************************************************/
void leftrun(void)
{
push_val_left=8;
push_val_right=8;
Right_moto_back ; //右電機(jī)后退
Left_moto_go ; //左電機(jī)前進(jìn)
}
/******************************************************************
** 小車(chē)右轉(zhuǎn)
******************************************************************/
void rightrun(void)
{
push_val_left=8;
push_val_right=8;
Right_moto_go; //右電機(jī)前進(jìn)
Left_moto_back ; //左電機(jī)停止
}
/******************************************************************
** 小車(chē)停走
******************************************************************/
void stoprun(void)
{
push_val_left=8;
push_val_right=8;
Left_moto_Stop
Right_moto_Stop;
}
/**********************************************************************************************
** 數(shù)碼管顯示
**********************************************************************************************/
/**********************************************************************************************
** 顯示數(shù)據(jù)的轉(zhuǎn)換
**********************************************************************************************/
void display()
{
P0=table[disbuff[1]];
P2_0 = 0;
delayms(5);
P2_0 = 1;
P0=table[disbuff[0]];
P2_1 = 0;
delayms(5);
P2_1 = 1;
P0=table[disbuff[1]];
P2_2 = 0;
delayms(5);
P2_2 = 1;
P0=table[disbuff[2]];
P2_3 = 0;
delayms(5);
P2_3 = 1;
}
/**********************************************************************************************
** 計(jì)算距離
**********************************************************************************************/
void Conut(void)
{
while(!ECHO); //當(dāng)RX為零時(shí)等待
TR0=1; //開(kāi)啟計(jì)數(shù)
while(ECHO); //當(dāng)RX為1計(jì)數(shù)并等待
TR0=0; //關(guān)閉計(jì)數(shù)
time=TH0*256+TL0; //讀取脈寬長(zhǎng)度
TH0=0;
TL0=0;
S=(time*1.7)/100; //算出來(lái)是CM
disbuff[0]=S%1000/100; //更新顯示 百位
disbuff[1]=S%1000%100/10; //更新顯示 十位
disbuff[2]=S%1000%10 %10; //更新顯示 個(gè)位
}
/**********************************************************************************************
** 計(jì)算速度
**********************************************************************************************/
void speed(void)
{
TR1=1;
TH1=0;
TL1=0;
flag=0;
while(flag==0);
S=TH1*256+TL1;
disbuff[0]=S%1000/100; //更新顯示 百位
disbuff[1]=S%1000%100/10; //更新顯示 十位
disbuff[2]=S%1000%10 %10; //更新顯示 個(gè)位
}
/**********************************************************************************************
** 判斷小車(chē)該往哪邊走
**********************************************************************************************/
void judge(void)
{
if((S2<40)||(S4<40)){ //只要左右各有距離小于,30CM小車(chē)后退
backrun(); //后退
timer=0;
while(timer<=1000);
}
if(S2>S4){
rightrun(); //車(chē)的左邊比車(chē)的右邊距離小 右轉(zhuǎn)
timer=0;
while(timer<=800);
}else{
leftrun(); //車(chē)的左邊比車(chē)的右邊距離大 左轉(zhuǎn)
timer=0;
while(timer<=800);
}
}
void judge1(void)
{
if((S2>S4)&&(S2 > 40)){
rightrun(); //車(chē)的左邊比車(chē)的右邊距離小 右轉(zhuǎn)
timer=0;
while(timer<=800);
}else if((S2<=S4)&&(S4 > 40)){
leftrun(); //車(chē)的左邊比車(chē)的右邊距離大 左轉(zhuǎn)
timer=0;
while(timer<=800);
}
}
/**********************************************************************************************
** 左右超聲波檢測(cè)距離
**********************************************************************************************/
void COMM( void )
{
push_val_steering=5; //舵機(jī)向右轉(zhuǎn)90度
timer=0;
while(timer<=3500); //延時(shí)400MS讓舵機(jī)轉(zhuǎn)到其位置 4000
StartModule(); //啟動(dòng)超聲波測(cè)距
Conut(); //計(jì)算距離
display(); //顯示距離
S2=S;
push_val_steering=25; //舵機(jī)再向左轉(zhuǎn)180度
timer=0;
while(timer<=3500); //延時(shí)400MS讓舵機(jī)轉(zhuǎn)到其位置
StartModule(); //啟動(dòng)超聲波測(cè)距
Conut(); //計(jì)算距離
display(); //顯示距離
S4=S;
push_val_steering=14; //舵機(jī)歸中
timer=0;
while(timer<=3500); //延時(shí)400MS讓舵機(jī)轉(zhuǎn)到其位置
StartModule(); //啟動(dòng)超聲波測(cè)距
Conut(); //計(jì)算距離
display(); //顯示距離
S1=S;
judge();
}
/*********************************************************************************************/
/* PWM調(diào)制電機(jī)轉(zhuǎn)速 */
/*********************************************************************************************/
/* 舵機(jī)電機(jī)調(diào)速 */
/* 調(diào)節(jié)steering_engine_left的值改變舵機(jī)轉(zhuǎn)速,占空比 */
void pwm_Servomoto(void)
{
if(pwm_val_steering<=push_val_steering)
Sevro_moto_pwm=1;
else
Sevro_moto_pwm=0;
if(pwm_val_steering>=100)
pwm_val_steering=0;
}
/******************************************************************
** 左電機(jī)調(diào)速
******************************************************************/
void pwm_out_left_moto(void)
{
if(Left_moto_stop){
if(pwm_val_left<=push_val_left){
Left_moto_pwm1=1;
Left_moto_pwm2=1;
}else {
Left_moto_pwm1=0;
Left_moto_pwm2=0;
}
if(pwm_val_left>=20)
pwm_val_left=0;
}else{
Left_moto_pwm1=0;
Left_moto_pwm2=0;
}
}
/******************************************************************
** 右電機(jī)調(diào)速
******************************************************************/
void pwm_out_right_moto(void)
{
if(Right_moto_stop){
if(pwm_val_right<=push_val_right){
Right_moto_pwm1=1;
Right_moto_pwm2=1;
}else {
Right_moto_pwm1=0;
Right_moto_pwm2=0;
}
if(pwm_val_right>=20)
pwm_val_right=0;
}else {
Right_moto_pwm1=0;
Right_moto_pwm2=0;
}
}
/**********************************************************************************************
** TIMER1中斷服務(wù)子函數(shù)產(chǎn)生PWM信號(hào) **
**********************************************************************************************/
/******************************************************************
** 定時(shí)器0初始化
******************************************************************/
void timer0_Init(void)
{
TMOD=0X01;
TH0= 0XFc; //1ms定時(shí)
TL0= 0X18;
TR0= 1;
ET0= 1;
EA = 1; //開(kāi)總中斷
}
/******************************************************************
** 定時(shí)器0中斷服務(wù)子程序
******************************************************************/
void timer0()interrupt 1 using 2
{
TH0=0XFc;
TL0=0X18;
time++;
pwm_val_left++;
pwm_val_right++;
pwm_out_left_moto();
pwm_out_right_moto();
}
/******************************************************************
** 定時(shí)器1中斷服務(wù)子程序
******************************************************************/
void time1()interrupt 3 using 2
{
TH1=(65536-100)/256; //100US定時(shí)
TL1=(65536-100)%256;
timer++; //定時(shí)器100US為準(zhǔn)。在這個(gè)基礎(chǔ)上延時(shí)
pwm_val_steering++;
pwm_Servomoto();
timer1++; //2MS掃一次數(shù)碼管
if(timer1>=20){
timer1=0;
}
}
/******************************************************************
** 外部中斷解碼程序
******************************************************************/
void intersvr0(void) interrupt 0 using 1
{
Tc=TH0*256+TL0; //提取中斷時(shí)間間隔時(shí)長(zhǎng)
TH0=0;
TL0=0; //定時(shí)中斷重新置零
if((Tc>Imin)&&(Tc<Imax)){
m=0;
f=1;
return;
} //找到啟始碼
if(f==1){
if(Tc>Inum1&&Tc<Inum3) {
Im[m/8]=Im[m/8]>>1|0x80; m++;
}
if(Tc>Inum2&&Tc<Inum1) {
Im[m/8]=Im[m/8]>>1; m++; //取碼
}
if(m==32) {
m=0;
f=0;
if(Im[2]==~Im[3]) {
IrOK=1;
}
else IrOK=0; //取碼完成后判斷讀碼是否正確
}
} //準(zhǔn)備讀下一碼
}
/******************************************************************
** 紅外線避障
******************************************************************/
void Infrared(void)
{
timer0_Init();
while(1){
if(IrOK==1) {
stoprun();
switch(Im[2]) {
case 0x16:
control_menu(); //返回主控菜單
break;
default:
break;
}
IrOK=0;
}
if(Left_1_led==1&&Right_1_led==1) //左右邊都檢測(cè)不到紅外,燈都是滅的
run(); //調(diào)用前進(jìn)函數(shù)
else{
if(Left_1_led==1&&Right_1_led==0){ //右邊邊檢測(cè)到紅外,右邊燈亮
leftrun(); //調(diào)用小車(chē)左轉(zhuǎn)函數(shù)
}
if(Right_1_led==1&&Left_1_led==0){ //左邊檢測(cè)到紅外,左邊燈亮
rightrun(); //調(diào)用小車(chē)右轉(zhuǎn)函數(shù)
}
if(Right_1_led == 0 && Left_1_led == 0){ //左右檢測(cè)到紅外,左右燈亮
backrun(); //小車(chē)后退
}
}
}
}
/**********************************************************************************************
** 超聲波的避障代碼
**********************************************************************************************/
void ultrasonic( void )
{ IrOK=0;
TMOD=0X11;
TH1=(65536-100)/256; //100US定時(shí)
TL1=(65536-100)%256;
TR1= 1;ET1= 1;
ET0= 1;TR0=1;
m=0;f=0;
IT0=1;EX0=1;
TH0=0;TL0=0;TR0=1;
EA=1;
delay(100);
push_val_steering=14; //舵機(jī)歸中
while (1){
if(IrOK==1) {
stoprun();
switch(Im[2]) {
case 0x16:
control_menu(); //返回主控菜單
break;
default:
break;
}
IrOK=0;
}
if(timer>=200){ //80MS檢測(cè)啟動(dòng)檢測(cè)一次 800
timer=0;
StartModule(); //啟動(dòng)檢測(cè)
Conut(); //計(jì)算距離
display();
if(S<=40) { //距離小于40CM
stoprun(); //小車(chē)停止
COMM(); //方向函數(shù)
} else
if(S>40){ //距離大于,40CM往前走
run();
}
}
}
}
/**********************************************************************************************
** 人工操控小車(chē)代碼
**********************************************************************************************/
void artificial( void )
{
m=0;f=0;
IT0=1;EX0=1;
TMOD=0x11;
TH0=0;TL0=0;
TR0=1;
EA=1;
delay(100);
speed();
display();
while(1) { /*無(wú)限循環(huán)*/
if(IrOK==1) {
switch(Im[2]) {
case 0x18: run(); //前進(jìn)
break;
case 0x52: backrun(); //后退
break;
case 0x08: leftrun(); //左轉(zhuǎn)
break;
case 0x5A: rightrun(); //右轉(zhuǎn)
break;
case 0x1C: stoprun(); //停止
break;
case 0x16: stoprun();
control_menu(); //返回主控菜單
break;
default:
break;
}
IrOK=0;
}
}
}
/**********************************************************************************************
** 小車(chē)主控菜單代碼
**********************************************************************************************/
void control_menu(void )
{
m=0;f=0;
IT0=1;EX0=1;
TMOD=0x11;
TH0=0;TL0=0;
TR0=1;
EA=1;
delay(100);
while(1){
if(IrOK==1) {
switch(Im[2]) {
case 0x18: push_val_steering=14; //舵機(jī)歸中
artificial(); //人工控制小車(chē)
break;
case 0x0C:
ultrasonic(); //超聲波避障
break;
case 0x5E:
Infrared(); //紅外線避障
break;
case 0x08: num = 4;
ultrasonic(); //超聲波紅外線避障
break;
default:
break;
}
IrOK=0;
}
}
}
/**********************************************************************************************
** 主函數(shù)
**********************************************************************************************/
void main(void)
{
while(1) { /*無(wú)限循環(huán)*/
control_menu(); //調(diào)用主控菜單
}
}
/**********************************************************************************************
** END FILE
**********************************************************************************************/
|
評(píng)分
-
查看全部評(píng)分
|