智能小車程序
按需開發(fā)可以根據(jù)自己的需求進(jìn)行定制,網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)構(gòu)思過程中功能建設(shè)理應(yīng)排到主要部位公司網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)的運(yùn)用實(shí)際效果公司網(wǎng)站制作網(wǎng)站建立與制做的實(shí)際意義
#include "reg52.h"
#define det_Dist 2.55 //單個脈沖對應(yīng)的小車行走距離,其值為車輪周長/4
#define RD 9 //小車對角軸長度
#define PI 3.1415926
#define ANG_90 90
#define ANG_90_T 102
#define ANG_180 189
/*============================全局變量定義區(qū)============================*/
sbit P10=P1^0; //控制繼電器的開閉
sbit P11=P1^1; //控制金屬接近開關(guān)
sbit P12=P1^2; //控制顏色傳感器的開閉
sbit P07=P0^7; //控制聲光信號的開啟
sbit P26=P2^6; //接收顏色傳感器的信號,白為0,黑為1
sbit P24=P2^4; //左
sbit P25=P2^5; //右 接收左右光傳感器的信號,有光為0
unsigned char mType=0; //設(shè)置運(yùn)動的方式,0 向前 1 向左 2 向后 3 向右
unsigned char Direction=0; //小車的即時朝向 0 朝上 1 朝左 2 朝下 3 朝右
unsigned sX=50; unsigned char sY=0; //小車的相對右下角的坐標(biāo) CM(sX,sY)
unsigned char StartTask=0; //獲得鐵片后開始執(zhí)行返回卸貨任務(wù),StartTask置一
unsigned char Inter_EX0=0; // 完成一個完整的任務(wù)期間只能有一次外部中斷
// Inter_EX0記錄外部中斷0的中斷狀態(tài)
// 0 動作最近的前一次未中斷過,
// 1 動作最近的前一次中斷過
unsigned char cntIorn=0; //鐵片數(shù)
unsigned char bkAim=2; //回程目的地,0為A倉庫,1為B倉庫,2為停車場,
//(在MAIN中接受鐵片顏色判斷傳感器的信號來賦值)
unsigned char Light_Flag=0;//進(jìn)入光引導(dǎo)區(qū)的標(biāo)志(1)
unsigned int cntTime_5Min=0;//時間周期數(shù),用于 T0 精確定時
unsigned int cntTime_Plues=0; //霍爾開關(guān)產(chǎn)生的脈沖數(shù)
/*============================全局變量定義區(qū)============================*/
/*------------------------------------------------*/
/*-----------------通用延遲程序-------------------*/
/*------------------------------------------------*/
void delay(unsigned int time) // time*0.5ms延時
{
unsigned int i,j;
for(j=0;jtime;j++)
{
for(i=0;i60;i++)
{;}
}
}
/*-----------------------------------------------*/
/*-------------------顯示控制模塊----------------*/
/*-----------------------------------------------*/
/*數(shù)碼管顯示,顯示鐵片的數(shù)目(設(shè)接在P0,共陰)*/
void Display(unsigned char n)
{
char Numb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77};
P0=Numb[n];
}
/*-----------------------------------------------*/
/*-------------------傳感器模塊------------------*/
/*-----------------------------------------------*/
/*光源檢測程序: */
/*用于糾正小車運(yùn)行路線的正確性*/
unsigned char LightSeek()
{ void Display(unsigned char);
bit l,r;
l=P24;
r=P25;
if(l==0r==1)
{
//Display(1);
return (3); //偏左,向右開
}
if(r==0l==1)
{
//Display(3);
return(1); //偏右,向左開
}
if((l==1r==1)||(l==0r==0))
{//Display(9);
return(0); //沒有偏離,前進(jìn)
}
}
/*鐵片檢測程序: */
/*判斷鐵片的顏色,設(shè)定bkAim,0為A倉庫,1為B倉庫,2為停車場*/
void IornColor()
{
delay(4000);
bkAim=(int)(P26);
Display((int)(P26)+2);
}
/*-----------------------------------------------*/
/*------------------運(yùn)動控制模塊-----------------*/
/*-----------------------------------------------*/
/*====基本動作層:完成基本運(yùn)動動作的程序集====*/
/*運(yùn)動調(diào)整程序: */
/*對小車的運(yùn)動進(jìn)行微調(diào)*/
void ctrMotor_Adjust(unsigned char t)
{
if(t==0)
{
P2=P2240|11; //用來解決兩電機(jī)不對稱的問題
delay(6);
}
if(t==3)
{
P2=P2250; //向左走
delay(1);
}
if(t==1)
{
P2=(P2245);
delay(1); //向右走
}
P2=((P2240)|15);
delay(10);
}
/*直走程序: */
/*控制小車運(yùn)動距離,dist為運(yùn)動距離(cm),type為運(yùn)動方式(0 2)*/
/*只改變小車sX 和 sY的值而不改變Direction的值. */
void ctrMotor_Dist(float dist,unsigned char type)
{unsigned char t=0;
mType=type;
P2=((P2240)|15);
cntTime_Plues=(int)(dist/det_Dist);
while(cntTime_Plues)
{
if(Inter_EX0==1StartTask==0)
{
cntTime_Plues=0;
break;
}
if(Light_Flag==1) t=LightSeek();
if(type==0) //向前走
{
P2=P2249;
delay(40);
ctrMotor_Adjust(t);
}
if(type==2) //向后退
{
P2=P2246;
delay(50);
ctrMotor_Adjust(t);
}
P2=((P2240)|15);
if(mType==2) delay(60);//剎車制動 0.5ms
else delay(75);
}
}
/*拐彎程序: */
/*控制小車運(yùn)動角度,type為運(yùn)動方式(1 3) */
/*只改變小車Direction的值而不改變sX 和 sY的值*/
void ctrMotor_Ang(unsigned char ang,unsigned char type,unsigned char dir)
{
unsigned char i=0;
mType=type;
P2=((P2240)|15);
cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90);
while(cntTime_Plues)
{
if(Inter_EX0==1StartTask==0)
{
cntTime_Plues=0;
break;
}
if(type==1) //向左走
{
P2=P2250;
delay(100);
ctrMotor_Adjust(0);
}
if(type==3) //向右走
{
P2=P2245;
delay(100);
ctrMotor_Adjust(0);
}
P2=((P2240)|15);
delay(50);//剎車制動 0.5ms
}
if(!(Inter_EX0==1StartTask==0))
{
Direction=dir;
}
}
/*====基本路線層:描述小車基本運(yùn)動路線的程序集====*/
/*當(dāng)小車到達(dá)倉庫或停車場時,放下鐵片或停車(0,1為倉庫,2為停車場)*/
void rchPlace()
{unsigned int time,b,s,g;
time=(int)(cntTime_5Min*0.065535);//只有一個數(shù)碼管時,輪流顯示全過程秒數(shù) 個 十 百
b=time%100;
s=(time-b*100)%100;
g=(time-b*100-s*10)%10;
if(bkAim==2)
{
//到達(dá)停車場了,停車
EA=0;
P2=((P2240)|15);
while(1)
{
Display(10); //N
delay(2000);
Display(cntIorn);
delay(2000);
Display(11);//A
delay(2000);
Display(b);
delay(2000);
Display(s);
delay(2000);
Display(g);
delay(2000);
}
}
else
{
if(Inter_EX0==1StartTask==1)P10=0; //到達(dá)倉庫,卸下鐵片
}
}
/*無任務(wù)模式: */
/*設(shè)置小車的固定運(yùn)動路線,未發(fā)現(xiàn)鐵片時的運(yùn)動路線*/
void BasicRoute()
{ //Light_Flag=1;
ctrMotor_Dist(153,0);
//Light_Flag=0;
ctrMotor_Ang(ANG_90,1,1);
ctrMotor_Dist(100-sX,0);
ctrMotor_Dist(125,2);
ctrMotor_Dist(73,0);
ctrMotor_Ang(ANG_90,1,2);
//Light_Flag=1;
ctrMotor_Dist(153,0);
//Light_Flag=0;
ctrMotor_Ang(ANG_180,1,0);
rchPlace();
}
/*任務(wù)模式: */
/*設(shè)置小車的發(fā)現(xiàn)鐵片后的運(yùn)動路線*/
void TaskRoute()
{
//基本運(yùn)行路線表,記載拐彎 0 向前 1 左拐 2 向后 3 右拐,正讀去A區(qū);反讀去B區(qū)
StartTask=1;
ctrMotor_Ang(ANG_90_T,1,2);
if(bkAim==1) //倉庫A
{
ctrMotor_Dist(10,0);
P2=((P2240)|15);
delay(60);
ctrMotor_Ang(ANG_90_T,1,3);
ctrMotor_Dist(100-sX,2);
ctrMotor_Ang(ANG_90_T,1,2);
Light_Flag=1;
ctrMotor_Dist(153,2);
Light_Flag=0;
// ctrMotor_Ang(208,1,0);
}
else if(bkAim==0) //倉庫B
{
ctrMotor_Dist(10,0);
P2=((P2240)|15);
delay(60);
ctrMotor_Ang(ANG_90_T,1,3);
ctrMotor_Dist(100-sX,0);
ctrMotor_Ang(ANG_90_T,1,0);
Light_Flag=1;
ctrMotor_Dist(153,2);
Light_Flag=0;
//ctrMotor_Ang(208,1,0);
}
delay(5000);
rchPlace();
}
/*---------------------------------------------*/
/*-------------------主程序段------------------*/
/*---------------------------------------------*/
void main()
{
delay(4000);
P2=0xff; //初始化端口
P07=0;
P1=0;
TMOD=0x01; //初始化定時器0/1 及其中斷
TL0=0;
TH0=0;
TR0=1;
ET0=1;
ET1=1;
IT0=1; //初始化外部中斷
EX0=1;
IT1=1;
EX1=1;
EA=1;
P11=1;
while(1)
{
Display(cntIorn);
bkAim=2;
BasicRoute();
if(Inter_EX0==1)
{
TaskRoute();//按獲得鐵片后的路線運(yùn)動
IE0=0;
EX0=1;
}
Inter_EX0=0;
}
}
/*----------------------------------------------------*/
/*----------------------中斷程序段--------------------*/
/*----------------------------------------------------*/
/*定時器0中斷程序: */
/*當(dāng)時間過了5分鐘,則就地停車并進(jìn)入休眠狀態(tài)*/
void tmOver(void) interrupt 1
{
cntTime_5Min++;
TL0=0;
TH0=0;
if(cntTime_5Min=4520)
{
Display(5);
P2=((P2240)|15);
EA=0; //停車程序
P07=1;
delay(4000);
PCON=0X00;
while(1);
}
}
/*外部中斷0中斷程序: */
/*發(fā)現(xiàn)鐵片,發(fā)出聲光信號并將鐵片吸起,發(fā)光二極管和蜂鳴器*/
/*并聯(lián)在一起(設(shè)接在P07). 0為A倉庫,1為B倉庫,2為停車場*/
void fndIorn(void) interrupt 0
{
unsigned char i;
P10=1;
P2=((P2240)|15); //停車
P07=1;
delay(1000);//剎車制動 0.5ms
P07=0;
Inter_EX0=1;
cntIorn++;
Display(cntIorn);
for(i=0;i40;i++)
{
P2=P2249;
delay(2);
P2=((P2240)|15);
delay(2);
}
P2=P2249;
delay(100);
P2=((P2240)|15); //停車
IornColor(); //判斷鐵片黑白,設(shè)置bkAim
for(i=0;i95;i++)
{
P2=P2249;
delay(3);
P2=((P2240)|15);
delay(2);
}
P2=((P2240)|15); //停車
delay(4000); //把鐵片吸起來
EX0=0;
}
/*外部中斷1中斷程序: */
/*對霍爾開關(guān)的脈沖記數(shù),對小車的位置進(jìn)行記錄,以便對小車進(jìn)行定位*/
void stpMove(void) interrupt 2
{
cntTime_Plues--;
if(Direction==0) //向上
{
if(mType==0) sY+=det_Dist;
else if(mType==2)
sY-=det_Dist;
}
else if(Direction==1) //向左
{
if(mType==0) sX+=det_Dist;
else if(mType==2)
sX-=det_Dist;
}
else if(Direction==2) //向下
{
if(mType==0) sY-=det_Dist;
else if(mType==2)
sY+=det_Dist;
}
else if(Direction==3) //向右
{
if(mType==0) sX-=det_Dist;
else if(mType==2)
sX+=det_Dist;
}
#includereg52.h
#define uchar unsigned char; //char單字節(jié)整型數(shù)據(jù)或字符型數(shù)據(jù)
#define uint unsigned int; //int聲明基本整型數(shù)據(jù)
#define PON 0
#define POFF 1
#define ON 1
#define OFF 0
#define SPEED2 100
#define SPEED1 50
uchar ito=0;
uchar m=0;
uchar time=0;
uchar PWM1=0;
uchar PWM2=0;
sbit p=P2^0; //控制左輪
sbit q=P2^1; //控制右輪
sbit p_green=P2^2;
sbit p_red=P2^3;
sbit TCRD1=P2^4;//此處是傳感器RPR220管腳位聲明
sbit TCRD2=P2^5;
sbit TCRD3=P2^6;
sbit TCRD4=P2^7;
int count1=0;//用于定時計(jì)數(shù)的兩個全局變量位聲明
int count2=0;
int x[4];
uchar table1[]={ 0x28, 0x7E, 0xA2, 0x62, 0x74, 0x61, 0x21, 0x7A, 0x20, 0x60,0xff};//0,1,2,3,4,5,6,7,8,9,關(guān)顯示,數(shù)碼管碼表,高電平有效
unsigned char code table2[]=
{0xfe,0xfd,0xfb, //11111110,11111101,11111011
0xf7,0xef,0xdf,0xbf,0x7f,}; //11110111,11101111,11011111,10111111,01111111
unsigned char dp=0x7f; //Use AND to add the decimal point/clock point.
unsigned char cp;
int s=0;
int sec=0; //定義路程,時間
char a;
int idi=0;
int j=0;
bit rup3=0;
int GAO=4000;
int T=0;//處理時間中斷3
int timeCount;//計(jì)時標(biāo)志
int wheelCount;//測距標(biāo)志
//int white=0;//測交叉線
void delay(int x)
{
int a;
int b;
for(a=x;a0;a--)
for(b=125;b0;b--);
}
void display()//顯示時間和路程
{
//顯示時間
P0=table1[x[idi]];
P1=table2[idi];
idi++;
if(idi==4)
idi=0;
delay(1);
}
void forward_turn1()//電機(jī)1前進(jìn)
{
if(PWM1)
p=PON;
else
p=POFF;
}
void forward_turn2()//電機(jī)2前進(jìn)
{
if(PWM2)
q=PON;
else
q=POFF;
}
void stop_turn1()//電機(jī)停止
{
P=POFF;
q=POFF;
}
void speed1(int ct,int sd)//電機(jī)1速度控制函數(shù),其中參數(shù) sd為生成 PWM 波
{
if(ct=sd)
PWM1=0;
else
PWM1=1;
}
void speed2(int ct,int sd)//電機(jī)2速度控制函數(shù),其中參數(shù) sd為生成 PWM 波
{
if(ct=sd)
PWM2=0;
else
PWM2=1;
}
void advance(int ct1,int sd1,int ct2,int sd2)//小車直線前進(jìn)函數(shù)
{
forward_turn1();
forward_turn2();
speed1(ct1,sd1);
speed2(ct2,sd2);
}
//*************以下是方案1, 通過使兩輪一快一慢來實(shí)現(xiàn)轉(zhuǎn)向*********
void left_turn1(int ct1,int sd1,int ct2,int sd2)//小車左轉(zhuǎn)
{
forward_turn1();
forward_turn2();
speed1(ct1,sd1);
speed2(ct2,sd2);
}
void right_turn1(int ct1,int sd1,int ct2,int sd2)//小車右轉(zhuǎn)
{
forward_turn1();
forward_turn2();
speed1(ct1,sd1);
speed2(ct2,sd2);
}
//*************以下是方案2, 通過使兩輪一慢傳,一停轉(zhuǎn)來實(shí)現(xiàn)轉(zhuǎn)向***
void left_turn2(int ct1,int sd1,int ct2,int sd2)//小車左轉(zhuǎn)
{
forward_turn1();
forward_turn2();
speed1(ct1,sd1);
speed2(ct2,sd2);
}
void right_turn2(int ct1,int sd1,int ct2,int sd2)//小車右轉(zhuǎn)
{
forward_turn1();
stop_turn1();
speed1(ct1,sd1);
speed2(ct2,sd2);
}
void main()
{
p=1;
q=1;
TMOD=0x11;//中斷模式設(shè)置
TH0=(65536-1000)/256;//定時器1初始化
TL0=(65536-1000)%256;
EA=1;
ET0=1;
TR0=1;
TH1=(65536-1000)/256;//定時器2初始化
TL1=(65536-1000)%256;
EA=1;
ET1=1;
TR1=1;
while(1)
{
..............
}
}
void time0()interrupt 1
{
TH0=(65536-5000)/256;//定時 5ms
TL0=(65536-5000)%256;
count1++;
ito++;
if(ito==200)
{
ito=0;
s++;
if(s==60)
{
s=0;
m++;
if(m==60)
{
m=0;
}
x[0]=m/10;
x[1]=m%10;
}
x[2] =s/10;
x[3] =s%10;
}
display();
if(count1==SPEED2)//周期是1s
count1=0;
count2++;
if(count2==SPEED2)//周期是1s
count2=0;
}
1. 你的flag沒有初始化。
2. while(flag!=1){}中的代碼有些問題。有幾處應(yīng)加上{ },給你改了一下:
while(flag!=1)
{
if(a5==0)
qianjin();
else
{ if(a4==0)
zuozhuan();
else
{ if(a6==0)
youzhuan();
else
flag=1;
}
}
}
你給的題盲點(diǎn)很多啊。
小車的前后左右函數(shù)。
while(1)
{
io口定義及初始化;
通過io讀取傳感器返回值;
對小車軌跡進(jìn)行初步判斷;
調(diào)用前后左右函數(shù)。
}
我以前是這么做的
void main ()//主函數(shù)程序入口 這個應(yīng)該明白吧 不明白的話 那就真沒辦法了
{
PWM_init();//初始化函數(shù)
while(1)//接下來是一個死循環(huán) 單片機(jī)中很常見的 一般不需要退出循環(huán)
{
//這里會循環(huán)讀取一些指令 然后完成相應(yīng)的操作 比如收取按鍵等
//也可能是檢查狀態(tài),某個寄存器或者pio的值 然后做一些功能
}
}