当前位置:文档之家› 智能小车循迹,避障,红外遥控C语言知识学习代码

智能小车循迹,避障,红外遥控C语言知识学习代码

//智能小车避障、循迹、红外遥控C语言代码//实现功能有超声波避障,红外遥控智能小车,红外传感器实现小车自动循迹,1602显示小车的工作状态,另有三个独立按键分别控制三种状态的转换//注:每个小车的引脚配置都不一样,要注意引脚的配置,但是我的代码注释比较多,看起来比较容易一点#include <reg52.h>#include <math.h>#include"lcd.h"#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar ENCHAR_PuZh1[8]=" run ";//1602显示数组uchar ENCHAR_PuZh2[8]=" back ";uchar ENCHAR_PuZh3[8]=" stop ";uchar ENCHAR_PuZh4[8]=" left ";uchar ENCHAR_PuZh5[8]=" right ";uchar ENCHAR_PuZh6[8]=" xunji ";uchar ENCHAR_PuZh7[8]=" bizhang";uchar ENCHAR_PuZh8[8]=" yaokong";#define HW P2 //红外传感器引脚配置P2k口#define PWM P1 /* L298N管脚定义*//******************************超声波引脚控制******************************/sbit ECHO=P3^2; //超声波接收引脚定义兼红外遥控按键state_total =2 sbit TRIG=P3^3; //超声波发送引脚定义/////红外控制引脚配置sbit KEY2=P3^7; //红外接收器数据线兼循迹按键state_total= 0 sbit KEY1=P3^4; //独立按键p3.4控制自动避障state_total=1 uchar state_total=3,state_2=0;//总状态控制全局变量0为自动循迹模块1为自动避障模块2为红外遥控uchar state_1,DAT; //红外扫描标志位uchar time_1=0,time_2=0;//定时器1中断全局变量time_ 2控制PWM脉冲计数time_1控制转弯延时计数也做延时一次0.005suchar time,timeH,timeL,state=0;//超声波测量缓冲变量state为超声波状态检测控制全局变量uint count=0; //1602显示计数/**************************/unsigned char IRCOM[7]; //红外接收头接收数据缓存IRCOM[2]存放的为数据unsigned char Number,distance[4],date_data[8]={0,0,0,0,0,0,0,0}; //红外接收缓存变量/***********/void IRdelay(char x); //x*0.14MS 红外头专用delayvoid run();void 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; //设置定时器0 1 工作方式1 16位初值定时器TH1=0Xfe; //装入初值定时一次为0.0005s 2000hzTL1=0x0c;TF0=0; //定时器0方式1计数溢出标志TF1=0; //定时器1方式1计数溢出标志ET0=1; //允许定时器0中断溢出ET1=1; //允许定时器1中断溢出EA=1; //开总中断if(state_total==1)//为超声波模块时初始化{TRIG=0; //发射引脚低电平ECHO=0; // 接收引脚低电平EX0=0; //关闭外部中断IT0=1; //由高电平变低电平,触发外部中断0}if(state_total==2) //红外遥控初始化{ IT1=1; //外部中断1为负跳变触发EX1=1; //允许外部中断1TRIG=1; // 3.3为高电平I/O口初始化}delay(60); //等待硬件操作}void main(){ uint i;delay(50);init_test();TR1=1; //开启定时器1LCD1602_Init() ;delay(50);* * while(state_2==0){if(KEY1==0) //检测按键s1是否按下{Delay10ms(); //消除抖动if(KEY1==0){state_total=0; //总状态定义0为自动循迹模块1为自动避障模块2为红外遥控while((i<30)&&(KEY1==0)) //检测按键是否松开{Delay10ms();i++;}i=0;}}if(TRIG==0) //检测按键s2是否按下{Delay10ms(); //消除抖动if(TRIG==0){state_total=1; //总状态定义0为自动循迹模块1为自动避障模块2为红外遥控while((i<30)&&(TRIG==0)) //检测按键是否松开{Delay10ms();i++;}i=0;}}if(KEY2==0) //检测按键s3是否按下{Delay10ms(); //消除抖动if(KEY2==0){state_total=2; //总状态定义0为自动循迹模块1为自动避障模块2为红外遥控while((i<30)&&(KEY2==0)) //检测按键是否松开{Delay10ms();i++;}i=0;}}}init_test();delay(50); //等待硬件操作50usTR1=0; //关闭定时器1if(state_total==1){//SPEED=90; //自动循迹速度控制高电平持续次数占空比为10的低电平bizhang_test();}if(state_total==0){// SPEED=98; //自动循迹速度控制高电平持续次数占空比为40的低电平xunji_test();}if(state_total==2){//SPEED=98; //自动循迹速度控制高电平持续次数占空比为40的低电平hongwai_test();}}void init0_suspend(void) interrupt 0 //3 为定时器1的中断号 1 定时器0的中断号0 外部中断1 2 外部中断0 4 串口中断{timeH=TH0; //记录高电平次数timeL=TL0; //state=1; //标志状态为1,表示已接收到返回信号EX0=0; //关闭外部中断0}void time0_suspend0(void) interrupt 1 //3 为定时器1的中断号 1 定时器0的中断号0 外部中断1 2 外部中断0 4 串口中断{if(state_total==1) // 自动避障初值装入{ TH0=0X00; //装入初值TL0=0x00;}if(state_total==0) //自动循迹初值装入{ TH0=0Xec; //装入初值定时一次0.005s 200hzTL0=0x78;time_1++; //控制转弯延时计数}}void IR_IN(void) interrupt 2{unsigned char j,k,N=0;EX1 = 0;IRdelay(5);if (TRIG==1){ EX1 =1;return;}//确认IR信号出现while (!TRIG) //等IR变为高电平,跳过9ms的前导低电平信号。

{IRdelay(1);}for (j=0;j<4;j++) //收集四组数据{for (k=0;k<8;k++) //每组数据有8位{while (TRIG) //等IR 变为低电平,跳过4.5ms的前导高电平信号。

{IRdelay(1);}while (!TRIG) //等IR 变为高电平{IRdelay(1);}while (TRIG) //计算IR高电平时长{IRdelay(1);N++;if(N>=30){EX1=1;return;} //0.14ms计数过长自动离开。

} //高电平计数完毕IRCOM[j]=IRCOM[j] >> 1; //数据最高位补“0”if (N>=8) {IRCOM[j] = IRCOM[j] | 0x80;} //数据最高位补“1”N=0;}//end for k}//end for jif(IRCOM[2]!=~IRCOM[3]) //判断数据码与数据反码是否正确真确返回{ EX1=1;return;}EX1 = 1;}void time1_suspend1(void) interrupt 3 //3 为定时器1的中断号 1 定时器0的中断号0 外部中断1 2 外部中断0 4 串口中断{TH1=0Xec; //装入初值定时一次为0.0005s 2000hzTL1=0x78;time_2++; //控制PWM 脉冲计数if(state_total!=3) //判断进入按键是否按下进入状态1 避障或者0 循迹{state_2=1; //退出按键判断}/* if(time_2>100){time_2=0;}else if(time_2<=SPEED){PWM_g; //频率为2000hz的占空比为高电平的方波}else{ PWM_l; //为低电平} */}void IRdelay(unsigned char x) //x*0.14MS用于红外遥控{unsigned char i;while(x--){for (i = 0; i<13; i++) {}}}void Delay10ms(void) //用于按键检测误差{unsigned char a,b,c;for(c=1;c>0;c--)for(b=38;b>0;b--)for(a=130;a>0;a--);}void delay(uint dat) //延时函数用于初始化{* * uint i;for(i=dat;i>0;i--){_nop_();}}void delay_100ms(uint ms) //延时函数用于超声波{uint i,j;for(i=ms;i>0;i--)for(j=200;j>0;j--){_nop_();_nop_();_nop_();_nop_();_nop_();}}//小车前进void run(void){}//小车后退void back(void){PWM=0XA9;TR1=1;time_2=0;while(time_2<=100); //延时0.2sTR1=0;}//小车停止void stop(void){PWM=0X00;}//小车左转180void left_180(){//PWM=0X59; //左两轮反转,右两轮正转PWM=0X50; //右两轮正转TR1=1;while(time_2<=150); //延时0.2stime_2=0;while(time_2<=150); //延时0.2s}//小车左转90void left_90(void){PWM=0X59; //左两轮反转,右两轮正转//PWM=0X50; //右两轮正转TR0=1;time_1=0;while(time_1<=20); //延时0.2sTR0=0;}//小车左转120void left_120(void){PWM=0X59; //左两轮反转,右两轮正转// PWM=0X50; //右两轮正转TR0=1;while(time_1<=60); //延时0.4sTR0=0;}//小车右转90void right_90(void){PWM=0XA6; //左两轮正转右两轮反转//PWM=0X06; //左两轮正转TR0=1;time_1=0;while(time_1<=20); //延时0.2sTR0=0;}//小车右转120void right_120(void){PWM=0XA6; //左两轮正转右两轮反转// PWM=0X06; //左两轮正转TR0=1;time_1=0;while(time_1<=60); //延时0.4s}/************************************自动避障模块************************************/void display(uchar temp) //判断障碍距离小车的距离,左转180,前进,峰呤器报警1602显示{ uint ge,shi,bai,i;if((temp<=20)&&(temp>2)) //小于15厘米小车后退再左转{back();left_180();}if(count>=20){bai=temp/100; //1602显示数据date_data[5]=bai;shi=(temp%100)/10;date_data [6]=shi;ge=temp%100%10;date_data[7]=ge;for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(date_data[i]+48);}count=0;}}void bizhang_test(){ int i,j=0;uchar distance_dat;delay(50);for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh7[i]);}while(1){run();EA=0; //关总中断TRIG=1; // 发射20us脉冲信号delay(30);TRIG=0;while(ECHO==0); //等待接收信号state=0; //标志清零EA=1; //开总中断EX0=1; //打开外部中断0 P3.2外部中断0引脚此时为高电平TH0=0x00; //定时器0 初值TL0=0x00;TF0=0; // 定时器0方式1计数溢出标志TR0=1; // 定时器0方式1启动定时器1while(state!=1);EX0=0; // 关闭外部中断0TR0=0; // 关闭定时器0中断TF0=0; // 定时器1方式1计数溢出标志if(state==1) //检测到障碍物计算离障碍物的距离{time=(timeH*4.352+timeL*0.017); //设定超声波的速度为340m/s 定时计数一次1usdistance_dat=time;}else //未检测到障碍物无返回信号{distance_dat=0;}distance[j]=distance_dat;j++;if(j==3){ if(distance[0]>distance[1]) {}else{distance[0]=distance[1];}if(distance[0]>distance[2]){}else{distance[0]=distance[2];}if(distance[0]>distance[3]){}else{distance[0]=distance[3];}distance_dat=distance[0];j=0;display(distance_dat);}count++;}}void xunji_test(){ int i;delay(50);for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh6[i]);}while(1){// delay(10);state_1=HW;DAT=state_1&(0x0f); //判断低4位的状态每隔5ms检测一次switch(DAT){case 0x00:run();break;case 0x01:right_120();break;case 0x02:right_90();break;case 0x04:left_90();break;case 0x06:run();break;case 0x03:right_120();break;case 0x08:left_120();break;case 0x0c:left_120();break;default:run();break;}}}void hongwai_test(){ int i;delay(60);for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh8[i]);}// TR1=1;while(1){Number=IRCOM[2];switch(Number){case 0x18:PWM=0X56; //前进for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh1[i]);}break;case 0x08:PWM=0X50; //右两轮正转左转for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh4[i]);}break;case 0x1c:PWM=0X00;for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh3[i]);}break;case 0x5a:PWM=0X06; //左两轮正转右转for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh5[i]);}break;case 0x52:PWM=0XA9; //后退for(i=0;i<8;i++){LCD1602_WriteCom(0x80+i);LCD1602_WriteData(ENCHAR_PuZh2[i]);}break;default:break;}//display(IRCOM[2]);}}。

相关主题