智能循迹小车程序

合集下载

智能循迹小车变速转弯程序

智能循迹小车变速转弯程序

include<reg52.h>define uchar unsigned chardefine uint unsigned intuchar a;i;time_count=0;count=0;Dutycycle0=50;Dutycycle1=50;flag;uchar state;/定义电机控制位/sbit INT11=P0^0; //电机控制位;左电机左;芯片中的总开关sbit INT22=P0^1; // 右电机控制位;高电平有效sbit INT33=P0^2; //控制左电机;从而控制其中的车轮sbit INT44=P0^3;sbit funpwm0=P1^3; ///两个控制PWM的端口sbit funpwm1=P1^4;sbit IO4=P2^0; //ST188输出端口sbit IO1=P2^1;sbit IO2=P2^2;sbit IO3=P2^3;sbit IO5=P0^7;sfr CCON = 0xD8; // PCA控制寄存器sbit CCF0 = CCON^0; // PCA模块0中断标志sbit CCF1 = CCON^1; // PCA模块0中断标志sbit CR = CCON^6; // PCA计数器阵列溢出标志位sbit CF = CCON^7; // PCA计数器阵列运行控制位sfr CMOD = 0xD9; // PCA工作模式寄存器sfr CL = 0xE9; // PCA的16位计数器----低8位sfr CH = 0xF9; // PCA的16位计数器----高8位sfr CCAPM0 = 0xDA; // PCA模块0的输出脉冲频率sfr CCAP0L = 0xEA; // PCA捕获、比较寄存器——低位字节sfr CCAP0H = 0xFA; // PCA捕获、比较寄存器——高位字节sfr CCAPM1 = 0xDB; // PCA模块1的输出脉冲频率sfr CCAP1L = 0xEB; // 同上sfr CCAP1H = 0xFB; // 同上sfr PCAPWM0= 0xf2; // PCA模块0的PWM寄存器sfr PCAPWM1= 0xf3; // PCA模块1的PWM寄存器/------------------------------------------------uS延时函数;含有输入参数 unsigned char t;无返回值unsigned char 是定义无符号字符变量;其值的范围是0~255 这里使用晶振12M;精确延时请使用汇编;大致延时长度如下 T=tx2+5 uS------------------------------------------------/void DelayUs2x unsigned char t{while--t;}/------------------------------------------------mS延时函数;含有输入参数 unsigned char t;无返回值unsigned char 是定义无符号字符变量;其值的范围是0~255 这里使用晶振12M;精确延时请使用汇编------------------------------------------------/void DelayMs unsigned char t{while t--{//大致延时1mSDelayUs2x245;DelayUs2x245;}}/速度设定:通过改变参数a;b 来来改变两路pwm的占空比数值越大占空比越小/void pwm0unsigned int a{CCAP0L=a;CCAP0H=a;}void pwm1unsigned int b{CCAP1L=b;CCAP1H=b;}void pwm_Init{CL=0;CH=0;CMOD=0x00;CCAP0H=CCAP0L=0x00;CCAPM0=0x42;CCAP1H=CCAP1L=0x00;CCAPM1=0x42;CR=1;}delayi{int k;j;for j=1000;j>0;j--for k=200;k>0;k--i--;}former{INT11=1;INT22=0;INT33=1;INT44=0;pwm045;pwm140;DelayMs1000;}turnleft0{pwm0130;pwm130;DelayMs1000;}turnright0{pwm030;pwm1130;DelayMs1000;}turnleft1{pwm00Xff;pwm10;DelayMs1000; }turnright1{pwm00;pwm10Xff;DelayMs1000;}stop{INT11=1;INT22=1;INT33=1;INT44=1;}void turnleft2 {INT11=1;INT22=0;INT33=0;INT44=1;pwm00;pwm130;}void turnright2 {INT11=0;INT22=1;INT33=1;INT44=0;pwm030;pwm10;}/主函数/main{while1{pwm_Init;DelayMs20;while1{if IO5==1 turnright2;else{INT11=1;INT22=1;INT33=1;INT44=1;}/ifIO3==0&&IO2==0&&IO1==0&&IO4==0 former;ifIO3==0&&IO2==0&&IO1==0&&IO4==1 turnright1; ifIO3==0&&IO2==0&&IO1==1&&IO4==0 turnright0; ifIO3==0&&IO2==0&&IO1==1&&IO4==1 turnleft2; ifIO3==0&&IO2==1&&IO1==0&&IO4==0 turnleft0; ifIO3==0&&IO2==1&&IO1==0&&IO4==1 turnright1; ifIO3==0&&IO2==1&&IO1==1&&IO4==0 former;ifIO3==0&&IO2==1&&IO1==1&&IO4==1 turnleft2; ifIO3==1&&IO2==0&&IO1==0&&IO4==0 turnleft1; ifIO3==1&&IO2==0&&IO1==1&&IO4==0 turnleft0; ifIO3==1&&IO2==0&&IO1==0&&IO4==1 former;ifIO3==1&&IO2==0&&IO1==1&&IO4==1 turnright1; ifIO3==1&&IO2==1&&IO1==0&&IO4==0 turnright2; ifIO3==1&&IO2==1&&IO1==0&&IO4==1 turnleft1; ifIO3==1&&IO2==1&&IO1==1&&IO4==0 turnright2; ifIO3==1&&IO2==1&&IO1==1&&IO4==1 former;/ }}}。

智能循迹避障小车完整程序(亲测好使)

智能循迹避障小车完整程序(亲测好使)

智能循迹避障小车完整程序(亲测好使)/*******************************************//利用51定时器产生PWM波来调节电机速度//速度变化范围从0-100可调//使用三路做寻迹使用,哪一路检测在黑线哪一路为//高电平//没检测到黑线表示有反射对应输出低电平信号*********************************************/#include<>#define uint unsigned int#define uchar unsigned char/*电机四个接口定义*/sbit in1=P0^0;sbit in2=P0^1;sbit in3=P0^2;sbit in4=P0^3;/*计时器*/uchar j,k,i,a,A1,A2,second,minge,minshi;sbit dula=P2^6;sbit wela=P2^7;uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};uchar code table2[]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};void delay(uchar i){for(j=i;j>0;j--)for(k=110;k>0;k--);}void display(uchar sh_c,uchar g_c,uchar min_ge,uchar min_shi) {dula=1;P0=table[sh_c];dula=0;P0=0xff;wela=1;P0=0xfb;wela=0;delay(5);dula=1;P0=table[g_c];dula=0;P0=0xff;wela=1;P0=0xf7;wela=0;delay(5);dula=1;P0=table[min_shi];dula=0;P0=0xff;wela=1;P0=0xfe;wela=0;delay(5);dula=1;P0=table2[min_ge];dula=0;P0=0xff;wela=1;P0=0xfd;wela=0;delay(5);}/*左、中、右三路循迹传感器接口定义*/ sbit zuo=P1^0; sbit zhong=P1^1;sbit you=P1^2;/*避障接口定义*/sbit bz_zuo=P1^3;sbit bz_zhong=P1^4;sbit bz_you=P1^5;uchar count = 0;/*利用定时器0定时中断,产生PWM波*/ void Init_timer() {TH0 = (65535-10)/256;TL0 = (65535-10)%256;TMOD = 0x01;TR0 = 1;ET0 = 1;EA = 1;}/*左轮速度调节程序*/void zuolun(uchar speed){if(count <= speed) //count计数变量{in1 = 1;in2 = 0;}else{in1 = 0;in2 = 1;}}void youlun(uchar speed) //同上{if(count<= speed){in3 = 1;in4 = 0;}else{in3 = 0;in4 = 1;}}void Inline() //检测黑线信号{uchar temp;temp =P1;switch(temp){case 0x01:zuolun(0); youlun(90);break; //左侧循迹传感器压线,小车向左前修正case 0x02:zuolun(100);youlun(100);break; //中间循迹传感器压线,保持直走此处两值使电机速度保持相同case 0x04:zuolun(90); youlun(0);break; //右侧循迹传感器压线,小车向右前修正case 0x08:zuolun(90); youlun(0);break; //左侧避障传感器有信号小车右转case 0x10:zuolun(90); youlun(0);break; //中间避障传感器有信号小车左转case 0x20:zuolun(90); youlun(0);break; //右侧避障传感器有信号小车左转}/*if(zuo==1){zuolun(10);youlun(50);}else if(zhong==1){zuolun(99);youlun(99);}else if(you==1){zuolun(50);youlun(10);} */}void main() //主函数{Init_timer(); //调用函数while(1){Inline();minge=0;minshi=0;second++;if(second==60)second=0,minge++;A1=second/10;A2=second%10;if(minge==10)minge=0,minshi++;for(a=200;a>0;a--){display(A1,A2,minge,minshi);};}}void Timer0_int()interrupt 1 //定时器中断计数{TH0 = (65535-10)/256;TL0 = (65535-10)%256;count ++;if(count >= 100){count = 0;}}。

自动循迹小车程序(包括LCD显示模块)

自动循迹小车程序(包括LCD显示模块)

#include<reg51.h>#define uchar unsigned char#define uint unsigned intunsigned char NUM=0 ;sbit LSEN1=P2^0;sbit LSEN2=P2^1;sbit MSEN1=P2^2;sbit RSEN1=P2^3;sbit RSEN2=P2^4;//**传感器***/sbit IN1=P1^0;sbit IN2=P1^1;sbit IN3=P1^2;sbit IN4=P1^3;sbit ENA=P1^4;sbit ENB=P1^5;void qianjin();void turn_left();void turn_right();//******************直行******************// void qianjin(){IN1=1;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;}//***************左转函数***************// void turn_left(){IN1=0;IN2=0;IN3=1;IN4=0;ENA=1;ENB=1;}//***************右转函数***************// void turn_right(){IN1=1;IN2=0;IN3=0;IN4=0;ENA=1;ENB=1;}//***************循迹函数*****************//void xunji(){uchar flag;if((RSEN1==1)&&(RSEN2==1)&&(MSEN1==0)&&(LSEN1==1)&&(LSEN2==1)) { flag=0; }//*******直行*******//elseif((RSEN2==0)&&(RSEN1==1)&&(LSEN1==1)&&(LSEN2==1)&&(MSEN1==1)) { flag=1;} //***左偏1,小右转***//elseif((RSEN1==1)&&(RSEN2==1)&&(LSEN1==1)&&(LSEN2==0)&&(MSEN1==1)) { flag=2; } //***右偏1,小左转***//elseif((RSEN1==1)&&(RSEN2==1)&&(LSEN1==0)&&(LSEN2==1)&&(MSEN1==1)) { flag=3; } //***右偏2,大左转***//elseif((RSEN2==1)&&(RSEN1==0)&&(LSEN1==1)&&(LSEN2==1)&&(MSEN1==1)) { flag=4;} //***左偏2,大右转***//elseif((RSEN1==1)&&(RSEN2==1)&&(LSEN1==0)&&(LSEN2==0)&&(MSEN1==1)) { flag=5; } //***右偏3,中左转***//elseif((RSEN1==0)&&(RSEN2==0)&&(LSEN1==1)&&(LSEN2==1)&&(MSEN1==1)) { flag=6; } //***左偏3,中右转***//elseif((RSEN1==0)&&(RSEN2==0)&&(LSEN1==1)&&(LSEN2==1)&&(MSEN1==0)) { flag=7; }elseif((RSEN1==0)&&(RSEN2==0)&&(LSEN1==1)&&(LSEN2==0)&&(MSEN1==0)) { flag=8; }elseif((RSEN1==1)&&(RSEN2==1)&&(LSEN1==0)&&(LSEN2==0)&&(MSEN1==0)) { flag=9;}elseif((RSEN1==1)&&(RSEN2==0)&&(LSEN1==0)&&(LSEN2==0)&&(MSEN1==0)){ flag=10;}elseif((RSEN1==0)&&(RSEN2==1)&&(LSEN1==1)&&(LSEN2==1)&&(MSEN1==0)) { flag=11;}elseif((RSEN1==1)&&(RSEN2==1)&&(LSEN1==0)&&(LSEN2==1)&&(MSEN1==0)) { flag=12;}switch (flag){ case 0:qianjin();break;case 1:turn_right();break;case 2:turn_left();break;case 3:turn_left();break;case 4:turn_right();break;case 5:turn_left();break;case 6:turn_right();break;case 7:turn_right();break;case 8:turn_right();break;case 9:turn_left();break;case 10:turn_left();break;case 11:qianjin();break;case 12:qianjin();break;default: break; }}//****************主程序****************// void main(){qianjin();while(1){xunji(); //*********寻迹**********// }}。

循迹小车程序代码

循迹小车程序代码

//(在MAIN中接受铁片颜色判断传感器的信号来赋值) unsigned char Light_Flag=0;//进入光引导区的标志(1) unsigned int cntTime_5Min=0;//时间周期数,用于 T0 精确定时 unsigned int cntTime_Plues=0; //霍尔开关产生的脉冲数 /*============================全局变量定义区 ============================*/ /*------------------------------------------------*/ /*-----------------通用延迟程序-------------------*/ /*------------------------------------------------*/ void delay(unsigned int time) { unsigned int i,j; for(j=0;j<time;j++) { for(i=0;i<60;i++) {;} } } /*-----------------------------------------------*/ /*-------------------显示控制模块----------------*/ /*-----------------------------------------------*/ /*数码管显示,显示铁片的数目(设接在P0,共阴)*/ void Display(unsigned char n) { char Numb[12]= {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77}; P0=Numb[n]; } // time*0.5ms延时

智能循迹小车程序

智能循迹小车程序

智能小车程序(共三个)第一个:#include "reg52.h"#define det_Dist 2.55 //单个脉冲对应的小车行走距离,其值为车轮周长/4#define RD 9 //小车对角轴长度#define PI 3.1415926#define ANG_90 90#define ANG_90_T 102#define ANG_180 189/*============================全局变量定义区============================*/sbit P10=P1^0; //控制继电器的开闭sbit P11=P1^1; //控制金属接近开关sbit P12=P1^2; //控制颜色传感器的开闭sbit P07=P0^7; //控制声光信号的开启sbit P26=P2^6; //接收颜色传感器的信号,白为0,黑为1sbit P24=P2^4; //左sbit P25=P2^5; //右接收左右光传感器的信号,有光为0unsigned char mType=0; //设置运动的方式,0 向前1 向左2 向后3 向右unsigned char Direction=0; //小车的即时朝向0 朝上1 朝左2 朝下3 朝右unsigned sX=50; unsigned char sY=0; //小车的相对右下角的坐标CM(sX,sY)unsigned char StartTask=0; //获得铁片后开始执行返回卸货任务,StartTask置一unsigned char Inter_EX0=0; // 完成一个完整的任务期间只能有一次外部中断// Inter_EX0记录外部中断0的中断状态// 0 动作最近的前一次未中断过,// 1 动作最近的前一次中断过unsigned char cntIorn=0; //铁片数unsigned char bkAim=2; //回程目的地,0为A仓库,1为B仓库,2为停车场,//(在MAIN中接受铁片颜色判断传感器的信号来赋值)unsigned char Light_Flag=0;//进入光引导区的标志(1)unsigned int cntTime_5Min=0;//时间周期数,用于T0 精确定时unsigned int cntTime_Plues=0; //霍尔开关产生的脉冲数/*============================全局变量定义区============================*//*------------------------------------------------*//*-----------------通用延迟程序-------------------*//*------------------------------------------------*/void delay(unsigned int time) // time*0.5ms延时{unsigned int i,j;for(j=0;j<time;j++){for(i=0;i<60;i++){;}}}/*-----------------------------------------------*//*-------------------显示控制模块----------------*//*-----------------------------------------------*//*数码管显示,显示铁片的数目(设接在P0,共阴)*/void Display(unsigned char n){char Numb[12]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x37,0x77}; P0=Numb[n];}/*-----------------------------------------------*//*-------------------传感器模块------------------*//*-----------------------------------------------*//*光源检测程序: *//*用于纠正小车运行路线的正确性*/unsigned char LightSeek(){ void Display(unsigned char);bit l,r;l=P24;r=P25;if(l==0&&r==1){//Display(1);return (3); //偏左,向右开}if(r==0&&l==1){//Display(3);return(1); //偏右,向左开}if((l==1&&r==1)||(l==0&&r==0)){//Display(9);return(0); //没有偏离,前进}}/*铁片检测程序: *//*判断铁片的颜色,设定bkAim,0为A仓库,1为B仓库,2为停车场*/ void IornColor(){delay(4000);bkAim=(int)(P26);Display((int)(P26)+2);}/*-----------------------------------------------*//*------------------运动控制模块-----------------*//*-----------------------------------------------*//*====基本动作层:完成基本运动动作的程序集====*//*运动调整程序: *//*对小车的运动进行微调*/void ctrMotor_Adjust(unsigned char t){if(t==0){P2=P2&240|11; //用来解决两电机不对称的问题delay(6);}if(t==3){P2=P2&250; //向左走delay(1);}if(t==1){P2=(P2&245);delay(1); //向右走}P2=((P2&240)|15);delay(10);}/*直走程序: *//*控制小车运动距离,dist为运动距离(cm),type为运动方式(0 2)*/ /*只改变小车sX 和sY的值而不改变Direction的值. */ void ctrMotor_Dist(float dist,unsigned char type){unsigned char t=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)(dist/det_Dist);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(Light_Flag==1) t=LightSeek();if(type==0) //向前走{P2=P2&249;delay(40);ctrMotor_Adjust(t);}if(type==2) //向后退{P2=P2&246;delay(50);ctrMotor_Adjust(t);}P2=((P2&240)|15);if(mType==2) delay(60);//刹车制动0.5mselse delay(75);}}/*拐弯程序: *//*控制小车运动角度,type为运动方式(1 3)*//*只改变小车Direction的值而不改变sX 和sY的值*/void ctrMotor_Ang(unsigned char ang,unsigned char type,unsigned char dir) {unsigned char i=0;mType=type;P2=((P2&240)|15);cntTime_Plues=(int)((PI*RD*90/(180*det_Dist)*1.2)*ang/90);while(cntTime_Plues){if(Inter_EX0==1&&StartTask==0){cntTime_Plues=0;break;}if(type==1) //向左走{P2=P2&250;delay(100);ctrMotor_Adjust(0);}if(type==3) //向右走{P2=P2&245;delay(100);ctrMotor_Adjust(0);}P2=((P2&240)|15);delay(50);//刹车制动0.5ms}if(!(Inter_EX0==1&&StartTask==0)){Direction=dir;}}/*====基本路线层:描述小车基本运动路线的程序集====*//*当小车到达仓库或停车场时,放下铁片或停车(0,1为仓库,2为停车场)*/void rchPlace(){unsigned int time,b,s,g;time=(int)(cntTime_5Min*0.065535);//只有一个数码管时,轮流显示全过程秒数个十百b=time%100;s=(time-b*100)%100;g=(time-b*100-s*10)%10;if(bkAim==2){//到达停车场了,停车EA=0;P2=((P2&240)|15);while(1){Display(10); //Ndelay(2000);Display(cntIorn);delay(2000);Display(11);//Adelay(2000);Display(b);delay(2000);Display(s);delay(2000);Display(g);delay(2000);}}else{if(Inter_EX0==1&&StartTask==1)P10=0; //到达仓库,卸下铁片}}/*无任务模式: *//*设置小车的固定运动路线,未发现铁片时的运动路线*/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();}/*任务模式: *//*设置小车的发现铁片后的运动路线*/void TaskRoute(){//基本运行路线表,记载拐弯0 向前1 左拐2 向后3 右拐,正读去A区;反读去B区StartTask=1;ctrMotor_Ang(ANG_90_T,1,2);if(bkAim==1) //仓库A{ctrMotor_Dist(10,0);P2=((P2&240)|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=((P2&240)|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();//按获得铁片后的路线运动IE0=0;EX0=1;}Inter_EX0=0;}}/*----------------------------------------------------*//*----------------------中断程序段--------------------*//*----------------------------------------------------*//*定时器0中断程序: *//*当时间过了5分钟,则就地停车并进入休眠状态*/ void tmOver(void) interrupt 1{cntTime_5Min++;TL0=0;TH0=0;if(cntTime_5Min>=4520){Display(5);P2=((P2&240)|15);EA=0; //停车程序P07=1;delay(4000);PCON=0X00;while(1);}}/*外部中断0中断程序: *//*发现铁片,发出声光信号并将铁片吸起,发光二极管和蜂鸣器*//*并联在一起(设接在P07). 0为A仓库,1为B仓库,2为停车场*/ void fndIorn(void) interrupt 0{unsigned char i;P10=1;P2=((P2&240)|15); //停车P07=1;delay(1000);//刹车制动0.5msP07=0;Inter_EX0=1;cntIorn++;Display(cntIorn);for(i=0;i<40;i++){P2=P2&249;delay(2);P2=((P2&240)|15);delay(2);}P2=P2&249;delay(100);P2=((P2&240)|15); //停车IornColor(); //判断铁片黑白,设置bkAimfor(i=0;i<95;i++)P2=P2&249;delay(3);P2=((P2&240)|15);delay(2);}P2=((P2&240)|15); //停车delay(4000); //把铁片吸起来EX0=0;}/*外部中断1中断程序: *//*对霍尔开关的脉冲记数,对小车的位置进行记录,以便对小车进行定位*/ 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;}第二个:#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit moto1=P1^5;sbit moto2=P1^6;sbit moto3=P2^0;sbit moto4=P2^1;sbit en1=P1^7;sbit en2=P2^2;//*循迹口七个红外传感器*///////////////sbit left1=P1^0;//*左边传感器*//sbit left2=P1^1;sbit left3=P1^2;sbit mid=P1^3;//*黑线位置*//sbit right1=P1^4;sbit right2=P2^3;sbit right3=P2^4;//*右边传感器*//////////////// sbit hled=P0^0;sbit bled=P0^1;sbit lled=P0^2;sbit rled=P0^3;sbit bizhang=P2^5;uchar pro_head;uchar pro_back;uchar i;uchar j; //前后占空比标志void delay(uint z){uchar i;while(z--){for(i=0;i<121;i++);}}/********初始化定时器,中断************/ void init(){TMOD=0x01;TH0=(65536-100)/256;TL0=(65536-100)%256;EA=1;TR0=1;en1=1;en2=1;}void time0(void) interrupt 1{i++;j++;if(i<=pro_back){en1=1;}else{en1=0;}if(i==40){en1=~en1;i=0;}if(j<=pro_head){en2=1;}else{en2=0;}if(j==40){en2=~en2;j=0;}TH0=(65536-100)/256;TL0=(65536-100)%256;}void qianjin()//*直行*///////////////////// {pro_back=15;pro_head=5;moto1=0;moto2=0;moto4=0;lled=1;rled=1;bled=1;}void turn_right1()//*右转1函数*//{pro_back=10;pro_head=15;moto1=0;moto2=1;moto3=1;moto4=0;}。

循迹小车(程序)

循迹小车(程序)

附录程序目录一、前言------------------------------------------------------------二、小车功能------------------------------------------------------三、元器件选择--------------------------------------------------四、I/O分配及硬件连接简图---------------------------------五、相关模块、算法---------------------------------------------六、系统框图------------------------------------------------------七、调试过程------------------------------------------------------八、小车图片资料---------------------------------------------------九、讲座所感------------------------------------------------------十、实习总结------------------------------------------------------一、前言感谢生产实习能给我们这次实现自己想法的机会,虽然实验条件异常简陋、资金投入非常有限,总体感觉我的队友们灰常灰常给力啊,我感觉我是抱到大腿了--王威,夏青、峰哥,团队气氛非常好,大家一起讨论,一起分工研究模块,最后一起解决问题调试程序,而且是不同的组合在不同阶段解决了不同的问题,大家精诚合作,各显身手,在奋战中给大三学年画上了圆满的句号。

之前我们本来商量是不是可以拿往年电子设计大赛的题目过来做,如果难度太大就算只实现一部分功能也算是成功完成了,结果研究一天后发现电子设计大赛的题目需要很长时间的知识积累啊,基本上都是准备一个月以上然后开工的,后来王威提议要不我们做个小车吧,超声波测距实现自动物体追踪,控制核心采用单片机,传感器采用广泛用于避障和测距的超声波传感器,前进和后退用普通伺服电机和电机驱动模块实现。

智能红外循迹小车程序

智能红外循迹小车程序

#include<reg52.h>#define uint unsigned int#define uchar unsigned char#define ulong unsigned longsbit you_2=P2^0;//红外探测端口定义sbit you_1=P2^1;sbit zhong=P2^2;sbit zuo_1=P2^3;sbit zuo_2=P2^4;sbit CG=P0^1;sbit DC=P0^0;uchar code L_F[8]= {0x10,0x30,0x20,0x60,0x40,0xc0,0x80,0x90};//左电机正转uchar code L_B[8]= {0x90,0x80,0xc0,0x40,0x60,0x20,0x30,0x10};//左电机反转uchar code R_F[8]= {0x01,0x03,0x02,0x06,0x04,0x0c,0x08,0x09};//右电机正转uchar code R_B[8]= {0x09,0x08,0x0c,0x04,0x06,0x02,0x03,0x01};//右电机反转uchar code B_F[8]= {0x91,0x83,0xc2,0x46,0x64,0x2c,0x38,0x19};//左反右正uchar code F_B[8]= {0x19,0x38,0x2c,0x64,0x46,0xc2,0x83,0x91}; //左正右反uchar code duandian[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};//断电unsigned char code qianjin[]={0x11,0x33,0x22,0x66,0x44,0xcc,0x88,0x99};//前进unsigned char h[]={0x11,0x33,0x22,0x66,0x44,0xcc,0x88,0x99};//uchar i;void delay(uint z){uint k ;uint j;for(k=0; k<z; k++)for(j=0; j<110; j++);}void QJ(unsigned int i){for(i=0;i<8;i++){P1=h[i]=qianjin[i];delay(13);}}void DD(){P1=0x00;delay(300);}void wtj(){while(1){if(P2==0xff){DD();delay(1000);break;}else{QJ(8);}}}void YG_1(){unsigned char i;for(i=0;i<8;i++){P1=h[i]=F_B[i];delay(10);}}void ZG_1(){ unsigned char i;for(i=0;i<8;i++){P1=h[i]=B_F[i];delay(10);}}void byg(){while(1){if(P2==0xfb)break;else if(P2==0xf9)break;else if(P2==0xfd)break;/*if(P2^0==0)break;else if(P2^1==0)break;/*else if(P2^2==0)break;else if(P2^3==0)break;else if(P2^4==0)break;*/elseYG_1();}}void bzg(){while(1){if(P2==0xfb)break;else if(P2==0xf3)break;else if(P2==0xf7)break;/*if(P2^0==0)break;else if(P2^1==0)break;else if(P2^2==0)break;if(P2^3==0)break;else if(P2^4==0)break;*/elseZG_1();}}void YG_2(){//unsigned char i; //unsigned char g;if(P2==0xfa){//delay(4000); wtj();byg();/*for(g=0;g<40;g++){for(i=0;i<8;i++){P1=F_B[i];delay(20);}} */}else if(P2==0xf2){//delay(4000); wtj();byg();/*for(g=0;g<40;g++){for(i=0;i<8;i++){P1=F_B[i];delay(20);}}*/}else if(P2==0xf6){//delay(4000);byg();/*for(g=0;g<40;g++){for(i=0;i<8;i++){P1=F_B[i];delay(20);}}*/}else if(P2==0xf4){//delay(4000); wtj();byg();/*for(g=0;g<40;g++){for(i=0;i<8;i++){P1=F_B[i];delay(20);}}*/}else ;}void ZG_2(){//unsigned char i; //unsigned char g;if(P2==0xeb){//delay(4000); wtj();bzg();/*for(g=0;g<40;g++){for(i=0;i<8;i++){P1=B_F[i];delay(20);}}*/else if(P2==0xe9){//delay(4000); wtj();bzg();/*for(g=0;g<40;g++) {for(i=0;i<8;i++){P1=B_F[i];delay(20);}}*/}else if(P2==0xed){//delay(4000); wtj();bzg();/*for(g=0;g<40;g++) {for(i=0;i<8;i++){P1=B_F[i];delay(20);}}*/}else if(P2==0xe5){//delay(4000); wtj();bzg();/*for(g=0;g<40;g++) {for(i=0;i<8;i++){P1=B_F[i];delay(20);}}*/}else ;}void ZG(){unsigned char i;for(i=0;i<8;i++){P1=h[i]=R_F[i];delay(11);}}void YG(){unsigned char i;for(i=0;i<8;i++){P1=h[i]=L_F[i];delay(11);}}/*void HT(){unsigned char i;for(i=0;i<8;i++){P1=houtui[i];delay(55);}}*/void zd(){while(1){if(P2==0xe0)QJ(8);else if(P2==0xff){while(1){DD();}}else{QJ(80);if(P2==0xff){while(1){DD();}}else{DC=0;break;break;}}}}void zd1(){while(1){if(P2==0xe0)QJ(8);else if(P2==0xff){while(1){DD();}}else{QJ(80);if(P2==0xff)while(1){DD();}}else{DC=0;break;}}}}void hy(){unsigned char i;for(i=0;i<8;i++){P1=h[i];delay(10);}}void main(){DC=1;while(1){QJ(8);if(P2!=0xff){delay(9000);break;}}while(1){DC=1;if(CG==1){delay(9000);DC=1;while(1){switch(P2){case 0xfb:QJ(8);break;//11011case 0xf1:QJ(8);break;//10001case 0xf3:QJ(8);break;//10011case 0xf7:ZG();break;//10111case 0xe7:ZG_1();break;//00111case 0xef:ZG_1();break;//01111case 0xe3:ZG_1();break; //00011case 0xe1:ZG_1();break; //00001case 0xf9:QJ(8);break;//11001case 0xfd:YG();break;//11101case 0xfc:YG_1();break;//11100case 0xfe:YG_1();break;//11110case 0xf8:YG_1();break; //11000case 0xf0:YG_1();break;//10000case 0xfa://11010QJ(16);// delay(4000);YG_2();//f7 break;case 0xf2://10010QJ(16);// delay(4000);YG_2();break;case 0xf6://10110QJ(16);// delay(4000);YG_2();break;case 0xf4://10100QJ(16);// delay(4000);YG_2();break;case 0xeb://01011QJ(16);//delay(4000);ZG_2();//fd break;case 0xe9://01001QJ(16);//delay(4000);ZG_2();break;case 0xed://01101QJ(16);//delay(4000);ZG_2();break;case 0xe5://00101QJ(16);//delay(4000);ZG_2();break;case 0xe0:zd1();break;//00000case 0xff:hy();break;//11111default:QJ(8); break;}}}else{switch(P2){case 0xfb:QJ(8);break;//11011 case 0xf1:QJ(8);break;//10001case 0xf3:QJ(8);break;//10011 case 0xf7:ZG();break;//10111 case 0xe7:ZG_1();break;//00111 case 0xef:ZG_1();break;//01111 case 0xe3:ZG_1();break; //00011 case 0xe1:ZG_1();break; //00001case 0xf9:QJ(8);break;//11001 case 0xfd:YG();break;//11101 case 0xfc:YG_1();break;//11100 case 0xfe:YG_1();break;//11110 case 0xf8:YG_1();break; //11000 case 0xf0:YG_1();break;//10000case 0xfa://11010QJ(16);// delay(4000);YG_2();//f7 break;case 0xf2://10010QJ(16);// delay(4000);YG_2();break;case 0xf6://10110QJ(16);// delay(4000);YG_2();break;case 0xf4://10100QJ(16);// delay(4000);YG_2();break;case 0xeb://01011QJ(16);//delay(4000);ZG_2();//fd break;case 0xe9://01001QJ(16);//delay(4000);ZG_2();break;case 0xed://01101QJ(16);//delay(4000);ZG_2();break;case 0xe5://00101QJ(16);//delay(4000);ZG_2();break;case 0xe0:zd();break;//00000case 0xff:hy();break;//11111default:QJ(8); break;}}}}。

智能循迹小车程序代码

智能循迹小车程序代码

/****************************************************************************硬件连接P1_4接驱动模块ENA使能端,输入PWM信号调节速度P1_5接驱动模块ENB使能端,输入PWM信号调节速度P1_0 P1_1接IN1 IN2 当P1_0=1,P1_1=0; 时左电机正转驱动蓝色输出端OUT1 OUT2接左电机P1_0 P1_1接IN1 IN2 当P1_0=0,P1_1=1; 时左电机反转P1_2 P1_3接IN3 IN4 当P1_2=1,P1_3=0; 时右电机正转驱动蓝色输出端OUT3 OUT4接右电机P1_2 P1_3接IN3 IN4 当P1_2=0,P1_3=1; 时右电机反转P1_0接四路寻迹模块接口第一路输出信号即中控板上面标记为OUT1P1_1接四路寻迹模块接口第二路输出信号即中控板上面标记为OUT2P1_2接四路寻迹模块接口第三路输出信号即中控板上面标记为OUT3P1_3接四路寻迹模块接口第四路输出信号即中控板上面标记为OUT4八路寻迹传感器有信号(白线)为0 没有信号(黑线)为1****************************************************************************/#include<AT89x51.H>#define Right_moto_pwm P1_4 //接驱动模块ENA使能端,输入PWM信号调节速度#define Left_moto_pwm P1_5 //接驱动模块ENB使能端,输入PWM 信号调节速度#define Left_1_led P2_0 //四路寻迹模块接口第一路#define Left_2_led P2_1 //四路寻迹模块接口第二路#define Right_1_led P2_2 //四路寻迹模块接口第三路#define Right_2_led P2_3 //四路寻迹模块接口第四路#define Left_moto_go {P1_0=0,P1_1=1;} //左电机前进#define Left_moto_back {P1_0=1,P1_1=0;} //左电机后退#define Left_moto_stop {P1_0=1,P1_1=1;} //左电机停转#define Right_moto_go {P1_2=0,P1_3=1;} //右电机前转#define Right_moto_back {P1_2=1,P1_3=0;} //右电机后退#define Right_moto_stop {P1_2=1,P1_3=1;} //右电机停转#define uchar unsigned char#define uint unsigned intuchar pwm_val_left =0;uchar push_val_left =0; //左电机占空比N/10uchar pwm_val_right =0;uchar push_val_right=0; //右电机占空比N/10bit Right_moto_stp=1;bit Left_moto_stp =1;/**************************************************************** ********/void run(void)//前进函数{push_val_left =13; //PWM 调节参数1-20 1为最慢,20是最快改这个值可以改变其速度push_val_right =15; //PWM 调节参数1-20 1为最慢,20是最快改这个值可以改变其速度Left_moto_go ;//左电机前进Right_moto_go ; //右电机前进}/**************************************************************** ********/void left(void) //左转函数{push_val_left =8;push_val_right =9;Right_moto_go;//右电机继续Left_moto_stop;//左电机停走}/************************************************************************/void right(void)//右转函数{push_val_left =8;push_val_right =9;Right_moto_stop;//右电机停走Left_moto_go;//左电机继续}void Delayms(uint x){uchar i;while(x--)for(i=0;i<120;i++);}void stop(void){Right_moto_stop;//右电机停走Left_moto_stop;//左电机停走Delayms(3000);run();Delayms(100);}/*************************PWM调制电机转速********************************/void pwm_out_left_moto(void) //左电机调速,调节push_val_left的值改变电机转速,占空比{if(Left_moto_stp){if(pwm_val_left<=push_val_left)Left_moto_pwm=1;elseLeft_moto_pwm=0;if(pwm_val_left>=20)pwm_val_left=0;}elseLeft_moto_pwm=0;}void pwm_out_right_moto(void) //右电机调速,调节push_val_left的值改变电机转速,占空比{if(Right_moto_stp){if(pwm_val_right<=push_val_right)Right_moto_pwm=1;elseRight_moto_pwm=0;if(pwm_val_right>=20)pwm_val_right=0;}elseRight_moto_pwm=0;}/***************************************************/void xunji(){switch(P2&0x0f){case 0x00: // 全部没有压线,直走run(); break;case 0x01:// 右压线,左转left(); break;case 0x02: // 右压线,左转left(); break;case 0x04: // 左压线,转右right(); break;case 0x08: // 左压线,右转right();break;case 0x0f:stop();break;default:run(); break;}}/***********TIMER0中断服务子函数产生PWM信号**********/ void timer0()interrupt 1 using 2{TH0=0XF8; //2Ms定时TL0=0X30;pwm_val_left++;pwm_val_right++;pwm_out_left_moto();pwm_out_right_moto();}/***************************************************/ void main(void){TMOD=0X01;TH0= 0XF8; //2ms定时TL0= 0X30;TR0= 1;ET0= 1;EA = 1;while(1)/*无限循环*/{xunji();} }。

智能循迹小车源程序

智能循迹小车源程序

#include<reg52.h>sbit lsig=P2^4; //循迹IO口定义sbit msig=P2^5;sbit rsig=P2^6;sbit gl1=P2^0; //电机IO口定义sbit gl2=P2^1;sbit gr1=P2^2;sbit gr2=P2^3;sbit c1=P1^3; //测速IO口定义sbit c2=P1^4;sbit rs=P1^0; //lcd液晶定义sbit rw=P1^1;sbit lcde=P1^2;#define uchar unsigned char#define uint unsigned intuchar code tab1[]=" JH UNIVERSITY ";uchar code tab4[]=" WUXIN XUEYUAN ";uchar code tab5[]=" NAME: LIULI ";uchar code tab2[]=" DIANXIN ONE ";uchar code tab3[]="V=0.48 m/s ";uchar t=0,a,i,f1,f2,num1=100,num2=100,m,n=0; uint vc[10]={54,50,53,51,57,53,55,51,50,54}; static uint b=0;static int p,q=0;uint temp1=0,temp2=0,v1,v2,v;void delay2(uint xms) //延时{uint i,j;for(i=xms;i>0;i--)for(j=110;j>0;j--);}void delay(void) //误差 -0.000000000001us {unsigned char a,b;for(b=15;b>0;b--)for(a=152;a>0;a--);}/**1602显示**/void write_com(uchar com) //写指令{rw=0;rs=0;P0=com;delay2(1);lcde=1;lcde=0;}void write_date(uchar date) //写数据{rs=1;rw=0;P0=date;delay2(1);lcde=1;lcde=0;}void init_lcd(){write_com(0x06);delay();write_com(0x0c);delay();write_com(0x38);delay();write_com(0x01);delay();write_com(0x80);i=0;while(tab1[i]!='\0'){write_date(tab1[i++]);delay2(150);}delay2(200);write_com(0x80);i=0;while(tab4[i]!='\0'){write_date(tab4[i++]);delay2(150);}delay2(200);write_com(0x80);i=0;while(tab2[i]!='\0'){write_date(tab2[i++]);delay2(150);}delay2(200);write_com(0x80);i=0;while(tab5[i]!='\0'){write_date(tab5[i++]);delay2(150);}write_com(0xc0);i=0;while(tab3[i]!='\0'){write_date(tab3[i++]);delay();}while(1);}void pwm(uchar num1,uchar num2){if(t>=100)t=0;if(t<num1){gl1=1;gl2=0;}else{gl1=0;gl2=0;}if(t<num2){gr1=1;gr2=0;}else{gr1=0;gr2=0;}}/********高效延时********/void delay3(){uint j;for(j=7500;j>0;j--){if((rsig==0)&&(lsig==0)&&(msig==1)){p=1;pwm(80,80);}else if((rsig==0)&&(lsig==1)&&(msig==0)){p=2;pwm(30,80);}else if((rsig==0)&&(lsig==1)&&(msig==1)){p=3;pwm(40,60);}else if((rsig==1)&&(lsig==0)&&(msig==0)){p=4;pwm(80,30);}else if((rsig==1)&&(lsig==0)&&(msig==1)){p=5;pwm(60,40);}else if ((rsig==0)&&(lsig==0)&&(msig==0)){if((p==2)||(p==3))pwm(30,80);else if ((p==4)||(p==5))pwm(80,30);//else pwm(80,80);}}}/************************计算小车转速**********************************/ /*ceshu(void ){if(c1==1) f1=1;else if(c1==0&&f1==1){f1=0;temp1++;}if(c2==1) f2=1;else if(c2==0&&f2==1){f2=0;temp2++;}if(m==20) //每秒脉冲数{v1=temp1*4;// 每次脉冲走4cmv2=temp2*4;if(v1>999)v1=0;if(v2>999)v2=0;m=0;temp1=0;temp2=0;}v=(v1+v2)/2;return v;}*/void display1(void) //LCD显示数据 1{write_com(0xc0+5);write_date('0'+vc[b]%10);delay();write_com(0xc0+4);write_date('0'+vc[b]/10%10);delay();write_com(0xc0+2);write_date('0'+vc[b]/100);delay();}void init (){TMOD=0x11;IE=0x8b;IT0=1;EX0=1;TH0 = 0xfe;TL0 = 0x33;TH1=0x4c;TL1=0xd0;gl1=1;gl2=1;gr1=1;gr2=1;}main(){t=0;init();TR0=1; //定时器0打开TR1=1; //定时器1打开while(1){if((rsig==0)&&(lsig==0)&&(msig==1)){p=1;pwm(80,80);}else if((rsig==0)&&(lsig==1)&&(msig==0)){p=2;pwm(30,80);}else if((rsig==0)&&(lsig==1)&&(msig==1)){p=3;pwm(40,60);}else if((rsig==1)&&(lsig==0)&&(msig==0)){p=4;pwm(80,30);}else if((rsig==1)&&(lsig==0)&&(msig==1)){p=5;pwm(60,40);}else if((rsig==1)&&(lsig==1)&&(msig==1)){delay2(100);q++;if(q==4){while(n+1){delay3();vc[n]=v;n++;if(n==10) break;}}if(q==5){pwm(0,0);delay2(5000);init_lcd();}}else if ((rsig==0)&&(lsig==0)&&(msig==0)){if((p==2)||(p==3))pwm(30,80);else if ((p==4)||(p==5))pwm(80,30);//else pwm(80,80);}}}void interrupt0() interrupt 0{display1();b++;if(b==9)b=0;delay2(20);}void timer() interrupt 1 //定时器0{TH0 = 0xfe;TL0 = 0x33;t++;}void T1_time()interrupt 3 //定时器1 {TH1=0x4c;TL1=0xd0;m++;if(c1==1) f1=1;else if(c1==0&&f1==1){f1=0;temp1++;}if(c2==1) f2=1;else if(c2==0&&f2==1){f2=0;temp2++;}if(m==20) //每秒脉冲数{v1=temp1*4;// 每次脉冲走4cmv2=temp2*4;if(v1>999)v1=0;if(v2>999)v2=0;m=0;temp1=0;temp2=0;}v=(v1+v2)/2+35;}。

arduino智能循迹小车代码(三个循迹模块)

arduino智能循迹小车代码(三个循迹模块)

arduino智能循迹⼩车代码(三个循迹模块)#include <Servo.h>int leftMotor1 = 3;int leftMotor2 = 5;int rightMotor1 = 6;int rightMotor2 = 11;int sum=0;void setup() {Serial.begin(9600);pinMode(leftMotor1, OUTPUT);pinMode(leftMotor2, OUTPUT);pinMode(rightMotor1, OUTPUT);pinMode(rightMotor2, OUTPUT);pinMode(A0, INPUT);pinMode(A1, INPUT);pinMode(A2, INPUT);}void loop() {tracing();}void tracing(){int data[4];data[0]=analogRead(A0);data[1]=analogRead(A1);data[2]=analogRead(A2);if(data[0]<210&&data[1]>500&&data[2]<210)//向前⾛{analogWrite(3,100);analogWrite(5,0);analogWrite(6,100);analogWrite(11,0);}if(data[0]>500 &&data[1]<210 && data[2]<210) // ⼩车偏左{analogWrite(3,0);analogWrite(5,0);analogWrite(6,120);analogWrite(11,0);}if(data[0]>500&&data[1]>500&&data[2]<210) //⼩车偏⼤左{analogWrite(3,0);analogWrite(5,120);analogWrite(6,120);analogWrite(11,0);}if(data[0]<210&&(data[1]-30)<210&&data[2]>500) //⼩车偏右{analogWrite(3,120);analogWrite(5,0);analogWrite(6,0);analogWrite(11,0);}if(data[0]<210&&data[1]>500&&data[2]>500) //⼩车偏⼤右{analogWrite(3,120);analogWrite(5,0);analogWrite(6,0);analogWrite(11,120);}if(data[0]>500&&data[1]>500&&data[2]>500) //左右都检测到⿊线是停⽌{analogWrite(3,0);analogWrite(5,0);analogWrite(6,0); analogWrite(11,0);}Serial.print(data[0]); Serial.print("---"); Serial.print(data[1]-30); Serial.print("---"); Serial.print(data[2]); Serial.print("---"); Serial.println(data[3]); }。

智能寻迹小车调试程序

智能寻迹小车调试程序
hyou1 = 1;
hyou2 = 0;
}
void TurnRight()//右转
{Leabharlann qzuo1 = 1;qzuo2 = 0;
hzuo1 = 1;
hzuo2 = 0;
qyou1 = 0;
qyou2 = 0;
hyou1 = 0;
hyou2 = 0;
}
void Xiaoying()
{
qzuo1=qzuo2=qyou1=qyou2=hzuo1=hzuo2=hyou1=hyou2=0 ;
if(LED1==1&&LED2==1&&LED3==0&&LED4==0&&LED5==1)//直行超出范围后速度变化不明显
{ RUN(); delay(30) ;Xiaoying() ;}
if(LED1==1&&LED2==0&&LED3==0&&LED4==1&&LED5==1)//直行
{ RUN(); delay(30) ;Xiaoying() ;}
void delay(int i)
{
while(i--);
}
void RUN()//向前
{
qzuo1 = 1;
qzuo2 = 0;
hzuo1 = 1;
hzuo2 = 0;
qyou1 = 1;
qyou2 = 0;
hyou1 = 1;
hyou2 = 0;
}
void STOP()//停车
{
qzuo1 = 0;
voiddelayintvoidrun向前voidstop停车voidturnleft左转voidturnright右转voidxiaoyingvoidmainvoidifled11led21led30led41led51直行delay值越小速度越小范围在10120为最佳控制范围run

循迹小车完整程序

循迹小车完整程序

程序# include <reg51.h>//********驱动芯片L298管脚位声明*****sbit IN1= P1^0;sbit PWM1= P1^1;sbit IN2= P1^2;sbit IN3= P1^3;sbit PWM2= P1^4;sbit IN4= P1^5;//********传感器TCRT5000管脚位声明****sbit XL= P1^6; //左侧第一个传感器sbit XR= P1^7; //右侧第一个传感器sbit YL= P2^0; //左侧第二个传感器sbit YR= P2^1; //右侧第二个传感器//********用于定时计数的两个全局变量位声明****** int count1=0;int count2=0;//********左边电机前进*******void forward_turn1(){IN1=0;IN2=0;}//*********左边电机后退******void reverse_tuen1(){IN1=1;IN2=0;}//*********右边电机前进*******void forward_turn2(){IN3=0;IN4=1;}//**********右边电机后退********void reverse_turn2(){IN3=1;IN4=0;}//***********左边电机速度控制函数******void speed1(int ct,int sd){if(ct<=sd)PWM1=1;elsePWM1=0;}//************右边电机速度控制函数******viod speed2(int ct,int sd){if (ct<=sd)PWM2=1;elsePWM2=0;//*************小车直线前进函数*********void advance (int ct1,int sd1,int ct2,int sd2); {forward_turn1();forward_turn2();speed1(ct1,sd1);speed2(ct2,sd2);}//**********小车左转********void left_turn1(int ct1,int sd1,int ct2,int sd2); {forward_turn1();forward_turn2();speed1(ct1,sd1);speed2(ct2,sd2);}//************小车右转*********viod riht_ turn1(int ct1,int sd1,int ct2,int sd2); {forward_turn1();forward_turn2();speed1(ct1,sd1);speed2(ct2,sd2);}//**************主函数**********main(){TMOD=ox11;TH0=(65536-1000)/256;TL0=(65536-1000)%256;EA=1;ET0=1;TR0=1;TH1=(65536-1000)/256;TL1=(65536-1000)%256;EA=1;ET1=1;TR1=1;while(1){if(XL==0&&XR==0&&YL==0&&YR==0) //传感器未检测到直线,小车直行{advance(count1,500,count2,500);}if(XL==1&&XR==0&&YL==0&&YR==0) //左边内侧传感器检测到黑线,小左转 {Left_turn1(count1,200,count2,500);}if(XL==0&&XR==0&&YL==1&&YR==0) //左边外侧传感器检测到黑线,大左转{Left_turn1(count1,200,count2,700);}if(XL==0&&XR==1&&YL==0&&YR==0) //右边内侧传感器检测到黑线,小右转{right_turn1(count1,500,count2,200);}if(XL==0&&XR==0&&YL==0&&YR=1) //右边外侧传感器检测到黑线,大右转{right_turn1(count1,700,count2,200);}if(XL==1&&XR==0&&YL==1&&YR=0) //左侧两个传感器均检测到黑线,中左转{Left_turn1(count1,200,count2,600);}if(XL==0&&XR==1&&YL==0&&YR=1) //右侧两个传感器均检测到黑线,中右转{right_turn1(count1,600,count2,200);}}}//******中断服务程序*******viod time0() interrupt1;{TH0=(65536-1000)/256;TL0=(65536-1000)%256;count1++;if (count1>=1000)count1=0}viod time1() interrupt1;{TH0=(65536-1000)/256;TL0=(65536-1000)%256;count2++;if (count2>=1000)count2=0}。

PWM调速循迹智能小车程序

PWM调速循迹智能小车程序

{ if(index==1) /*{m1=abs(speed); /*s1=1; s2=0;} if(index==2) /* {m2=abs(speed); /*s3=1;s4=0;}}}电机 1 的处理 */取速度的绝对值 */电机 2 的处理 */电机 2 的速度控制 */的上拉/*晶振采用12M,产生的PWM 勺频率约为100Hz */#include<reg51.h> #include<math.h> #define uchar unsigned char#define uint unsigned int sbit en 1=P3A 4; /* L298 sbit en 2=卩3人5; /* L298 sbit s1=P1A0; /* L298 sbit s2=P1A1; /* L298 sbit s3=P1A3; /* L298 sbit s4=P1A2; /* L298 sbit R=P2A0; sbit C=P2A1; sbit L=P2A2; sbitkey=P1A4; uchar t=0; /* uchar m1=0; /* uchar m2=0; /* 的 Enable A*/ 的 Enable B*/ 的 Input 1*/ 的 Input 2*/ 的 Input 3*/ 的 Input 4*/uchar tmp1,tmp2; /* 中断计数器 */电机 1 速度值 */电机 2 速度值 */ 电机当前速度值 *//* 电机控制函数 index- 电机号(1,2); speed- 电机速度 (0-100) */void motor(uchar index, char speed){if(speed<=100)void Back(void){s1=0;s2=1;s3=1;s4=0;}void GO(void){s1=1;s2=0;s3=1;s4=0;}void TL(void){s1=1;s2=0;s3=0;s4=1;}void TR(void){s1=0;s2=1;s3=1;s4=0;}void STOP(void){s1=1;s2=1;s3=1;s4=1;}/*void delay(uint j) /*简易延时函数*/ { for(j;j>0;j--);} */void delay(uint z){uint x,y;for(x=z;x>0;x--) for(y=110;y>0;y--);}void main(){uchar i=0,j=0;TMOD=0x02;/*设定TO的工作模式为2 ,8位自动重置定时器,每过几个机器周期,计数器加一*/THO=Ox9B; /* 装入定时器的初值,计数1OO 次溢出*/TLO=Ox9B; /* 装入时间常数*/EA=1; /* 开中断*/ETO=1; /* 定时器O 允许中断*/TRO=1; /* 启动定时器O */while(1){if(key==1){/* 电机实际控制演示*/if(i<=1OO) // 正转加速{motor(1,i);motor(2,i);delay(5OOO);i++;}else{GO();}}else{EA=O;while(1){if((L|C|R)==O)STOP();if(L&R)GO();if(L==0){while(C){TL();}}if(R==0){while(C){TR();}}}}}} void timer0() interrupt 1 /* T0 中断服务程序*/{if(t==O) /* 1 个PWM周期完成后才会接受新数值*/{ tmp1=m1;tmp2=m2;}if(t<tmp1) en仁1; else en仁0; /* 产生电机 1 的PWM信号*/ if(t<tmp2) en2=1; else en2=0; /* 产生电机 2 的PWM信号*/ t++;if(t>=100) t=0; /* 1 个PWM信号由100 次中断产生*/}#in clude< intrin s.h>#i nclude<AT89X52.h>******************************************************************************宏定义区/* -------------------- LCD 模块 -------------------------------------- */#defineLCD_RW P2_6 // 读写控制端#defi neLCD_RS P2_7 //数据命令选择端#defi neLCD_E P2_5 // 执行使能端#defineLCD DataP1 〃P1 口#defi neWrite 0x00 //#defi neRead 0x01 //#defi neData 0x01 //#defi neCmd 0x00 //#defineDisable 0x01 #defi neTrue 0x01 #defi neFalse 0x00#defi neLCD_I nit 0x38 // 初始化模式#defi neLCD_DispCtr 0x0C //开显示及光标设置 #defi neLCD_CloseCtr 0x08 // 关显示#defi neLCD_CLS 0x01 // 清屏幕#defi neLCD_E nterSet 0x06 //显示光标 #defi neBusy P1_7 // 忙信号 /*-----------------测 速 / 测距 / 测 时 模 --------------------- */ #defin eCircleLe ngth 0.132 //小车转 「轮的长度为 .132m /* --------------------- 控速 模----------------------- */#defi neP03 P0_3 // 后电机#defi neP04 P0_4 // 后电机#defi neP01 P0_1 // 前电机#defi neP02 P0_2 // 前电机#defi neP31 P0 5 // 控制液晶背光#defi neP33 P3_3 /** 低电平写入高电平读出高电平选择数据低电平选择命令#defi neEn able 0x00 // 跃变到低电平时执行命令**//* ------------------- 菜单选择模 --------------------- */#defi neLi ne 0x00 〃0 代表直线模式#defineCurve 0x01 〃1 代表S 型模式***//* LCD*/voidLCDI nit(void); //LCD voidSetWriteCmd(void); // voidSetReadCmd(void); // voidSetWriteData(void); // voidWriteCmd(charcmd); // voidWriteData(charddata); // voidExecuteCmd(void); // voidSetXY(charx,chary); // 初始化设置写命令模式设置读命令模式设置写数据模式写命令写数据执行命令定位显示地址 显示单个字符显示一段字符串voidDisplayS in gleChar(charx,chary,charcchar); // voidDisplayStri ng(charx,chary,char*str); // voidDelay(u nsig nedi nttime); // 延时主程序 voidDelayUs(u nsig nedi nttime); // 延时子程序bit IsBusy(void); // 判断忙标志函数 voidDisplayTime(void); // 显示时间voidDisplayAVGSpeed(void); // 显示平均速度voidDisplayDista nce(void); // 显示路程测 速 / 测 距 / 测 时 模 块/**/voidINTI ni t(void); // 所有中断初始化voidSpeedlNT(void); // voidComputeTime(void); voidComputeSpeedANDDista nce(void); // 计算速度和距离测速中断 ------------------------ */voidCtrSpeedlNT(void);// 控速中断voidTime0INT(void);voidTime1INT(void); // 控速单位时间中断voidClock0 ln it(void);// 时钟中断初始化voidClock1」n it(void); //时钟中断初始化/********************************************************************************\**全局变量区#defi neNormal 0x00 〃0 代表正常速度#defi neLow 0x01 〃1 代表低速#defi neHigh 0x02 〃2 代表咼速嗫*****************************************************************************全局函数声明区**/voidCtrSpeed(void);'****************************************************************************float SpeedCount=0; //测速计数脉冲float Speed=0.0;float Distance=0.0; char Time1INTCount=0; //T1 中断时间计时 float PassTime=0.00; // 小车行走的时间 short IsT0INT=1;bit IsT1INT; // 判断 T1 是否已经响应中断short IsT0INT2=1;char Thx[5]={0xf4,0xf4,0xc5,0xf4,0xff}; //3ms,3ms,15ms,3ms charTlx[5]={0x48,0x48,0x68,0x48,0xff};char Thx0=0xd8;char Tlx0=0xf0;char Thx1=0xb1; //20mschar Tlx1=0xe0;short Round=0;short Back=0;short Back0=0;bit Backid;bit Stop=0;char Area0=0;char Area1=0; // 区域变量char LowSpeedArea1StartTime; char LowSpeedArea1EndTime;char HighSpeedAreaEndTime;char LowSpeedArea2EndTime;char LowSpeedArea1PassTime=0; // char HighSpeedAreaPassTime=0; // char LowSpeedArea2PassTime=0; // char ReadyToGo=4; // 倒计时char flag;bit Roundid=0;char Nocurve=0;char ChangeFlag;char Mode;bit Running;bit SelectedAll; // 模式和速度是否选择完毕标志bit IsSelectingMode; // 模式选择标志bit IsSelectingSpeed; // 速度选择标志bit ModeSelected; // 已经被选择的模式标志 char SelectedMode=10; //模式选择是否完毕标志 bitNext; //Next 键标志bit SpeedSelected; // 已经被选中的速度方案标志第一个低速区通过时间高速区通过时间 第二个低速区通过时间char SelectedSpeed; //bit ChoosingDisplay;// bit SelectedShow; // 速度选择是否完毕标志 人工选择菜单开始标志 显示选择标志bit Selected; // 确定 / 返回键选择标志bit AVGSpeedShow; // 平均速度显示标志bit TotalDistanceShow; // 总路程显示标志 bit ReturnMain; // 返回主菜单标志bit AutoDisplay; // 自动显示标志bit GoToChoosingDisplay; // 人工选择标志bit AutoMode=0;char PassLineID=0;char PassLine=0;float PrepareDistance;float FirstDistance;float SecondDistance;float ThirdDistance;int FirstHigh;int SecondHigh;int ThirdHigh;float Rate=1.25; //5ms 时的速度float Count=4; // 时间的倍数****************************************************************************voidmain(){P01=0;P02=0;P03=0;P04=0;P31=1; // 单片机复位,背光开Delay(40); // 延时等待LCD 启动LCDInit(); // 初始化 LCDDisplayString(0x0,0," Starting... ");DisplayString(0x0,1,"DesignedBy202");Delay(300);WriteCmd(LCD_CLS);EA=1; // 开总中断EX0=1; // 开 INT0 中断IT0=1; //INTO 边沿触发EX1=1; // 开 INT1 中断IT1=1; //INT1 边沿触发SelectedAll=False; // 开始模式和速度选择 bit SelectedReturn; // 返回选择标志bit ReturnSelection; // 返回键启用标志/* --------------------- 主函数------------------------ */ ****/* ------------------- 模式选择 ----------------------------------- */ DisplayString(0x0,0,"ChooseTheMode");DisplayString(0x0,1,"youwant. ");Delay(50);WriteCmd(LCD_CLS); IsSelectingMode=True;while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0," LineMode ");DisplayString(0x0,1,"Next Yes");Delay(300); // 延时消除抖动while(1) // 不断检测中断,直到按确定键或是NEXT键{ if(Next==True) // 如果按Next 键则直接跳出break;if(ModeSelected==True) // 如果按确定键则设置模式为Line 并跳出{SelectedMode=Line;break;} // 如果什么键都没有按下,那么一直显示等待} if(ModeSelected==True) // 按下了确定键,退出模式选择{IsSelectingMode=False; break;}if(Next==True) // 按下了Next 键,显示下一个菜单项{Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," CurveMode "); DisplayString(0x0,1,"Next Yes");Delay(300); // 延时消除抖动while(1) // 不断检测中断,直到按确定键或是Next 键{if(Next==True) // 如果再一次按下Next 键,则跳出break;if(ModeSelected==True) // 如果按下确定键,则设置模式为Curve ,并跳出{SelectedMode=Curve;break;}}}if(ModeSelected==True) // 按下了确定键,退出模式选择{IsSelectingMode=False;break;}if(Next==True) // 再一次按下了Next 键,则循环模式选择{WriteCmd(LCD_CLS);DisplayString(0x0,0," AutoMode "); DisplayString(0x0,1,"Next Yes");Delay(300); // 延时消除抖动while(1){ if(Next==True) break;if(ModeSelected==True){AutoMode=1; break;}}} if(ModeSelected==True){IsSelectingMode=False; break;} if(Next==True){Next=False; continue;}}Delay(50);WriteCmd(LCD_CLS);/* ------------------- 速度选择 ----------------------------------- */ if(SelectedMode==Line&&AutoMode==0){DisplayString(0x0,0," NowChoosea ");DisplayString(0x0,1," kindofSpeed"); Delay(50);WriteCmd(LCD_CLS); IsSelectingSpeed=True;while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0,"NormalSpeed "); DisplayString(0x0,1,"Next Yes"); Delay(300); // 延时消除抖动while(1){ if(Next==True) // 如果按Next 键则直接跳出break;if(SpeedSelected==True) // 如果按确定键则设置速度为Normal 并跳出{Thx[0]=0xec;Tlx[0]=0x78; //5msThx[1]=0xf0;Tlx[1]=0x60; //4msThx[2]=0x8a;Tlx[2]=0xd0; //30ms Thx[3]=0xf4;Tlx[3]=0x48; //3ms SelectedSpeed=Normal; break;} // 如果什么键都没有按下,那么一直显示等待} if(SpeedSelected==True) // 按下了确定键,退出速度选择{IsSelectingSpeed=False; break;}if(Next==True){WriteCmd(LCD_CLS); DisplayString(0x0,0," Low Speed "); DisplayString(0x0,1,"Next Yes");Delay(300); // 延时消除抖动while(1){if(Next==True) // 如果再一次按下Next 键,则跳出break;if(SpeedSelected==True) // 如果按下确定键,则设置速度为Low,并跳出{SelectedSpeed=Low; // 这里没有速度设置,因为默认速度就是Low break;}}}if(SpeedSelected==True) // 按下了确定键,退出速度选择{ IsSelectingSpeed=False; break;} if(Next==True){ Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," High Speed ");DisplayString(0x0,1,"Next Yes");Delay(300); // 延时消除抖动while(1){if(Next==True) // 如果再一次按下Next 键,则跳出break;if(SpeedSelected==True) // 如果按下确定键,则设置速度为并跳出High,{Thx[0]=0xe0;Tlx[0]=0xc0;//8ms Thx[1]=0xe0;Tlx[1]=0xc0; //8msThx[2]=0x63;Tlx[2]=0xc0; //40ms Thx[3]=0xec;Tlx[3]=0x78; //5ms SelectedSpeed=High; break;}}}if(SpeedSelected==True) // 按下了确定键,退出速度选择{ IsSelectingSpeed=False;break;}if(Next==True) // 再一次按下了Next 键,则循环速度选择{Next=False;continue;}}}SelectedAll=True; // 标志模式选择和速度选择完毕Running=True;Delay(50);WriteCmd(LCD_CLS);/* ---------------- 显示所选择的模式和速度方案----------------- */ if(SelectedMode==Line){ DisplayString(0x0,0,"ChoosenModeis");DisplayString(0x0,1," Line ");Delay(50); WriteCmd(LCD_CLS);}if(SelectedMode==Curve){DisplayString(0x0,0,"ChoosenModeis"); DisplayString(0x0,1," Curve "); Delay(50);WriteCmd(LCD_CLS);}if(AutoMode==1){DisplayString(0x0,0,"ChoosenModeis"); DisplayString(0x0,1," AutoMode "); Delay(50);WriteCmd(LCD_CLS);} if(SelectedMode==Line){if(SelectedSpeed==Normal){ DisplayString(0x0,0,"ChoosenSpeedis");DisplayString(0x0,1," Normal ");Delay(50);WriteCmd(LCD_CLS);}if(SelectedSpeed==Low){DisplayString(0x0,0,"ChoosenSpeedis");DisplayString(0x0,1," Low ");Delay(50);WriteCmd(LCD_CLS);}if(SelectedSpeed==High){DisplayString(0x0,0,"ChoosenSpeedis");DisplayString(0x0,1," High ");Delay(50);WriteCmd(LCD_CLS);}}INTInit(); // 初始化所有中断DisplayString(0x0,0,"LeftTimesToGo"); while(ReadyToGo--){DisplaySingleChar(0x7,1,ReadyToGo+0x30);DisplaySingleChar(0x09,1,'s');Delay(300);}WriteCmd(LCD_CLS);DisplayString(0x05,0,"Go!!!");Delay(100);WriteCmd(LCD_CLS);DisplayString(0x0,0," Living... ");DisplayString(0x0,1,"Designedby202"); if(SelectedMode==Line&&AutoMode==0) flag=Area0; elseflag=1;while(flag<5){if(AutoMode==1) // 自动模式{switch(PassLineID){case0 :{if(IsT0INT==1){P01=P02=P04=0;P03=1;}else{P01=P02=P03=P04=0;}}break;case1 :{P01=P02=P03=0;P04=1;}break;case2 :{P01=P02=P04=0;P03=1;}break; default:break;}}else{if(SelectedMode==Line) // 直线模式{flag=Area0;if(IsT0INT==1) {P03=1;P04=0;P01=P02=0;}else{P03=0;P04=0;P01=P02=0;}}else{ //S 型模式if((Nocurve<2)&&Round!=0&&(Back0>0)&&Back!=0) {if(Backid==1){P01=1;P02=0;P03=0;P04=1;}else{P01=0;P02=1;P03=0;P04=1;}Back=1;}else{if(Round==0){ if(IsT0INT2==1){P01=0;P02=0;P03=1;P04=0;}else{P01=0;P02=0;P03=0;P04=0;}}else{if(P33==0){if(IsT0INT2==1){P01=0;P02=0;P03=1;P04=0;} else{P01=0;P02=0;P03=0;P04=0;}}else{EX1=1; if(Round%2){if(IsT0INT2==1){P01=1;P02=0;P03=1;P04=0;Backid=1;} else{P01=1;P02=0;P03=0;P04=0;}}else{if(IsT0INT2==1){P01=0;P02=1;P03=1;P04=0;Backid=0;}else{P01=0;P02=1;P03=0;P04=0;}}}}}}}if(IsT1INT==1){IsT1INT=0;ComputeTime();ComputeSpeedANDDistance();}}// 补中断路程,加上最后一次中断缺失的路程ComputeSpeedANDDistance(); P04=1;P03=0;P01=P02=0;Delay(90);P03=0;P04=0; // 行程结束,小车停止P31=1; // 行程结束,背光开ET0=0x0; // 关T0 中断ET1=0x0; // 关T1 中断EX1=0x01; // 开INT1 中断Running=False;AutoDisplay=True; // 默认情况下直线模式会自动显示各个区域经过的时间WriteCmd(LCD_CLS);if(SelectedMode==Line) // 直线模式才显示{while(1){ if(GoToChoosingDisplay==True) break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,"LowSpeedArea1");DisplayString(0,1,"Costed");DisplaySingleChar(0x0C,1,'s');LowSpeedArea1PassTime=LowSpeedArea1EndTime-LowSpeedArea1StartTime;DisplaySingleChar(0x0A,1,LowSpeedArea1PassTime%10+0x30);if(LowSpeedArea1PassTime>9) // 通过第一个低速区的时间超过sDisplaySingleChar(0x0B,1,LowSpeedArea1PassTime/10+0x30); if(GoToChoosingDisplay==True) break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,"HighSpeedArea");DisplayString(0,1,"Costed");DisplaySingleChar(0x0C,1,'s');HighSpeedAreaPassTime=HighSpeedAreaEndTime-LowSpeedArea1EndTime;DisplaySingleChar(0x0A,1,HighSpeedAreaPassTime%10+0x30);if(HighSpeedAreaPassTime>9) // 通过高速区的时间超过sDisplaySingleChar(0x0B,1,HighSpeedAreaPassTime/10+0x30); if(GoToChoosingDisplay==True) break;Delay(200);WriteCmd(LCD_CLS);Delay(200);DisplayString(0,0,"LowSpeedArea2");DisplayString(0,1,"Costed");DisplaySingleChar(0x0C,1,'s');LowSpeedArea2PassTime=LowSpeedArea2EndTime-HighSpeedAreaEndTime;DisplaySingleChar(0x0A,1,LowSpeedArea2PassTime%10+0x30);if(LowSpeedArea2PassTime>9) // 通过第二个低速区的时间超过sDisplaySingleChar(0x0B,1,LowSpeedArea2PassTime/10+0x30);}}AutoDisplay=False;/* ---------- 菜单选择你想要看的内容-- 总时间、总路程以及平均速度--------- */ChoosingDisplay=True; WriteCmd(LCD_CLS);/* 首先显示主菜单,然后显示第一个选项*/ DisplayString(0x0,0,"NowChoosewhat"); DisplayString(0x0,1,"youwanttosee"); Delay(100);while(1){WriteCmd(LCD_CLS);DisplayString(0x0,0," CostedTime ");DisplayString(0x0,1,"Next Show"); Delay(250); // 延时消除抖动/*-------------------------- */ /* 不断检测确定键和Next 键*/ while(1){第一次按键if(Next==True) break;if(SelectedShow==True)break;}/* 按下了确定键,显示第一个选项的内容*/ if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;WriteCmd(LCD_CLS);DisplayString(0,0,"CostedTimeis");DisplayTime();DisplayString(0x0A,1,"s");ReturnSelection=True; // 按下了确定键,那么这个时候开启返回键的功能AVGSpeedShow=False;Delay(250); // 延时消除抖动}/** 按下了Next 键,则显示第二个选项*/if(Next==True)// 按下Next 键,显示AVGSpeec菜单项{Next=False;WriteCmd(LCD_CLS);DisplayString(0x0,0," AVGSpeed ");DisplayString(0x0,1,"Next Show");ReturnMain=False;ReturnSelection=False; // 按下了Next 键,那么这个时候关闭返回键的功能AVGSpeedShow=True; // 表明AVGSpeec选项已经显示过了Delay(250); // 延时消除抖动}/* ------------------------ 第二次按-------------------------- *//* 显示第一个选项的内容后又不断检测返回键(确定键)和Next 键*/while(1){if(Next==True)break;if(Selected==True)break;}if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False; // 按下了Next 键,那么这个时候关闭返回键的功能if(AVGSpeedShow==False)// 还没有显示AVGSpeec选项,显示它{ // 即第一次选择了确定键WriteCmd(LCD_CLS);DisplayString(0x0,0," AVGSpeed ");DisplayString(0x0,1,"Next Show");TotalDistanceShow=False; // 显示了AVGSpeed 则表明TotalDistanee 还没有显示Delay(250); // 延时消除抖动}if(AVGSpeedShow==True) // 已经显示过AVGSpeed选项了,则显示下一个选项{ // 即第一次选择了Next 键WriteCmd(LCD_CLS);DisplayString(0x0,0,"TotalDistance");DisplayString(0x0,1,"Next Show");TotalDistanceShow=True; // 表明显示了TotalDistance选项Delay(250); // 延时消除抖动}} if(Selected==True) // 按下了确定键或返回键{SelectedShow=False;SelectedReturn=False;Selected=False;if(ReturnSelection==True) // 第一次选择了确定键,故这次按下的是返回键ReturnMain=True; if(ReturnSelection==False) { WriteCmd(LCD_CLS);DisplayString(0,0,"TheAVGSpeedis"); DisplayAVGSpeed(); DisplayString(0x0A,1,"m/s"); ReturnSelection=True; // 按下了确定键,那么这个时候开启返回键的功能Delay(250); // 延时消除抖动}TotalDistanceShow=False;} if(ReturnMain==True) // 按下了返回键,返回主菜单{ReturnMain=False;continue;}/* ------------------------第三次按键-------------------------- */ /* 如果没有返回主菜单,则继续检测Next 键和确定键*/ while(1){if(Next==True) break;if(SelectedShow==True)break;}/* 按下Next 键,显示下一个选项*/ if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False; // 按下了Next 键,那么这个时候关闭返回键的功能if(TotalDistanceShow==True)ReturnMain=True;if(TotalDistanceShow==False) // 还没有显示TotalDistance 选项,显示它{WriteCmd(LCD_CLS); DisplayString(0x0,0,"TotalDistance");DisplayString(0x0,1,"Next Show"); TotalDistanceShow=True;Delay(250); // 延时消除抖动}} if(Selected==True) // 按下了确定键或返回键{SelectedShow=False;SelectedReturn=False;Selected=False; if(ReturnSelection==True) // 按下的是返回键ReturnMain=True; if(ReturnSelection==False){if(TotalDistanceShow==False)// 表明AVGSpeec选项的内容还没有显示{WriteCmd(LCD_CLS);DisplayString(0,0,"TheAVGSpeedis");DisplayAVGSpeed();DisplayString(0x0A,1,"m/s");ReturnSelection=True;Delay(250); // 延时消除抖动}if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,"TotalDistance");DisplayDistance();DisplayString(0x0A,1,"m");ReturnSelection=True; // 按下了确定键,那么这个时候开启返回键的功能Delay(250); // 延时消除抖动}}}if(ReturnMain==True) // 按下了返回键,返回主菜单{ReturnMain=False;continue;}/* ------------------------ 第四次按键-------------------------- */while(1){ if(Next==True) break;if(SelectedShow==True)break;}if(Next==True) // 所有菜单项已经显示完毕,返回主菜单{Next=False;ReturnMain=False;ReturnSelection=False; if(TotalDistanceShow==False) {WriteCmd(LCD_CLS); DisplayString(0x0,0,"TotalDistance"); DisplayString(0x0,1,"Next Show"); TotalDistanceShow=True;Delay(250); // 延时消除抖动}} if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False; if(ReturnSelection==True) // 按下的是返回键ReturnMain=True;if(ReturnSelection==False){ if(TotalDistanceShow==True) {WriteCmd(LCD_CLS); DisplayString(0,0,"TotalDistance");DisplayDistance();DisplayString(0x0A,1,"m");ReturnSelection=True;// 按下了确定键,那么这个时候开启返回键的功台匕能Delay(250); // 延时消除抖动}}}if(ReturnMain==True) // 按下了返回键,返回主菜单{ReturnMain=False;continue;}/* ------------------------ 第五次按键-------------------------- */while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True) // 所有菜单项已经显示完毕,返回、•t t - l、/,主菜单{Next=False;ReturnMain=False;ReturnSelection=False;if(TotalDistanceShow==True) // 最后一个选项已经显示完毕,返回、•t t - l、/,主菜单{ReturnMain=True;}} if(SelectedShow==True){ SelectedShow=False;SelectedReturn=False;Selected=False; if(ReturnSelection==True) // 按下的是返回键ReturnMain=True; if(ReturnSelection==False){ if(TotalDistanceShow==True){WriteCmd(LCD_CLS);DisplayString(0,0,"TotalDistance");DisplayDistance();DisplayString(0x0A,1,"m");ReturnSelection=True; // 按下了确定键,那么这个时候开启返回键的功能Delay(250); // 延时消除抖动}}}/* ------------------------ 第六次按键-------------------------- */while(1){if(Next==True)break;if(SelectedShow==True)break;}if(Next==True){Next=False;ReturnMain=False;ReturnSelection=False;}if(SelectedShow==True){SelectedShow=False;SelectedReturn=False;Selected=False;}continue;}while(1);}/****************************************************************************** **********\** LCD 驱动模块**\****************************************************************************** **********//* ---------------------- LCD 初始化函数-------------------------- */ voidLCDInit(void){// 三次显示模式设置LCD_Data=0;LCD_E=Disable;Delay(5);WriteCmd(LCD_Init);Delay(5);WriteCmd(LCD_Init);Delay(5);WriteCmd(LCD_Init);WriteCmd(LCD_Init); // 初始化WriteCmd(LCD_CloseCtr); // 关显示WriteCmd(LCD_CLS); // 清屏幕WriteCmd(LCD_EnterSet); // 光标移动设置WriteCmd(LCD_DispCtr); // 显示开以及光标设置}/* ---------------------- LCD 模式设置函数-------------------------- *\SetWriteCmd() 设置LCD为写命令模式SetReadCmd()设置LCD为读命令模式SetWriteData() 设置LCD为写数据模式\* ------------------------------------------------------------ */voidSetWriteCmd(void){LCD_RW=Write;LCD_RS=Cmd;voidSetReadCmd(void){LCD_RW=Read;LCD_RS=Cmd;}voidSetWriteData(void){LCD_RW=Write;LCD_RS=Data;}/* ---------------------- LCD 功能执行函数-------------------------- *\WriteCmd() 写命令WriteData() 写数据ExecuteCmd() 执行命令SetXY() 显示定位DisplaySingleChar() 显示单个字符DisplayString() 显示一串字符IsBusy() 忙标志检测\* ----------------------------------------------------- ------- */voidWriteCmd(charcmd){while(IsBusy());LCD_Data=cmd;SetWriteCmd();ExecuteCmd();}voidWriteData(charddata){while(IsBusy());LCD_Data=ddata;SetWriteData();ExecuteCmd();}voidExecuteCmd(void){LCD_E=Enable;LCD_E=Disable;}voidSetXY(charx,chary){if(y)x|=0x40;x|=0x80;Delay(5);WriteCmd(x);}voidDisplaySingleChar(charx,chary,charcchar)SetXY(x,y);WriteData(cchar);}voidDisplayString(charx,chary,char*str){while(*str){Delay(5);DisplaySingleChar(x++,y,*str);str++;}}bitlsBusy(void){LCD_Data=OxFF;SetReadCmd();ExecuteCmd();return(bit)(P1 &0x80);}/* ------------------------- 延时------------------------- */voidDelay (un sig nedi nttime){un sig nedi nttimeCo un ter=0;for(timeCo un ter=time;timeCo un ter>0;timeCo un ter--)DelayUs(255);}voidDelayUs( un sig nedi nttime){un sig nedi nttimeCo un ter=0;for(timeCo un ter=0;timeCo un ter<time;timeCo un ter++)_n op_();}/****************************************************************************** *************、** LCD显示模块\****************************************************************************** *************/voidComputeTime(void){if(AreaO<5)PassTime+=0.5;}voidComputeSpeedANDDista nce(void){Speed=SpeedCou nt/4*CircleLe ngth; // 计算瞬时速度Dista nce+=Speed; // 计算距离SpeedCou nt=O;}/* ------------------------- 显示*/voidDisplayTime(void){charPassTime1=0x30;charPassTime2=0x30;charPassTime3=0x30;charPassTime4=0x30;if((int)PassTime*100<100) // 时间未够1s{PassTime1+=0;PassTime2+=(int)(PassTime*100)/10;PassTime3+=(int)(PassTime*100)%10;}elseif((int)(PassTime*100)>100 &&(int)(PassTime*100)<1000)// 够1s 而未够10s { PassTime1+=(int)(PassTime*100)/100;PassTime2+=(int)(PassTime*100)/10%10;PassTime3+=(int)(PassTime*100)%10;}else{PassTime1+=(int)(PassTime*100)/1000;PassTime2+=(int)(PassTime*100)/100%10;PassTime3+=(int)(PassTime*100)/10%10;PassTime4+=(int)(PassTime*100)%10;}if((int)(PassTime*100)<1000){DisplaySingleChar(0x05,1,PassTime1);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,PassTime2);DisplaySingleChar(0x08,1,PassTime3);}else{DisplaySingleChar(0x04,1,PassTime1);DisplaySingleChar(0x05,1,PassTime2);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,PassTime3);DisplaySingleChar(0x08,1,PassTime4);}}/* ------------------------- 显示平均速--------------------------- */ voidDisplayAVGSpeed(void) {intSpeed1=0x30; // 初始化为0 的ASCII 码intSpeed2=0x30;intSpeed3=0x30; if((int)(Distance/PassTime*100)<100){Speed1+=0;Speed2+=(int)(Distance/PassTime*100)/10;Speed3+=(int)(Distance/PassTime*100)%10;}else{Speed1+=(int)(Distance/PassTime*100)/100;Speed2+=(int)(Distance/PassTime*100)/10%10;Speed3+=(int)(Distance/PassTime*100)%10;}DisplaySingleChar(0x05,1,Speed1);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,Speed2);DisplaySingleChar(0x08,1,Speed3);}/* ------------------------- 显示路--------------------------- */voidDisplayDistance(void){intDistance1=0x30;intDistance2=0x30;intDistance3=0x30;intDistance4=0x30;if((int)(Distance*100)<100){Distance1+=0;Distance2+=(int)(Distance*100)/10;Distance3+=(int)(Distance*100)%10;}elseif((int)(Distance*100)>100 &&(int)(Distance*100)<1000) {Distance1+=(int)(Distance*100)/100;Distance2+=(int)(Distance*100)/10%10;Distance3+=(int)(Distance*100)%10; }else {Distance1+=(int)(Distance*100)/1000;Distance2+=(int)(Distance*100)/100%10;Distance3+=(int)(Distance*100)/10%10;Distance4+=(int)(Distance*100)%10;} if((int)(Distance*100)<1000){DisplaySingleChar(0x05,1,Distance1); DisplaySingleChar(0x06,1,'.'); DisplaySingleChar(0x07,1,Distance2);DisplaySingleChar(0x08,1,Distance3); }else{DisplaySingleChar(0x04,1,Distance1); DisplaySingleChar(0x05,1,Distance2);DisplaySingleChar(0x06,1,'.');DisplaySingleChar(0x07,1,Distance3);DisplaySingleChar(0x08,1,Distance4);}}/* -------------------------中断初始化-------------------------- */ voidINTInit(void){EA=1; // 开总中断IT0=1; //INTO 边沿触发PX0=1; //INTO 优先级为高级EX1=1; // 开INT1 中断IT1=1; //INT1 边沿触发PX1=1; //INT1 优先级为高级Clock0_Init(); // 初始化时钟中断TMOD=0x11; //T0/T1 定时方式 1ET0=0x01; // 开T0 中断ET1=0x01; // 开T1 中断}voidClock0_Init(void){TR0=0x01; // 启动T0TH0=Thx0; // 定时初值TL0=Tlx0;}voidClock1_Init(void){TR1=0x01; // 启动T1TH1=0x3C; // 定时初值-50ms 中断一次TL1=0x0B0;}/*******************************************************************************************、**中断处理程序\*******************************************************************************************//* ----------------------- 外部中断0 ---------------------------- *\外部中断0有两个功能(1)作为菜单选择的Next键(2)作为测速的计数器\* ------------------------------------------------------------- */voidSpeedlNT(void)interruptO // 中断INTO {if(SelectedAII==False) // 如果模式和速度还没有选择完毕,则此中断作为。

智能循迹小车程序

智能循迹小车程序
{
IN5=0;
IN6=1;
IN7=0;
IN8=1;
dj1=15;
dj2=15;
}
void turnleft2()//小车前进向左微调
{
IN5=0;
IN6=1;
IN7=0;
IN8=1;
dj1=7;
dj2=20;
}
void turnright2()//小车前进向右微调
{
IN5=0;
IN6=1;
IN7=0;
{
turnright2();
}
if(HW1==0&&HW2==1&&HW3==1&&HW4==1)
{
turnleft2();
}
if(HW1==1&&HW2==1&&HW3==1&&HW4==0)
{
turnright2();
}
if(num2==3&&HW1==0&&HW2==0&&HW3==0&&HW4==0)
sbit ENB=P3^3;
sbit IN5=P2^4;//电机
sbit IN6=P2^5;
sbit IN7=P2^6;
sbit IN8=P2^7;
void delay(uint x)//延时1ms
{
uint i,j;
for(i=0;i<x;i++)
for(j=0;j<120;j++);
}
void qianjin()//小车前进
{
turnright2();
}

智能循迹小车详细源代码程序(MSP430,PID)

智能循迹小车详细源代码程序(MSP430,PID)
80 }
81 LEFTOUT=Period/100*speed;
82 }
83 void MotorRight(int speed,int direction)
84 {
85 if(speed>max_speed)speed=max_speed;
86
72 {
73 EnableLeftNeg;
74 UnenableLeftPos;
75 }
76 else if(direction==foreward)//正转
77 {
78 EnableLeftPos;
79 UnenableLeftNeg;
17 #define LEFTOUT TACCR1
18 #define RIGHTOUT TACCR2
19 #define SensorIn P5IN
20 #define F 5000//5000hz
21 #define Period (8000000/F)
64 {
65 LEFTOUT=0;
66 RIGHTOUT=0;
67 }
68 void MotorLeft(int speed,int direction)
69 {
70 if(speed>max_speed)speed=max_speed;
71 if(direction==backward)//反转
183 TACCTL2|=OUTMOD_7;//
184 LEFTOUT=0;
185 RIGHTOUT=0;
186 }
187
188 float abs(float a)
189 {

智能循迹小车C程序(完美_详尽)

智能循迹小车C程序(完美_详尽)

/*小车运行主程序简介: @模块组成:红外对管检测模块---- 五组对管,五个信号采集端口直流电机驱动模块 -- 驱动两个直流电机,另一个轮子用万向轮单片机最小系统 ---- 用于烧写程序,控制智能小车运动@ 功能简介:在白色地面或皮质上用黑色胶带粘贴出路线路径宽度微大于相邻检测管间距。

这样小车便可在其上循迹运行。

@ 补充说明:该程序采取“右优先”的原则:即右边有黑线向右转,若无,前方有黑线,向前走,若无,左边有黑线,向左转,若全无,从右方向后转。

程序开头定义的变量的取值是根据我的小车所调试选择好的,如果采用本程序,请自行调试适合自己小车的合适参数值。

编者:陈尧,黄永刚(江苏大学电气学院二年级,三年级)1. 假定:IN仁1,IN3=1 时电机正向转动,必须保证本条件2. 假定: 遇到白线输出 0,遇到黑线输出 1;如果实际电路是:遇到白线输出1,遇到黑线输出 0,这种情况下只需要将第四,第五句改成:#define m0 1#define m1 0即可。

3. 说明 1:直行--------- 速度 full_speed_left,full_speed_right.转弯 , 调头速度 - c orrect_speed_left,correct_speed_right.微小校正时 ------ 高速轮 full_speed_left,full_speed_right;低速轮 correct_speed.可以通过调节第六,七,八,九,十条程序,改变各个状态下的占空比( Duty cycle ) ,以求达到合适的转弯,直行速度4.lenth ---- length 检测到黑线到启动转动的时间间隔5. width ---- mid3 在黑线上到脱离黑线的时间差6. mid3 ----- 作为判断中心位置是否进入黑线的标志,由于运行的粗糙性和惯性,常取其他对管的输出信号作为判断条件7. check_right 若先检测到左边黑线,并且左边已出黑线,判断右端是否压黑线时间拖延*/#include<reg52.h>#define uchar unsigned char#define uint unsigned int#define m0 1〃黑线 ml,白线 m0#define m1 0#define full_speed_left 40 // 方便调节各个状态的占空比 , 可用参数组:(30,35,6,25,30,68000,27000,500 );#define full_speed_right 45 //(40,45,6,25,30,68000,27000,500 );#define correct_speed 6 // 校正时的低速轮的占空比#define turn_speed_left 25#define turn_speed_right 30#define lenth 68000 // 测试数据:10000-- 》100-- 》500-- 》2000--80000--76000--68000#define width 27000 //500-- 》10-->2000-- 》60000--30000--- 》27000#define check_right 500 //2000--#define midl left1 》20-- 》200-- 》500#define midrright5ucharDuty_left,Duty_right,i=0,j=0; //左右占空比标志,取 1--100 sbit IN仁 P2A0;sbit IN2=P2A1;sbit IN3=P2A2;sbit IN4=P2A3;sbit ENA=P1A0;sbitENB=P1A1;// 循迹口五组红外对管,依次对应从左往右第 1,2,3,4,5 五组 sbitleft1 =P1A6;sbit left2 =P1A5;sbit mid3 =P1A4;sbit right4=P1A3;sbit right5=P1A2;void line_left();void line_right();voidline_straight()reentrant;// ------------------------{uint t=Delay_time;while(t--);}// -------------------------void init() // 定时器初始化{left1=m0; // 初始化left2=m0; // 白线位置mid3 =m1; // 黑线位置right4=m0;right5=m0;TMOD|=0x01;TH0=(65536-66)/256;TL0=(65536-66)%256;EA=1;ET0=1;TR0=1;ENA=1; // 使能端口,初始化ENB=1;}// ----------------------------void time0(void)interrupt 1 // 中断程序{i++; // 调速在中断中执行j++;if(i<=Duty_left)ENA=1;else ENA=0;if(i>100){ENA=1;i=0;}if(j<=Duty_right)ENB=1;else ENB=0;if(j>100){ENB=1;j=0;}TH0=(65536-66)/256; // 取约 150HZ, 12M 晶振,每次定时 66us, 分 100 次,这样开头定义的变量正好直接表示占空比的数值TL0=(65536-66)%256;}// ------------------------------void correct_left()// 向左校正,赋值{Duty_left =correct_speed;Duty_right=full_speed_right;IN1=1;IN2=0;IN3=1;IN4=0;}// ------------------------------void correct_right()// 向右校正,赋值{Duty_left =full_speed_left;Duty_right=correct_speed;IN1=1;IN2=0;IN3=1;IN4=0;}// --------------------------------void turn_left()// 左转,赋值{Duty_left =turn_speed_left;Duty_right=turn_speed_right;IN1=0; // 转弯时一个正转,一个反转,IN2=1;IN3=1;IN4=0;}// --------------------------------void turn_right()// 右转,赋值{Duty_left =turn_speed_left;Duty_right=turn_speed_right;IN1=1; // 转弯时一个正转,一个反转,IN2=0;IN3=0;IN4=1;}// ----------------------------------void straight() // 直走,赋值{Duty_left =full_speed_left; // 左右电机占空比初始化,调节直线运动速度Duty_right=full_speed_right; // 鉴于左右轮电机内部阻力不同,故占空比取不同值,这组值需要单独写程序取值IN1=1;IN2=0;IN3=1;IN4=0;}// ----------------------------------void line_straight()reentrant // 函数名后加 reentrant 可以递归调用, // 一直走黑直线时{straight();if(right5==m1){line_right();}elseif(left1==m1){line_left();}elseif(left2==m1) // 防止校正时,小车冲出过大,导致 2,4 号检测管屏蔽了两端检测管的检测,避免其走直线时出轨while(left2==m1){correct_left();if(right5==m1){line_right();goto label3;}else if(left1==m1){line_left();goto label3;}}elseif(right4==m1) // 防止校正时,小车冲出过大,导致 2,4 号检测管屏蔽了两端检测管的检测,避免其走直线时出轨while(right4==m1){correct_right();if(right5==m1){ line_right(); goto label3;}else if(left1==m1){line_left();goto label3;}}else if((left1==m0)&&(left2==m0)&&(mid3==m0)&&(right4==m0)&&(right5==m0)){straight();//delay(lenth);while(right4==m0) // 本来应该是用 mid3, 但是为了提高灵敏度,选择 right4 ;向左时,可取 left2 对管{turn_right();} if(mid3==m1){line_straight();}}label3: ; // 什么都不做}// -----------------------------------------------void line_right() // 右边有黑线时{straight();// 这里的直走是在不管红外检测结果的直行 delay(lenth);if(mid3==m1){turn_right();// 执行向右转的赋值label:delay(width); // 由 width 值决定转弯时 mid3 经过黑线宽度时所需要的时间 if(mid3==m0) while(right4==m0){}elsegoto label;}else if(mid3==m0){turn_right();while(right4==m0){}if(midr==m1){line_straight();}}}// ------------------------------------------void line_left() // 左边出现黑线时{while(left1==m1){if(right5==m1){line_right();goto label2;}delay(check_right);// 左边遇到黑线时,左边出了黑线之后,继续延时一段时间,判断右边是否遇到黑线,// 若遇到黑线,执行 line_right() 函数if(right5==m1){line_right();goto label2;}if((mid3==m1)||(left2==m1)||(right4==m1)){line_straight();} else{while(left2==m0){turn_left();}if(midl==m1) line_straight();}label2: ;}// -------------------------------------------void detect_infrared() // 循迹,红外检测{if(right5==m1){line_right();}elseif(left1==m1){line_left();}elseif(left2==m1){correct_left();}elseif(right4==m1){correct_right();}elseline_straight();}// ------------------------void main(void)// 主程序部分{init();while(1) // 循环检测红外对管采集的电平信号{detect_infrared();}。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include<reg52.h> #define uchar unsigned char
#define uint unsigned int
//D0-D7:f,b,a,e,d,h,c,g 共阴 依次编码 //74LS04 反相器驱动数码管
uchar code table[10] = {0x5F,0x42,0x9E,0xD6,0xC3,0xD5,0xDD,0x46,0xDF,0xD7};
uchar
i = 0; // 用于 0-3 数码管轮流显示 uint
j = 0; // 计时的次数 uint
time=0; // 计时 uint
pwm=16; // 占空比 uint
speed; //调制PWM 波的当前的值
// 电机驱动口定义
sbit
ENB=P1A0; // 前轮电机停止控制使能 sbit
ENA=P1A1; // 后轮控制调速控制端口 sbit
IN1=P1A2; // 前轮 sbit
IN2=P1A3; // 前轮 sbit
IN3=P1A4; // 后轮 sbit IN4=P1A5; // 后轮
void Init()
{
TMOD = 0x12; // 定时器 0 用方式 2, 定时器 1 用方式 1
TH0=(256-200)/256; //pwm
TL0=(256-200)/256;
TH1 = 0x0F8; // 定时 2ms
TL1 = 0x30;
EA = 1;
ET0 = 1;
ET1 = 1;
TR0 = 1;
TR1 = 1;
}
void tim0(void) interrupt 1 //
产生 PWM
{ speed ++; if(speed <= pwm)
sbit
R=P3A 2; // 右边传感器 P3A 2 sbit L=P3A3; // 左边传感器 P3A3 //pwm 就相当于占 100 的比例
ENA = 1;
}
else if(speed < 100) {
ENA = 0;
}
else
speed = 0;
}
void time1() interrupt 3 {
TH1 = 0x0F8;
TL1 = 0x30;
i =(i+1) % 4; j++;
if(i == 0)
{ P0 = 0x00; P0 = table[time%10]; } if(i == 1) {
P0 = 0x00;
P0 = table[time/ 10% 10]; } if(i == 2) { P0 = 0x00;
P0 = table[time/ 100% 10]; } if(i == 3) {
P0 = 0x00;
P0 = table[time/ 1000% 10];
}
P2 = ( 0x10 << i );
// 送位选信号 if(j == 500)
{
time ++; //500 次为 1 秒 j = 0;
void forward() // 前进
{
IN2=1;
IN1=0;
}
void back() // 后退
{
IN2=0;
IN1=1;
}
void left()
// 左转
{ ENB=1;
// 打开使能 IN3=1;
// 定时 2ms //0-3 循环
// 显示最低位数码管
// 段选清零防止乱码
// 送段码信号
IN4=0;
}
void right() // 右转
{
ENB=1; // 打开使能
IN3=0;
IN4=1;
}
void stop() // 停止
{
IN2=0;
IN1=0;
IN3=0;
IN4=0;
}
void main()
{
Init(); // 定时器初始化while(1)
{
if(R==0 && L==1) // 右传感器检测到黑线
{
right(); // 右转
forward();
while(R==0 && L==1);
}
if(R==1 && L==0) // 左传感器检测到黑线{
left(); forward(); while(R==1 && L==0);
}
if(R==0 && L==0) // 都检测到黑线则停止
{
stop();
j = 0; // 定时器仍在工作,计数时间清空} else // 都没有检测到黑线
{
ENB = 0; // 关闭转向控制
forward();
}
}
}。

相关文档
最新文档