標(biāo)題:
關(guān)于51單片機智能循跡小車的驅(qū)動問題
[打印本頁]
作者:
超級羽
時間:
2019-11-2 01:02
標(biāo)題:
關(guān)于51單片機智能循跡小車的驅(qū)動問題
各位大神請教一下小車的驅(qū)動問題:程序燒錄進(jìn)單片機,電源啟動后,小車的輪子不轉(zhuǎn),用手撥動一下會極小的速度轉(zhuǎn)動(像功率不足,而且只有一側(cè)轉(zhuǎn)),占空比也調(diào)得比較高,不知道是哪里出問題了,請各位大神批評指教(用的是4節(jié)1.5伏的電池,驅(qū)動5個紅外對管,超聲波模塊,電機,不知道是不是輸入電壓不足的問題,也可能是我理解錯了pwm原理),下面是小車的代碼,新手第一次寫,請多包涵。(如有其他問題能幫忙一起指出嗎,麻煩各位了)
單片機源程序如下:
#include <reg52.h>
#include<intrins.h>
sbit IN1=P0^1; //左電機//
sbit IN2=P0^2;
sbit ENA=P0^0;
sbit IN3=P0^3; //右電機//
sbit IN4=P0^4;
sbit ENB=P0^5;
sbit Trig=P1^1; //超聲波模塊的TRIG,具體接口需要改變//
sbit Echo=P1^2; //超聲波模塊的ECHO
#define uc unsigned char
#define ui unsigned int
#define juli 25 //距離障礙物的距離//
#define leftgo {IN1=1, IN2=0;} //左電機正傳
#define leftback {IN1=0, IN2=1;} //左電機反轉(zhuǎn)
#define rightgo {IN3=0, IN4=1;} //右電機正傳
#define rightback {IN3=1, IN4=0;} //右電機反轉(zhuǎn)
uc ZKBR=0;
uc ZKBL=0;
uc t=0; //定時器計數(shù)次數(shù)//
uc FLAG; //超聲波超出測量范圍的標(biāo)志
ui sum; //超聲波模塊中定時器1所計的總數(shù)//
float L; //L為超聲波模塊中計算的與障礙物之間的距離//
sbit L1=P2^0; //五個紅外循跡模塊//
sbit L2=P1^2;
sbit M=P1^3;
sbit R2=P1^4;
sbit R1=P1^5;
void t0go() //定時器0開始工作的函數(shù)//
{
TMOD=0x01; //定時器t0工作方式為1//
TH0=(65536 - 100)/ 256; //定時器計時108.5微秒//
TL0=(65536 - 100)% 256;
EA=1; //開總中斷//
ET0=1; //打開定時器0中斷//
TR0=1; //開啟定時器//
}
void t1go() //定時器1馬上開始工作的函數(shù)//
{
TMOD=0x10;
EA=1; //可能出錯//
ET1=1;
}
void t0() interrupt 1 //t0的中斷函數(shù)//
{
TH0 =(65536-100)/ 256; //重裝定時器的初值//
TL0 =(65536-100)% 256;
if(t<ZKBL)
{
ENA=1;
}
else
{
ENA=0;
}
if(t < ZKBR)
{
ENB=1;
}
else
{
ENB=0;
}
++t;
if(t>=50)
{
t=0;
}
}
void t1() interrupt 3 //超聲波超出測量范圍//
{
FLAG=1;
}
void turnleft1() //左轉(zhuǎn)小轉(zhuǎn)彎//
{
ZKBL=30;
ZKBR=10;
}
void turnleft2() //左轉(zhuǎn)大轉(zhuǎn)彎//
{
ZKBL=50;
ZKBR=10;
}
void turnright1() //右轉(zhuǎn)小轉(zhuǎn)彎//
{
ZKBL=10;
ZKBR=30;
}
void turnright2() //右轉(zhuǎn)大轉(zhuǎn)彎//
{
ZKBL=10;
ZKBR=50;
}
void go()
{
ZKBL=40;
ZKBR=40;
leftgo;
rightgo;
}
void back()
{
ZKBL=10;
ZKBR=10;
leftback;
rightback;
}
void stop()
{
ZKBL=0;
ZKBL=0;
}
void xunji()
{
uc flag;
if ((R2==0)&&(L1==1)&&(L2==1)&&(R1==1)) //小右轉(zhuǎn)//
{
flag=1;
}
else if((R1==0)&&(R2==0)&&(L1==1)&&(L2==1)) //大右轉(zhuǎn)//
{
flag=2;
}
else if((R2==0)&&(L2==1)) //停車
{
flag=3;
}
else if((R2==1)&&(R1==1)&&(L1==1)&&(L2==0)) //小左轉(zhuǎn)//
{
flag=4;
}
else if((R1==1)&&(R2==1)&&(L1==0)&&(L2==0)) //大左轉(zhuǎn)//
{
flag=5;
}
else if((L1==0)&&(L2==1)&&(M==1)&&(R1==1)&&(R2==1))
{
flag=5;
}
else if((L1==1)&&(L2==1)&&(M==1)&&(R1==0)&&(R2==1))
{
flag=2;
}
else if((L1==1)&&(L2==1)&&(M==1)&&(R1==1)&&(R2==1)) //特殊情況,當(dāng)小車無法掃描到黑線時,小車后退//
{
flag=6;
}
switch(flag)
{
case 1:turnright1(); break;
case 2:turnright2(); break;
case 3:stop(); break;
case 4:turnleft1(); break;
case 5:turnleft2(); break;
case 6:back(); break;
default:go(); break;
}
}
void send() //使模塊開始發(fā)送8個方波//
{
Trig=1;
_nop_(); //單片機延后一個機器周期//
_nop_(); //設(shè)置目的在于使Trig口開始發(fā)送方波//。
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
Trig=0;
}
void distance()
{
TH1=0; //使定時器1計數(shù)歸位//
TL1=0;
send();
while(!Echo); //!echo=0,既echo=1輸出高電平時跳出while,實質(zhì)是等待輸出開始后便打開計時器//
TR1=1;
while(Echo); //等待echo口輸出高電平結(jié)束后(即輸出低電平時)后便關(guān)閉計時器//
TR1=1;
sum=TH1*256+TL1; //得到計時器在過程中計的總數(shù)//
L=(sum*1.87)/100; //已得到的公式 1.87為在20度溫度下的聲速取值344,L的單位是厘米//
if(L<=juli && FLAG==0) //上邊已經(jīng)定義了距離障礙物的最小距離,單位是厘米//
{
back();
}
if(FLAG==1) //超出測量
{
FLAG=0;
}
}
void main()
{
t0go();
t1go();
leftgo;
rightgo;
while(1)
{
xunji();
distance();
}
}
作者:
邏輯落寞
時間:
2019-11-2 10:14
把原理圖放上來看看
作者:
超級羽
時間:
2019-11-2 17:12
邏輯落寞 發(fā)表于 2019-11-2 10:14
把原理圖放上來看看
原理圖是關(guān)于什么的
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1