循迹小车设计(附代码)
循迹小车代码
#include<reg52.h>#define uchar unsigned char#define uint unsigned intuint a,d,y,z,h,q;sbit out1 = P0^0 ;//电机驱动输出控制管脚配置sbit out2 = P0^1 ;sbit out3 = P0^2 ;sbit out4 = P0^3 ;sbit in1 = P2^0;//循迹模块的信号输入管脚配置sbit in2 = P2^1;sbit in3 = P2^2;sbit in4 = P2^3;sbit in5 = P2^4;delay(uint a);int zuozhuan(uint z)//控制小车做左转动作(参数z和a可以用来调节左转时间,本程序设定//为不同参数表示每次调用程序左转时间相同不可变,没有调节转弯时间的功能){out1=1;out2=0;out3=0;out4=1;delay(a);}int youzhuan(uint y)//控制小车做右转动作(参数y和a可以用来调节右转时间,本程序设定//为不同参数表示每次调用程序右转时间相同不可变,没有调节转弯时间的功能){out1=0;out2=1;out3=1;out4=0;}int houtui(uint h)//控制小车可以使小车倒退行驶(参数功能与转弯类似){out1=0;out2=1;out3=0;out4=1;delay(a);out1=0;out2=0;out3=0;out4=0;delay(20);}int dengdai (uint d) //使小车停止当前所有动作,停止时间可调。
{out1=0;out2=0;out3=0;out4=0;delay(d);}void qianjin(q)//使小车向前行驶,行驶时间可调{out1=1;out2=0;out3=1;out4=0;delay(q);}void xunji(){P1=P1|0XF0; d elay(5);if(in1==0){dengdai();youzhuan(100);while(in3==1);}else if(in5==0){dengdai();zuozhuan(100);while(in3==1);}else if(in2==0){dengdai();youzhuan(30);}else if(in4==0){dengdai();zuozhuan(30);}else if(in3==0) {qianjin(20); }else {qianjin(20);}}int delay(uint a)//延时子函数{uint x,y;for(x=a;x>0;x--)for(y=110;y>0;y--);}void main(){delay(2000);while(1)xunji();}#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 R=P3^2; //右边传感器P3^2 sbit L=P3^3; //左边传感器P3^3 //电机驱动口定义sbit ENB=P1^0; //前轮电机停止控制使能sbit ENA=P1^1; //后轮控制调速控制端口sbit IN1=P1^2; //前轮sbit IN2=P1^3; //前轮sbit IN3=P1^4; //后轮sbit IN4=P1^5; //后轮void Init() {TMOD = 0x12; //定时器0用方式2,定时器1用方式1TH0=(256-200)/256; //pwmTL0=(256-200)/256;TH1 = 0x0F8; //定时2msTL1 = 0x30;EA = 1;ET0 = 1;ET1 = 1;TR0 = 1;TR1 = 1;}void tim0(void) interrupt 1 //产生PWM{speed ++;if(speed <= pwm) //pwm 就相当于占100的比例{ENA = 1;}else if(speed < 100){ENA = 0;}elsespeed = 0;}void time1() interrupt 3 //定时2ms{TH1 = 0x0F8;TL1 = 0x30;i =(i+1) % 4; //0-3循环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;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();}}}。
智能小车循迹、避障、红外遥控C语言代码
智能小车循迹、避障、红外遥控C语言代码//智能小车避障、循迹、红外遥控 C 语言代码// 实现功能有超声波避障,红外遥控智能小车,红外传感器实现小车自动循迹, 1602 显示小车的工作状态,另有三个独立按键分别控制三种状态的转换// 注:每个小车的引脚配置都不一样,要注意引脚的配置,但是我的代码注释比较多,看起来比较容易一点#include <> #include <> #include"" #include <> #define uchar unsigned char #define uint unsigned int uchar ENCHAR_PuZh1[8]=" uchar ENCHAR_PuZh2[8]=" uchar ENCHAR_PuZh3[8]=" uchar ENCHAR_PuZh4[8]=" uchar ENCHAR_PuZh5[8]=" run back stop left right "; ";//1602 显示数组H. H. H. uchar ENCHAR_PuZh6[8]=" xunji "; uchar ENCHAR_PuZh7[8]=" bizhang"; uchar ENCHAR_PuZh8[8]=" yaokong"; #define HW P2 #define PWM /****************************** P1 //红外传感器引脚配置P2k 口/* L298N 管脚定义*/ 超声波引脚控制******************************/ sbit ECHO=P3A2; sbit TRIG=P3A3;///// 红外控制引脚配置 sbit sbituchar KEY2=P3A7; KEY 仁 P3M;state_total=3,state_2=0;// 2 为红外遥控 ucharuchar time_1 uchar 局变量 // 超声波接收引脚定义 // 超声波发送引脚定义// 红外接收器数据线 // 独立按键控制总状态控制全局变量 state_1,DAT; // 红外扫描标志位time_1=0,time_2=0;// 定时器1 中断全局变量控制转弯延时计数也做延时一次time,timeH,timeL,state=0;// 超声波测量缓冲变量count=0;//1602 显示计数兼红外遥控按键state_total =2 兼循迹按键state_total= 0 自动避障 state_total=10 为自动循迹模块 1 为自动避障模块 time_ 2 控制 PWM 脉冲计数state 为超声波状态检测控制全uint /**************************/ unsigned char IRC0M[7]; // 红外接收头接收数据缓存unsigned char Number,distance[4],date_data[8]={0,0,0,0,0,0,0,0}; /********* voidvoid voidIRC0M[2 ]存放的为数据 // 红外接收缓存变量 **/ IRdelay(char x); //x* 红外头专用 delay run(); back();void stop(); void left_90(); void left_180(); void right_90(); void delay(uint dat); //void init_test();void delay_100ms(uint ms) ;void display(uchar temp); void bizhang_test(); void xunji_test(); void hongwai_test();void Delay10ms(void);void init_test()// 定时器 0{ 1 外部中断 // 超声波显示驱动 0 1 延时初始化 TMOD=0x11; TH1=0Xfe; TL1=0x0c; TF0=0; TF1=0; ET0=1; ET1=1; EA=1;// 设置定时器 0 1 // 装入初值定时一次为工作方式 1 16 位初值定时器2000hz// 定时器 // 定时器 // 允许定时器// 允许定时器 0 方式 1 计数溢出标志 1 方式 1 计数溢出标志 0 中断溢出 1 中断溢出//开总中断 if(state_total==1)// 为超声波模块时初始化 {TRIG=0; ECHO=0; EX0=0; IT0=1;}if(state_total==2)// 发射引脚低电平 // 接收引脚低电平 // 关闭外部中断// 由高电平变低电平,触发外部中断 0// 红外遥控初始化{ IT1=1; EX1=1;TRIG=1;}del ay(60);} void main(){ uint i; delay(50); init_test(); TR1=1; LCD1602_Init() ; delay(50); while(state_2==0)// 外部中断 1 为负跳变触发 // 允许外部中断 1 // 为高电平 I/O 口初始化// 等待硬件操作// 开启定时器 1{if(KEY1==0){Delay10ms(); // 消除抖动 if(KEY1==0) {state_total=0; // 总状态定义 0 为自动循迹模块 1 为自动避障模块2 为红外遥控while((i<30)&&(KEY1==0))// 检测按键是否松开{Delay10ms(); i++;}i=0;}}if(TRIG==0){while((i<30)&&(TRIG==0))// 检测按键是否松开{Delay10ms(); i++;}i=0;}if(KEY2==0){while((i<30)&&(KEY2==0))// 检测按键是否松开{Delay10ms(); i++; }i=0;// 检测按键 s1 是否按下//检测按键s2是否按下障模块Delay10ms(); // 消除抖动 if(TRIG==0) { state_total=1; 2 为红外遥控//总状态定义 0 为自动循迹模块 1 为自动避// 检测按键 s3 是否按下障模块Delay10ms(); // 消除抖动 if(KEY2==0) { state_total=2; 2 为红外遥控// 总状态定义 0 为自动循迹模块1 为自动避}}} init_test();delay(50); // 等待硬件操作50us TR1=0; // 关闭定时器 1 if(state_total==1) {//SPEED=90; bizhang_test();} if(state_total==0) {// SPEED=98; 电平// 自动循迹速度控制// 自动循迹速度控制高电平持续次数占空比为10 的低电平高电平持续次数占空比为40 的低xunji_test(); }if(state_total== 2){//SPEED=98; // 自动循迹速度控制高电平持续次数占空比为40 的低电平hongwai_test(); }void 断号init0_suspend(void)2 外部中断0 4 串口中断外部中断 1timeH=TH0;timeL=TL0;state=1;EX0=0;}void 断号0{if(state_total==1) { TH0=0X00;TL0=0x00;}if(state_total==0) { TH0=0Xec;TL0=0x78;time_1++;interrupt 0 //3 为定时器 1 的中断号 1 定时器0 的中// 记录高电平次数//// 标志状态为// 关闭外部中断1,表示已接收到返回信号//3 为定时器 1 的中断号2 外部中断0 4 串口中断time0_suspend0(void) interrupt 1外部中断 1// 自动避障初值装入// 装入初值// 自动循迹初值装入// 装入初值定时一次200hz// 控制转弯延时计数1 定时器0 的中}}void IR_IN(void){unsigned char j,k,N=0;EX1 = 0; IRdelay(5); if (TRIG==1) { EX1 =1; return;}//确认IR 信号出现//等IR 变为高电平,跳过 9ms 的前导低电平信号。
51的智能循迹小车代码
#include<reg52.h>#define sense P1 /*宏定义光电传感器端口*/#define input1 P0 /*左电机的IN1,IN2定义在P0口*/#define input2 P2 /*右电机的IN3,IN4及ENA,ENB定义在P2口*/ //宏定义电机的具体端口sbit MOTO1_INT1=P0^0;sbit MOTO1_INT2=P0^1;sbit MOTO1_ENA=P2^0;sbit MOTO2_INT3=P2^5;sbit MOTO2_INT4=P2^4;sbit MOTO2_ENB=P2^2;//宏定义传感器的具体端口sbit sense_L=P1^3;sbit sense_R=P1^6;//宏定义金属传感器端口sbit METAL=P1^1;//宏定义DELAY函数中的一些变量int Dtime1=20000;int Dtime2=2000;int i=0;unsigned char SIGNAL(void); //传感器信号分析函数void DELAY(void); //延时函数void main(){int a;MOTO1_INT1=1; //使车开始时运动MOTO1_INT2=0;MOTO1_ENA=1;MOTO2_INT3=1;MOTO2_INT4=0;MOTO2_ENB=1;while(1){if(METAL==1) //有金属时车停止DELAY();else{a=SIGNAL();switch(a){case 1:input2=0x25;break; //前进case 2:input2=0x24;break; //左转case 3:input2=0x21;break; //右转default:break;}}}}void DELAY() //延时函数{input2=0x20; //使驱动芯片的两个使能端为0,使两个电机停转for(i=0;i<Dtime1;i++); //实现延时,用DTIME控制input2=0x25; //使驱动芯片的两个使能端为1,使两个电机重新转for(i=0;i<Dtime2;i++);}unsigned char SIGNAL(){unsigned char Re;Re=sense&0x28;if(Re==40)return 1;//前进else if(Re==8)return 2;//左转else if(Re==32)return 3;//右转else return 1;//有错时前进}。
循迹小车程序代码
//(在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延时
循迹小车的C语言程序(带注释)
/************ ******** *
第二部分 电机控制子函数 ************* ******** ******* /
void forward1()// { IN1=0; IN2=1; }
电机
1
前进
void forward2()// { IN3=0; IN4=1; }
电机
2
前进
void back1()// { IN1=1; IN2=0; }
当第一、二个 LED 检测到黑线时,小车左转
if(RP1==0&&RP2==0&&RP3==0&&RP4==1) turn(count1,0,coun t2,200); // 0001
当第一、二、三个 LED 检测到黑线时, 小车
左大转
/************ ******** ***
小车右转*******************************/
当最右边的 LED 检测到黑线时,小车左转
if(RP1==1&&RP2==0&&RP3==1&&RP4==1)
turn(count1,80,coun t2,150); // 1011
当第二个 LED 检测到黑线时,小车偏左转
if(RP1==0&&RP2==0&&RP3==1&&RP4==1) turn(count1,0,coun t2,100); // 0011
void time0()interrupt 1 { TH0=(65536-1000)/256;// TL0=(65536-1000)%256; count1++; count2++; if(count1>=500)// count1=0; if(count2>=500)// count2=0; }
四路循迹小车单片机代码
#include<reg52.h>#define uchar unsigned char#define uint unsigned intsbit p0_0=P0^0;sbit p0_7=P0^7;sbit p1_7=P0^7;sbit EN1=P1^2;//m1脉冲输入sbit EN2=P1^5;//m2脉冲输入//*****************************sbit HW1=P2^0;//加建sbit HW2=P2^1;//减键m1//***************************sbit p2_2=P2^2;sbit p2_3=P2^3; // m2//*********************sbit p1_3=P1^3;sbit p1_4=P1^4;//M2转向组合//******************************sbit p1_1=P1^1;sbit p1_0=P1^0;//M1转向组合//*****M1***********************************************uint t=100;//载波周期uint time0; // 低电平可按键调整量我这里是把周期和低电平设为一个是程序内可调,一个是程序外可调而高电平是死的,也可以反之是一样的uint time1; // 高点平基准量uint timeing0;//立即低电平动态变量uint timeing1; //立即高电平动态变量//*****M2****************//uint t=500;//载波周期uint time_0; // 低电平可按键调整量我这里是把周期和低电平设为一个是程序内可调,一个是程序外可调而高电平是死的,也可以反之是一样的uint time_1; // 高点平基准量uint timeing_0;//立即低电平动态变量uint timeing_1; //立即高电平动态变量//********传感器中间变量定义****************************uchar middate,middate1,middate2;//********************************//void delay(uint z) //延时1ms程序//{//uint x,a,b;//for (x=0;x<z;x++)//{//for(b=120;b>0;b--)//{//for(a=3;a>0;a--);// }// }//// }void stop() //停止函停止HW1=HW2=0;{EA=0;//禁止中断EN1=0;EN2=0;}void goon()//直着走HW1=1=HW2;{EA=1;time0=50;time_0=50;time1=50;time_1=50;}void left()//向左转弯HW1=1;HW2=0; 修改定时数据,实现实时PWM调制{EA=1;//********* time_0=50;time_1=50;// //通过调整左轮的转速来调整转弯力度,这里要配合传感器实时采集才行time0=(time0-1);time1=(t-time0);//***********************timeing0=0;timeing1=0;}void right()//向右转弯HW1=0;HW2=1;{EA=1;//***************time0=50;time1=50;//通过调整右轮的转速来调整转弯力度,这里要配合传感器实时采集才行time_0=(time_0-1);time_1=(t-time_0);//******************timeing_0=0;timeing_1=0;//太关键了!这一步,因为不加的话,当再一次的time0被修改时timeing0,和timeing1不为0//所以才会发生错误,表现为波形时断时续,而且有尖锋脉冲,这都是没有在刷新TIME0的同时刷新tineing的后果//没想到很简单的一点事竟差点酿成PWM做不出来!真是有有教训了//}void InitTimer0(void) //10us 定时器初始化设置函数{TMOD = 0x01;TH0 =0xff;TL0 =0xf7;EA = 1;ET0 = 1;TR0 = 1;}void main(void)//主函数{P2=0x0f;InitTimer0(); //10 us(可变啊,根据不同的精准度和频率要求)//************p1_0=0;p1_1=1;//M2//决策转向p1_3=1;p1_4=0;//M1//************time0=50;//***************************************************************************** *********************************//time1=50; ////time_0=50; ////time_1=50; //通知////L293B的8脚是要接>5V的,16脚要接5V,但是别人的不是这样的,我是看了手册,和失败后这样做的//////这里我用了周期是1000us的但是我的定时器是10us一次的所以我这里取t=100;表示我把周期分成100份////占空比(q)=高电平(time1)/周期(t);故而time1/100=占空比;////电压(u)=占空比*最大电压(Um)故而我的输出电压函数为:U0=Um*q =time1/100*5V(这里我用的是5v电压=Um)// // 根据上述公式可以算出MCU输出电压:例如:我要输出1.5V电压只要让time1=30即可,当然time0=70(保证频率不变) ///我要输出3V只要让time1=60,tim0=40;即可呵呵呵呵// //大概这也就是数模转换的原理吧/////2010年10月24日下午与天津第四项目部宿舍////***************************************************************************** *********************************//while(1) //主循环{//***********************middate=0x00;middate1=0x00;middate2=0x00;middate1=HW1;//传感器信号采集后处理middate2=HW2;CY=0;middate2=(middate2<<1) ;middate=(middate1+middate2) ;// ****************************switch(middate)//转向关键步函数{case 3:{stop();break;}//停止>>>>>>>>>>>>>>HW1=0=HW2;case 1:{left();break;}//左转>>>>>>>>>>>>>>HW1=1;HW2=0;case 2:{right();break;}//右转>>>>>>>>>>>>>>HW1=0;HW2=1;case 0:{goon();break;}//直行>>>>>>>>>>>>>>HW1=1=HW2;}}}void Timer0Interrupt(void) interrupt 1/定时器中断函数生成PWM,接口单元为:time0(PWM1号低电平时间),time1(PWM1号高电平时间),time_0(PWM2号低电平时间),time_1(PWM2号高电平时间),t(周期){//MCU:P1.2是第一路PWM,P1.5是第二路PWMif(time0==timeing0){if(time1!=timeing1){//高电平时间段TH0 =0xff;TL0 =0xf7;EN1=1;timeing1++;}//中断子函数(定时器参量修改)}elseif(time0!=timeing0){TH0 =0xff;EN1=0;//低电平时间段timeing0++;}if(time0==timeing0){if(time1==timeing1){timeing0=0;timeing1=0;}}//****************M2的******************************************************************************* *****************************************************************************if(time_0==timeing_0){if(time_1!=timeing_1){//高电平时间段TH0 =0xff;TL0 =0xf7;EN2=1;timeing_1++;}//中断子函数(定时器参量修改)}elseif(time_0!=timeing_0){TH0 =0xff;TL0 =0xf7;EN2=0;//低电平时间段timeing_0++;}if(time_0==timeing_0){if(time_1==timeing_1){timeing_1=0; }}。
循迹小车程序 带注释
left_qian;
//左边电机前进
right_hou;
//右边电机后退
}
else if((left_2==1)&&(left_1==1)&&(righ_1==1)&&(righ_2==0)) //右转弯 幅度大
{
zkb_l=100;
//左边占空比100%
zkb_r=100;
//右边占空比100%
left_qian;
/*********************************************************************/
void timer0() interrupt 1
{
TH0=0xff;
//定时器0高8位初值(65536-100)/256;
TL0=0x9c;
//定时器0低8位初值(65536-100)%256;
//右边占空比20%
left_qian;
//左边电机前进
right_qian;
//右边电机前进
}
else if((left_2==1)&&(left_1==1)&&(righ_1==0)&&(righ_2==0)) //右转弯 幅度中
{
zkb_l=100;
//左边占空比100%
zkb_r=40;
//右边占空比40%
//左转弯 幅度大
{
zkb_l=100;
//左边占空比100%
zkb_r=100;
//右边占空比100%
left_hou;
//左边电机后退
right_qian;
//右边电机前进
循迹小车代码
#include<reg52.h>#define uchar unsigned char#define uint unsigned intuint a,d,y,z,h,q;sbit out1 = P0^0 ;//电机驱动输出控制管脚配置sbit out2 = P0^1 ;sbit out3 = P0^2 ;sbit out4 = P0^3 ;sbit in1 = P2^0;//循迹模块的信号输入管脚配置sbit in2 = P2^1;sbit in3 = P2^2;sbit in4 = P2^3;sbit in5 = P2^4;delay(uint a);int zuozhuan(uint z)//控制小车做左转动作(参数z和a可以用来调节左转时间,本程序设定//为不同参数表示每次调用程序左转时间相同不可变,没有调节转弯时间的功能){out1=1;out2=0;out3=0;out4=1;delay(a);}int youzhuan(uint y)//控制小车做右转动作(参数y和a可以用来调节右转时间,本程序设定//为不同参数表示每次调用程序右转时间相同不可变,没有调节转弯时间的功能){out1=0;out2=1;out3=1;out4=0;}int houtui(uint h)//控制小车可以使小车倒退行驶(参数功能与转弯类似){out1=0;out2=1;out3=0;out4=1;delay(a);out1=0;out2=0;out3=0;out4=0;delay(20);}int dengdai (uint d) //使小车停止当前所有动作,停止时间可调。
{out1=0;out2=0;out3=0;out4=0;delay(d);}void qianjin(q)//使小车向前行驶,行驶时间可调{out1=1;out2=0;out3=1;out4=0;delay(q);}void xunji(){P1=P1|0XF0; d elay(5);if(in1==0){dengdai();youzhuan(100);while(in3==1);}else if(in5==0){dengdai();zuozhuan(100);while(in3==1);}else if(in2==0){dengdai();youzhuan(30);}else if(in4==0){dengdai();zuozhuan(30);}else if(in3==0) {qianjin(20); }else {qianjin(20);}}int delay(uint a)//延时子函数{uint x,y;for(x=a;x>0;x--)for(y=110;y>0;y--);}void main(){delay(2000);while(1)xunji();}#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 R=P3^2; //右边传感器P3^2 sbit L=P3^3; //左边传感器P3^3 //电机驱动口定义sbit ENB=P1^0; //前轮电机停止控制使能sbit ENA=P1^1; //后轮控制调速控制端口sbit IN1=P1^2; //前轮sbit IN2=P1^3; //前轮sbit IN3=P1^4; //后轮sbit IN4=P1^5; //后轮void Init() {TMOD = 0x12; //定时器0用方式2,定时器1用方式1TH0=(256-200)/256; //pwmTL0=(256-200)/256;TH1 = 0x0F8; //定时2msTL1 = 0x30;EA = 1;ET0 = 1;ET1 = 1;TR0 = 1;TR1 = 1;}void tim0(void) interrupt 1 //产生PWM{speed ++;if(speed <= pwm) //pwm 就相当于占100的比例{ENA = 1;}else if(speed < 100){ENA = 0;}elsespeed = 0;}void time1() interrupt 3 //定时2ms{TH1 = 0x0F8;TL1 = 0x30;i =(i+1) % 4; //0-3循环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;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();}}}。
循迹小车程序代码(带解释说明)
int Left_motor_go=6; //左电机前进(IN1)int Left_motor_back=7; //左电机后退(IN2)int Right_motor_go=9; // 右电机前进(IN3)int Right_motor_back=10; // 右电机后退(IN4)const int SensorRight = 3; //右循迹红外传感器(P3.2 OUT1)const int SensorLeft = 4; //左循迹红外传感器(P3.3 OUT2)int SL; //左循迹红外传感器状态int SR; //右循迹红外传感器状态void setup(){//初始化电机驱动IO为输出方式pinMode(Left_motor_go,OUTPUT); // PIN 8 (PWM)pinMode(Left_motor_back,OUTPUT); // PIN 9 (PWM)pinMode(Right_motor_go,OUTPUT);// PIN 10 (PWM)pinMode(Right_motor_back,OUTPUT);// PIN 11 (PWM)pinMode(SensorRight, INPUT); //定义右循迹红外传感器为输入pinMode(SensorLeft, INPUT); //定义左循迹红外传感器为输入}//=======================智能小车的基本动作========================= //void run(int time) // 前进void run(){digitalWrite(Right_motor_go,HIGH); // 右电机前进digitalWrite(Right_motor_back,LOW);analogWrite(Right_motor_go,20);//PWM比例0~255调速,左右轮差异略增减analogWrite(Right_motor_back,0);digitalWrite(Left_motor_go,LOW); // 左电机前进digitalWrite(Left_motor_back,HIGH);analogWrite(Left_motor_go,0);//PWM比例0~255调速,左右轮差异略增减analogWrite(Left_motor_back,127 );//delay(time * 100); //执行时间,可以调整}//void brake(int time) //刹车,停车void brake(){digitalWrite(Right_motor_go,LOW);digitalWrite(Right_motor_back,LOW);digitalWrite(Left_motor_go,LOW);digitalWrite(Left_motor_back,LOW);//delay(time * 100);//执行时间,可以调整}//void left(int time) //左转(左轮不动,右轮前进) void left(){digitalWrite(Right_motor_go,HIGH);// 右电机前进digitalWrite(Right_motor_back,LOW);analogWrite(Right_motor_go,1);analogWrite(Right_motor_back,0);//PWM比例0~255调速digitalWrite(Left_motor_go,LOW); //左轮后退digitalWrite(Left_motor_back,LOW);analogWrite(Left_motor_go,0);analogWrite(Left_motor_back,0);//PWM比例0~255调速//delay(time * 100);//执行时间,可以调整}void right(){digitalWrite(Right_motor_go,LOW); //右电机后退digitalWrite(Right_motor_back,LOW);analogWrite(Right_motor_back,0);//PWM比例0~255调速digitalWrite(Left_motor_go,LOW);//左电机前进digitalWrite(Left_motor_back,HIGH);analogWrite(Left_motor_go,0);analogWrite(Left_motor_back,127);//delay(time * 100);//执行时间,可以调整}void back(int time){digitalWrite(Right_motor_go,LOW); //右轮后退digitalWrite(Right_motor_back,HIGH);analogWrite(Right_motor_go,0);analogWrite(Right_motor_back,60);//PWM比例0~255调速digitalWrite(Left_motor_go,HIGH); //左轮后退digitalWrite(Left_motor_back,LOW);analogWrite(Left_motor_go,60);analogWrite(Left_motor_back,0);//PWM比例0~255调速delay(time * 100); //执行时间,可以调整}//==========================================================void loop(){//有信号为LOW 没有信号为HIGH 检测到黑线输出高检测到白色区域输出低SR = digitalRead(SensorRight);//有信号表明在白色区域,车子底板上L1亮;没信号表明压在黑线上,车子底板上L1灭SL = digitalRead(SensorLeft);//有信号表明在白色区域,车子底板上L2亮;没信号表明压在黑线上,车子底板上L2灭if (SL == LOW&&SR==LOW)run(); //调用前进函数else if (SL == HIGH & SR == LOW)// 左循迹红外传感器,检测到信号,车子向右偏离轨道,向左转left();else if (SR == HIGH & SL == LOW) // 右循迹红外传感器,检测到信号,车子向左偏离轨道,向右转right();else // 都是黑色, 停止brake();}。
无线遥控循迹避障小车代码
#include< reg51.h >#define uchar unsigned char#define uint unsigned int#define MOTOR_C P1 //P1口作为电机的控制口。
//#define SIGNAL P3 //P3口的低两位为循迹传感器输入口。
#define SHELVES 10 //速度总档数。
#define BACK 0xfa //后退。
#define FORWARD 0xf5 //前进。
#define WXYK P2 //无线遥控sbit senserr = P3^2; //(右)循迹。
sbit senserl = P3^3; //(左)循迹。
sbit hwr = P3^0; //(前)红外壁障传感器入口。
sbit hwl = P3^1; //(后)红外壁障传感器入口。
sbit PWM_R = P1^0; //右电机PWM输入口。
sbit PWM_L = P1^2; //左电机PWM输入口。
sbit PWM_HR = P1^1; //(后退)右电机。
sbit PWM_HL = P1^3; //(后退)左电机。
sbit wxr_a = P2^4; //无线遥控接收端D0sbit wxb_b = P2^5; //无线遥控接收端D1sbit wxl_c = P2^6; //无线遥控接收端D2sbit wxs_d = P2^7; //无线遥控接收端D3void timer0_init( void ); //定时器0初始化函数。
void timer1_init( void ); //定时器1初始化函数。
void right( void ); //前进右转弯函数。
void left( void ); //前进左转弯函数。
void forward( void ); //前进函数。
void hright(void); //后退右转函数。
void hleft(void); //后退左转函数。
循迹小车编程
#define check_right 500 //check_right若先检测到左边黑线,并且左边已出黑线,判断右端是否压黑线时间拖延2000--》20--》200--》500
while(1)//循环检测红外对管采集的电平信号
{
// line_straight();
detect_infrared();
}
}
}
else
{
IN3=1; IN4=1;
}
}
void turn_right()//右转,赋值
{
Duty_left =turn_speed_left;
Duty_right=turn_speed_right;
(ENA==1)
{
IN1=0; IN2=1;//左正
}
else
{
IN1=1; IN2=1;//左正
#define correct_speed 35//校正时的低速端的占空比//
#define turn_speed_left 20
#define turn_speed_right 20//(25,30)--(10,15)--(18,23)
//定义反应时间
#definelenth 40000//length检测到黑线到启动转动的时间间隔10000--》100--》500--》2000--80000--76000--68000
{
straight();//这里的直走是在不管红外检测结果的直行
delay(lenth);//直走一段时间
if(mid3==m1)//如果中间是黑线
智能循迹小车详细源代码程序MSPID
巡线车程序(完整版)1 #ifndef _Macro.h_2 #define _Macro.h_3 #include <msp430x14x.h>4 #include <intrinsics.h>5 #define uchar unsigned char6 #define uint unsigned int7 #define one 11.118 #define LMAX 19999 #define RMAX 399910 #define CPU_F ((double)8000000)11 #define delay_us(x)__delay_cycles((long)(CPU_F*(double)x/1000000.0))1213 #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))14 #define PC 20 // 比例放大系数15 #define IC 0 //积分放大系数16 #define DC 85 //大系数17 #define LEFTOUT TACCR118 #define RIGHTOUT TACCR219 #define SensorIn P5IN20 #define F 5000//5000hz21 #define Period (8000000/F)22 #define EnableLeftPos P3OUT|=BIT123 #define UnenableLeftPos P3OUT&=~BIT12425 #define EnableLeftNeg P3OUT|=BIT026 #define UnenableLeftNeg P3OUT&=~BIT02728 #define EnableRightPos P3OUT|=BIT229 #define UnenableRightPos P3OUT&=~BIT23031 #define EnableRightNeg P3OUT|=BIT332 #define UnenableRightNeg P3OUT&=~BIT33334 #define Basic_Left 100//百分之八十35 #define Basic_Right 100//Basic_Left36 #define MAX (100)37 #define MIN (-100)38 #define foreward 139 #define backward 040 #define max_speed 10041 #define min_speed -10042 #define key 0434445 #define left_1 146 #define left_2 247 #define left_3 348 #define left_4 449 #define left_5 550 #define left_6 651 #define left_7 7//右直角5253 #define right_1 -154 #define right_2 -255 #define right_3 -356 #define right_4 -457 #define right_5 -558 #define right_6 -659 #define right_7 -7//左直角60 #endif[cpp]view plaincopy61 #include "Macro.h"62 #include "sensor.h"63 void Motorstop()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)//反转72 {73 EnableLeftNeg;74 UnenableLeftPos;75 }76 else if(direction==foreward)//正转77 {78 EnableLeftPos;79 UnenableLeftNeg;80 }81 LEFTOUT=Period/100*speed;82 }83 void MotorRight(int speed,int direction)84 {85 if(speed>max_speed)speed=max_speed;8687 if(direction==backward)//反转88 {89 EnableRightNeg;90 UnenableRightPos;91 }92 else if(direction==foreward)//正转93 {94 EnableRightPos;95 UnenableRightNeg;96 }97 RIGHTOUT=Period/100*speed;98 }99 void MotorDrive(int PIDout)100 {101 int speedleft,speedright;102 speedleft=Basic_Left PIDout;103 speedright=Basic_Right-PIDout;104105 if(speedleft<0)106 MotorLeft(speedleft,backward);//反转107 else MotorLeft(speedleft,foreward);//正转108109 if(speedright<0)110 MotorRight(speedright,backward);//反转111 else MotorRight(speedright,foreward);//正转112 }113 void Rangle(float angle)114 {115 // TBCTL|=TBCLR;116 TBCCR1=LMAX (unsigned int)(angle*one);117 }[cpp]view plaincopy118 //下面是小车的程序。
循迹小车完整程序
程序# 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}。
循迹小车设计(附代码)
if(d5==1&&d6==0&&d7==0)
turn_left2();
}
void init()//初始化函数;
{
TMOD=0X01;
TH0=(65536-100)/256; //设置计时时间长度100us
TL0=(65536-100)%256;
ET0=1;
EA=1;
TR0=1;
基于单片机的智能寻迹小车
一.方案设计与论证
1.1控制模块采用STC89C52单片机
设计中采用了一款十分常用的51系列单片机作为处理器,特点是价格低廉、使用方便,且可与其他处理器进行通讯。
系统时钟:晶振频率1/12,本设计采用12M晶振,因此系统时钟为1us。
I/O口资源:4个通用8位准双向I/O口(P0、P1、P2、P3,其中P3为特殊功能口)。
{
d0=0;
d1=1;
d2=0;
d3=0;
zkb1=30;
zkb2=0;
}
void turn_right2()//2级右转
{
d0=0;
d1=1;
d2=0;
d3=0;
zkb1=50;
zkb2=0;
}
void xunji() /*检测到黑线输出为高电平1,检测到白色为低电平0*/
{
if((d5==1&&d6==1&&d7==1)||(d5==0&&d6==1&&d7==0))
#define uint unsigned int
uchar x3,x4;
uint zkb1,zkb2,t=0;
sbit d0=P1^0; /*d1到d3为控制电机的输出口*/
红外循迹小车c程序(舵机小车)
#include<reg52.h>sbit servo=P2^5;uint control=12;uint jishu;uint pianchu;sbit zuo11=P3^4; //为0为左边正转sbit zuo12=P3^5; //为1为左边正转sbit you21=P3^6; //为1为右边正转sbit you22=P3^7; //为0为右边正转uint sp,speed=3;uint ji=1,guang,bi; //判断循迹寻光变量uint stop1,stop2,stop3;void delay(uint a){uint b,c;for(b=a;b>0;b--)for(c=115;c>0;c--);}void qianjin() //可以当做延时函数来用{// P3=0x0f;// delay(speed);P3=0xf9;}void initial_T0(){TMOD=0x21;TH1=0x8c;TL1=0x8c;EA=1;ET1=1;TR1=1;}void xunji(){if(P1==0x00){qianjin();}// if(P1==0x20)// {// //加速// qianjin();// speed=2;// qianjin();// qianjin();// }if(P1==0x10){//左转qianjin();control+=1;qianjin();while(P1!=0x20){if(P1==0x08){//大角度左转qianjin();qianjin();control+=1;while(P1!=0x10){// if(P1==0x00) //偏出跑道,小车停止// {// speed=10000;// }pianchu++;if(pianchu>=20000){break;}}control-=1;qianjin();qianjin();}pianchu++;if(pianchu>=20000){break;}}pianchu=0;control-=1;qianjin();qianjin();}if(P1==0x40){//右转qianjin();control-=1;qianjin();while(P1!=0x20){if(P1==0x80){//大角度右转qianjin();control-=1;qianjin();while(P1!=0x40){// if(P1==0x00) //偏出跑道,小车停止// {// speed=10000;// }pianchu++;if(pianchu>=20000){break;}}qianjin();control+=1;qianjin();}pianchu++;if(pianchu>=20000){break;}}pianchu=0;qianjin();control+=1;qianjin();}}void main(){initial_T0();P1=0xf8;while(1){stop1=P1;if(stop1==stop2){stop3++;}else{stop3=0;}xunji();if(P1==0x80||P1==0x08||stop3>10000){P3=0x00;while(1);}stop2=P1;}}void T0_waytwo() interrupt 3 {if(jishu<control)servo=1;elseservo=0;jishu++;jishu=jishu%160;}。
智能循迹小车详细源代码程序(MSP430,PID)
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 {
智能循迹小车程序代码(4路)
智能循迹小车程序代码(4路)/************************************************************** **************硬件连接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#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(); }}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基于单片机的智能寻迹小车
一.方案设计与论证
1.1控制模块采用STC89C52单片机
设计中采用了一款十分常用的51系列单片机作为处理器,特点是价格低廉、使用方便,且可与其他处理器进行通讯。
系统时钟:晶振频率1/12,本设计采用12M晶振,因此系统时钟为1us。
I/O口资源:4个通用8位准双向I/O口(P0、P1、P2、P3,其中P3为特殊功能口)。
通讯:一对全双工串行通讯口(P3.0、P3.1),可与其他单片机或上位机进行通讯。
中断:2个外部中断(/INT0、/INT1),2个定时器中断(T0、T1),1个串行通讯中断,共5个中断资源并有2级中断优先级可供配置。
ROM:该单片机提供8K的ROM供用户编写程序。
1.2 寻黑胶带方案
方案一、
可见光发光二级管组成的发射-接收电路。
这种方案的缺点在于其他环境光源会对光敏二极管的工作产生很大干扰,一旦外界光亮条件改变,很可能造成误判和漏判;虽然采取超高亮发光管可以降低一定的干扰,但这又将增加额外的功率损耗。
方案二、
反射式红外发射-接收器。
由于采用红外管代替普通可见光管,可以降低环境光源干扰,大大减小了误判和漏判的可能性。
经过比较选择方案二。
电机的选择和控制
方案一:
采用电阻网络或数字电位器调整电动机的分压,从而达到调速的目的。
但是电阻网络只能实现有级调速,而数字电阻元件价格比较昂贵。
更主要的问题在于一般电动机的电阻比较小,但电流比较大;分压不仅降低了效率,而且实现很困难。
方案二:
采用继电器对电动机的开或关进行控制,通过开关的切换对电动机的转速进行控制,此方案的优点是电路比较简单,缺点是继电器的响应时间慢,机械结构易损坏,寿命较短、可靠性不高。
方案三:
采用由达林顿管组成的H型PWM电路。
用单片机控制达林顿管使之工作在占空比可调的开关状态,精准调整电动机转速。
这种电路由于工作在管子的饱和截至状态下,效率非常高;H型电路保证了可以简单的实现转速的控制;电子开关的速度很快,稳定性也较之继电器高的多,是一种广泛采用的PWM调速技术。
经过比较选择方案三。
二.硬件电路设计
2.1反射式红外发送接收对管的使用
本设计采用的是tcrt5000反射式光电传感器,原理图如下,传感器采用高
发射功率红外光电二极管和高灵敏光电晶体管组成,输出信号经施密特电路整形,稳定可靠。
其工作电压为DC3V~5.5V,推荐工作电压为5V,检测距离为1mm~8mm,焦点距离为2.5mm。
传感器检测到黑线输出为高电平,发光二极管为熄灭状态;检测到白色时输出低电平,发光二极管被点亮。
2.2 电源模块
小车的供电采用的是由两节输出电压为3.7的可充电锂电池串联的电池组,选用锂电池的原因在于锂电池可以多次充电,输出电流大可保证电机正常工作
2.3 电机驱动电路
小车采用两轮驱动,另外一个为万向轮,为了使小车灵活运动,要求小车在速度和方向上能够大范围调整。
为此我们选择了控制可靠、便于单片机控制的脉宽调制专用集成电路L298N,一片L298N可驱动两个直流电机。
L298N为Multiwatt15封装,工作电压最高为50V,通过电流达5A。
既可以与整个系统使用同一电源,又有足够的输出电流驱动电机。
L298N 驱动芯片上集成有5V稳压芯片,可从L298N上连线给单片机及红外对管供电。
我们用单片机产生PWM波,通过调节占空比来控制电机的转速。
A、B连接小车的左电机,C、D 连接小车的右电机。
左右电机速度相同时可实现小车的前进或后退;速度不同时可实现小车的转弯;当两个电机反向等速运转时,小车可原地转圈。
循迹控制程序设计
整体电路如下:
车前从左至右安装3个红外发送接收对管。
(白色输出0,黑色输出1)
源代码如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar x3,x4;
uint zkb1,zkb2,t=0;
sbit d0=P1^0; /*d1到d3为控制电机的输出口*/
sbit d1=P1^1;
sbit d2=P1^2;
sbit d3=P1^3;
sbit d5=P1^5; /*d5到d7为红外信号输入口*/ sbit d6=P1^6;
sbit d7=P1^7;
sbit ENA=P0^0; /*定义使能端ENA ENB接口*/ sbit ENB=P0^1;
void qianjin() //前进
{
d0=0;
d1=1;
d2=0;
d3=1;
zkb1=50;
zkb2=50;
}
void back()
{
d0=1;
d1=0;
d2=1;
d3=0;
zkb1=40;
zkb2=40;
}
void turn_left1() //1级左转
{
d0=0;
d1=0;
d2=0;
d3=1;
zkb1=0;
zkb2=30;
}
void turn_left2() //2级左转
{
d0=0;
d1=0;
d2=0;
d3=1;
zkb1=0;
zkb2=50;
}
void turn_right1() //1级右转
{
d0=0;
d1=1;
d2=0;
d3=0;
zkb1=30;
zkb2=0;
}
void turn_right2()//2级右转
{
d0=0;
d1=1;
d2=0;
d3=0;
zkb1=50;
zkb2=0;
}
void xunji() /*检测到黑线输出为高电平1,检测到白色为低电平0*/ {
if((d5==1&&d6==1&&d7==1)||(d5==0&&d6==1&&d7==0)) qianjin();
if(d5==0&&d6==0&&d7==0)
back();
if(d5==0&&d6==1&&d7==1)//右边压黑线
turn_right1();
if(d5==0&&d6==0&&d7==1)
turn_right2();
if(d5==1&&d6==1&&d7==0) //左边压黑线
turn_left1();
if(d5==1&&d6==0&&d7==0)
turn_left2();
}
void init()//初始化函数;
{
TMOD=0X01;
TH0=(65536-100)/256; //设置计时时间长度100us
TL0=(65536-100)%256;
ET0=1;
EA=1;
TR0=1;
ENA=1;
ENB=1;
d0=0;
d1=1;
d2=0;
d3=1;
}
void main()
{
init();
while(1) //主函数等待中断请求;
{
xunji();
}
}
void time0() interrupt 1
{
TH0=(65536-100)/256; //设置计时时间长度
TL0=(65536-100)%256;
if(t<=zkb1)
ENA=1;
else
ENA=0;
if(t<=zkb2)
ENB=1;
else
ENB=0;
t++;
if(t>=50)//周期为5ms
t=0;
}。