|
六路循迹小车,红外模块作循迹部分,主控芯片用STC89C52RC,lcd1602显示小车行驶时间,小车通过设定标志位来通过复杂的赛道,小车赛道如图:
白色区域是上坡,两个凹槽是障碍物
对赛道解析:中间白色,两边黑色的是桥,蓝色的区域是一个坡,中间的凹槽是障碍物.
程序如下:
- #include <reg52.h>
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit En_L=P1^4;
- sbit En_R=P1^5; //定义使能端
- sbit l2 = P2^0;
- sbit ml = P2^1;
- sbit r2 = P2^2;
- sbit mr = P2^3;
- sbit l1 = P1^6;
- sbit r1 = P1^7; //定义传感器位置: (l1) (l2) (ml) (mr) (r2) (r1)
-
- sbit IN1 = P1^0;
- sbit IN2 = P1^1;
- sbit IN3 = P1^2;
- sbit IN4 = P1^3; //定义驱动IO口
- uchar count,num;
- uchar bz=0; //定义标志位
- #define PWM_CHUZHI 100
- #define S_CIRCLE 100
- uchar Speed_L_Now;
- uchar Speed_R_Now; //左右轮实时速度
- #define Data P0 //lcd数据端口
- sbit RS = P2^7; //lcd的rs口
- sbit RW = P2^6; //lcd的rw口
- sbit E = P2^5; //lcd的e口
- int sec=0,min=0;
- uchar FirstLine[]=" Time:00min00s";
- /********功能函数********/
- /***延时函数***/
- void DelayMs(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- /******液晶写命令******/
- void lcd_write_com(uchar c)
- {
- DelayMs(5); //操作前短暂延时,保证信号稳定
- E=0;
- RS=0;
- RW=0;
- _nop_();
- E=1;
- Data=c;
- E=0;
- }
- /*****写数据*****/
- void lcd_write_dat(uchar c)
- {
- DelayMs(5);// 操作前短暂延时,保证信号稳定
- E=0;
- RS=1;
- RW=0;
- _nop_();
- E=1;
- Data=c;
- E=0;
- RS=0;
- }
- /*******LCD初始化****/
- void lcd_init()
- {
- DelayMs(15);
- lcd_write_com(0x38);
- DelayMs(10);
- lcd_write_com(0x38);
- DelayMs(10);
- lcd_write_com(0x38);
- DelayMs(10);
- lcd_write_com(0x06);
- DelayMs(10); //显示光标移动位置
- lcd_write_com(0x0c);
- DelayMs(10); //显示开及光标设置
- lcd_write_com(0x01);
- DelayMs(10); //显示清屏
- for(num=0;num<15;num++)
- {
- lcd_write_dat(FirstLine[num]); //将“Time:”写入LCD
- DelayMs(5);
- }
- }
-
- /****定时器T1:液晶实时显示***/
- void timer1()interrupt 3
- {
- TH1=(65536-50000)/256;
- TL1=(65536-50000)%256;
- count++;
- }
- /******定时器0用于输出PWM控制电机速度*******/
- void motor_pwm_out()interrupt 1
- {
- static uchar count;
- TH0=(65536-PWM_CHUZHI)/256;
- TL0=(65536-PWM_CHUZHI)%256;
- count++;
- if(count>=Speed_L_Now)
- {
- En_L=0;
- }
- if(count>=Speed_R_Now)
- {
- En_R=0;
- }
- if(count==S_CIRCLE)
- {
- En_L=1;
- En_R=1;
- count=0;
- }
- }
- void write_fm(uchar add,uchar date) //将分秒写进lcd的函数
- {
- uint shi,ge;
- lcd_write_com(0x80+add);
- shi=date/10;
- ge =date%10;
- lcd_write_dat(0x30+shi);
- lcd_write_dat(0x30+ge);
- }
- void ahead() //前进函数
- {
- IN1=1;
- IN2=0;
- IN3=1;
- IN4=0;
- Speed_L_Now=46;
- Speed_R_Now=43;
- }
- void poahead() //上坡后的前进函数
- {
- IN1=1;
- IN2=0;
- IN3=1;
- IN4=0;
- Speed_L_Now=43;
- Speed_R_Now=40;
- }
- void turn_left() //左转函数
- {
- IN1=0;
- IN2=1;
- IN3=1;
- IN4=0;
- Speed_L_Now=44;
- Speed_R_Now=42;
- }
- void turn_right() //右转函数
- {
- IN1=1;
- IN2=0;
- IN3=0;
- IN4=1;
- Speed_L_Now=44;
- Speed_R_Now=42;
- }
- void big_turn() //上坡后大转弯函数
- {
- IN1=1;
- IN2=0;
- IN3=0;
- IN4=1;
- Speed_L_Now=43;
- Speed_R_Now=20;
- }
- void stop() //停止函数
- {
- IN1=0;
- IN2=0;
- IN3=0;
- IN4=0;
- }
- void xunji1() //循迹控制函数
- {
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //六个都没检测到黑线
- ahead();
- if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //l1检测到
- turn_left();
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0) //l2检测到
- turn_left();
- if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l1,l2,ml检测到
- ahead();
- if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l2,ml检测到
- turn_left();
- if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1) //r1,r2检测到
- turn_right();
- if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1) //mr,r2检测到
- turn_right();
- if(l1==0&&ml==1&&r1==0&&mr==0&&l2==0&&r2==0) //ml检测到
- turn_left();
- if(l1==0&&ml==1&&mr==1&&r1==0&&l2==0&&r2==0) //ml,mr检测到
- poahead();
- if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==0) //mr检测到
- turn_right();
- if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
- turn_right();
- if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
- turn_right();
- if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
- ahead();
- if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
- ahead();
- if(l1==1&&ml==1&&mr==1&&r1==0&&l2==1&&r2==0) //l1,l2,mr,ml检测到
- ahead();
- if(l1==0&&ml==1&&mr==1&&r1==0&&l2==1&&r2==1) //l2,r2,ml,mr检测到
- ahead();
- if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
- ahead();
- }
- void xunji2()
- {
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //六个都没检测到黑线
- ahead();
- if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //l1检测到
- turn_right();
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0) //l2检测到
- turn_right();
- if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l1,l2,ml检测到
- ahead();
- if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l2,ml检测到
- turn_right();
- if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1) //r1,r2检测到
- turn_left();
- if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1) //mr,r2检测到
- turn_left();
- if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
- turn_left();
- if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
- turn_left();
- if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
- ahead();
- if(l1==1&&ml==1&&mr==1&&r1==0&&l2==1&&r2==0) //l1,l2,mr,ml检测到
- big_turn();
- if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
- turn_right();
- if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
- big_turn();
- bz++;
- }
- void xunji3()
- {
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //六个都没检测到黑线
- poahead();
- if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //l1检测到
- turn_right();
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0) //l2检测到
- turn_right();
- if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l1,l2,ml检测到
- turn_right();
- if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l2,ml检测到
- turn_right();
- if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1) //r1,r2检测到
- turn_left();
- if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1) //mr,r2检测到
- turn_left();
- if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
- turn_left();
- if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
- turn_left();
- if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
- turn_left();
- if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
- turn_right();
- if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
- poahead();
- bz++;
- }
- void xunji4()
- {
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //六个都没检测到黑线
- poahead();
- if(l1==1&&ml==0&&r1==0&&mr==0&&l2==0&&r2==0) //l1检测到
- turn_right();
- if(l1==0&&ml==0&&r1==0&&mr==0&&l2==1&&r2==0) //l2检测到
- turn_right();
- if(l1==1&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l1,l2,ml检测到
- poahead();
- if(l1==0&&ml==1&&r1==0&&mr==0&&l2==1&&r2==0) //l2,ml检测到
- turn_right();
- if(l1==0&&ml==0&&r1==1&&mr==0&&l2==0&&r2==1) //r1,r2检测到
- turn_left();
- if(l1==0&&ml==0&&r1==0&&mr==1&&l2==0&&r2==1) //mr,r2检测到
- turn_left();
- if(l1==0&&ml==0&&mr==0&&r1==1&&l2==0&&r2==0) //r1检测到
- turn_left();
- if(l1==0&&ml==0&&mr==1&&r1==0&&l2==0&&r2==1) //mr,r2检测到
- turn_left();
- if(l1==0&&ml==0&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr检测到
- poahead();
- if(l1==1&&ml==1&&mr==1&&r1==0&&l2==1&&r2==0) //l1,l2,mr,ml检测到
- poahead();
- if(l1==0&&ml==1&&mr==1&&r1==1&&l2==0&&r2==1) //r1,r2,mr,ml检测到
- poahead();
- if(l1==1&&ml==1&&mr==1&&r1==1&&l2==1&&r2==1) //六个都检测到
- stop();
- }
- /******mcu初始化*******/
- void mcu_init()
- {
- TMOD=0x11; // 设置定时器0和为工作方式1(0001 0001)
- TH0=(65536-PWM_CHUZHI)/256; //装初值
- TL0=(65536-PWM_CHUZHI)%256;
- TH1=(65536-50000)/256; //装初值(50ms溢出一次)
- TL1=(65536-50000)%256;
- EA=1; //开总中断
- ET0=1; //开定时器0中断
- ET1=1; //开定时器1中断
- TR0=1; //启动定时器0
- TR1=1; //启动定时器1
-
- IT0=1;
- IT1=1;
- EX0=1;
- EX1=1;
- En_L=1;
- En_R=1;
- ahead();
- }
- /*********main********/
- void main()
- {
- lcd_init(); //液晶初始化
- DelayMs(20);
- mcu_init(); //mcu初始化
- while(1)
- {
- switch(bz)
- {
- case 0: xunji1();break;
- case 1: xunji1();break;
- case 2: xunji1();break;
- case 3: xunji2();break;
- case 4: xunji2();break;
- case 5: xunji3();break;
- case 6: xunji4();break;
- default: xunji4();
- }
- if(count==20) //将分和秒的数值写进lcd
- {
- count=0;
- sec++;
- if(sec==60)
- {
- sec=0;
- min++;
- }
- write_fm(12,sec);
- write_fm(7,min);
- }
- }
- }
复制代码
注:小车选择上坡和过桥,不绕过障碍物
|
-
-
循迹小车.zip
36.3 KB, 下载次数: 27, 下载积分: 黑币 -5
循迹小车程序
评分
-
查看全部评分
|