- <避障小车的问题,在实物中小车不动
- #include<reg52.h> //此文件中定义了单片机的一些特殊功能寄存器
- #include"lcd.h"
- #include<intrins.h>
- #define uchar unsigned char //无符号字符型 宏定义 变量范围0~255
- #define uint unsigned int //无符号整型 宏定义 变量范围0~65535
- /***************超声波**I/O口******************/
- sbit Trig = P2^3; //超声波测距模块Trig
- sbit Echo = P2^4; //超声波测距模块Echo
- /*****************蜂鸣器******************/
- sbit beep = P2^7; //蜂鸣器
- /*****************舵机******************/
- sbit SG_PWM = P3^7; //舵机
- /****************电机驱动**IO口******************/
- /*使能端*/
- sbit ENA = P2^5; //左下电机pwm信号端
- sbit ENB = P2^6; //右下电机pwm信号端
- sbit ENC = P3^0; //左上电机pwm信号端
- sbit END = P3^1; //右上电机pwm信号端
- /*电机口*/
- sbit IN1 = P1^0;
- sbit IN2 = P1^1;
- sbit IN3 = P1^2;
- sbit IN4 = P1^3;
- sbit IN5 = P1^4;
- sbit IN6 = P1^5;
- sbit IN7 = P1^6;
- sbit IN8 = P1^7;
- /***************定义全局变量******************/
- static unsigned char DisNum = 0; //显示用指针
- unsigned char table[]="Distance:";
- unsigned char code ASCII[13] = {'0','1','2','3','4','5','6','7','8','9','.','-','M',};
- unsigned int time=0; //用于存放定时器时间的值
- unsigned long S=0; //用于存放距离的值
- unsigned long S1=0;
- unsigned long S2=0;
- unsigned long S3=0;
- unsigned int timer=10000; //延时基准变量
- bit flag =0; //超声波超出量程溢出标志位
- unsigned char disbuff[4] = { 0,0,0,0,}; //用于存放距离的值0.1mm、mm、cm和m的值
- unsigned char pwm_val_left1 = 0; //左下电机变量定义
- unsigned char pwm_val_right1 =0; //右下电机变量定义
- unsigned char pwm_val_left2 = 0; //左上电机变量定义
- unsigned char pwm_val_right2 = 0; //右下电机变量定义
- unsigned char push_val_left1 = 0; //左下电机占空比N/20
- unsigned char push_val_right1 =0; //右下电机占空比N/20
- unsigned char push_val_left2 = 0; //左上电机占空比N/20
- unsigned char push_val_right2 = 0; //右下电机占空比N/20
- unsigned char count=0; //0.2ms次数标识
- unsigned char PWM_count=5; //舵机归中
- /******************************************************************************
- * 函 数 名 : Delay1ms
- * 函数功能 : 延时函数,延时1ms
- *******************************************************************************/
- void Delay1ms(uint j)
- {
- uchar k;
- while(j--)
- {
- for(k = 120; k > 0; k--);
- }
- }
- /******************************************************************************
- * 函 数 名 : feng
- * 函数功能 : 报警函数
- *******************************************************************************/
- void feng()
- {
- if(S<=40)
- {
- beep=~beep;
- Delay1ms(50);
- }
- else
- beep=1;
- }
- void StartModule() //启动模块
- {
- Trig=1; //启动一次模块
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- Trig=0;
- }
- //计算距离
- void Conut(void)
- {
- TH0=0;
- TL0=0;
- while(!Echo); //当RX为零时等待
- TR0=1; //开启计数
- while(Echo); //当RX为1计数并等待
- TR0=0; //关闭计数
- time=TH0*256+TL0;
- TH0=0;
- TL0=0;
-
- S=(time*1.7)/100; //算出来是CM
- if((S>=450)||flag==1) //超出测量范围显示“-”
- {
- flag=0;
-
- DisplayOneChar(10, 0, ASCII[11]);
- DisplayOneChar(11, 0, ASCII[10]); //显示点
- DisplayOneChar(12, 0, ASCII[11]);
- DisplayOneChar(13, 0, ASCII[11]);
- DisplayOneChar(14, 0, ASCII[12]); //显示M
- }
- else
- {
- disbuff[0]=S%1000/100;
- disbuff[1]=S%1000%100/10;
- disbuff[2]=S%1000%10 %10;
- DisplayOneChar(10, 0, ASCII[disbuff[0]]);
- DisplayOneChar(11, 0, ASCII[10]); //显示点
- DisplayOneChar(12, 0, ASCII[disbuff[1]]);
- DisplayOneChar(13, 0, ASCII[disbuff[2]]);
- DisplayOneChar(14, 0, ASCII[12]); //显示M
- }
- }
- void Timer0() interrupt 1 //T0中断用来计数器溢出,超过测距范围
- {
- flag=1; //中断溢出标志
- }
- void run(void) //前进
- {
- push_val_left1 = 10; //PWM 调节参数1-20 1为最慢,20是最快 改这个值可以改变其速度
- push_val_right1 = 10;
- push_val_left2 = 10;
- push_val_right2 = 10;
- IN1 = 1;
- IN2 = 0;
- IN3 = 1;
- IN4 = 0;
- IN5 = 1;
- IN6 = 0;
- IN7 = 1;
- IN8 = 0;
- }
- void backrun(void) //后退
- {
- push_val_left1 = 8; //PWM 调节参数1-20 1为最慢,20是最快 改这个值可以改变其速度
- push_val_right1 = 8;
- push_val_left2 = 8;
- push_val_right2 = 8;
- IN1 = 0;
- IN2 = 1;
- IN3 = 0;
- IN4 = 1;
- IN5 = 0;
- IN6 = 1;
- IN7 = 0;
- IN8 = 1;
- }
- void leftrun(void) //左转
- {
- push_val_left1 = 7; //PWM 调节参数1-20 1为最慢,20是最快 改这个值可以改变其速度
- push_val_right1 = 7;
- push_val_left2 = 7;
- push_val_right2 = 7;
- IN1 = 0;
- IN2 = 0;
- IN3 = 1;
- IN4 = 0;
- IN5 = 0;
- IN6 = 0;
- IN7 = 1;
- IN8 = 0;
- }
- void rightrun(void) //右转
- {
- push_val_left1 = 7; //PWM 调节参数1-20 1为最慢,20是最快 改这个值可以改变其速度
- push_val_right1 = 7;
- push_val_left2 = 7;
- push_val_right2 = 7;
- IN1 = 1;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0;
- IN5 = 1;
- IN6 = 0;
- IN7 = 0;
- IN8 = 0;
- }
- void stop(void) //停止
- {
- IN1 = 0;
- IN2 = 0;
- IN3 = 0;
- IN4 = 0;
- IN5 = 0;
- IN6 = 0;
- IN7 = 0;
- IN8 = 0;
- }
- //pwm控制电机速度
- void pwm_out_left1_moto(void) //左下电机
- {
- if(pwm_val_left1<=push_val_left1)
- ENA=1;
- else
- ENA=0;
- if(pwm_val_left1>=20)
- pwm_val_left1=0;
- else
- ENA=0;
- }
- void pwm_out_right1_moto(void) //右下电机
- {
- if(pwm_val_right1<=push_val_right1)
- ENB=1;
- else
- ENB=0;
- if(pwm_val_right1>=20)
- pwm_val_right1=0;
- else
- ENB=0;
- }
- void pwm_out_left2_moto(void) //左上电机
- {
- if(pwm_val_left2<=push_val_left2)
- ENC=1;
- else
- ENC=0;
- if(pwm_val_left2>=20)
- pwm_val_left2=0;
- else
- ENC=0;
- }
- void pwm_out_right2_moto(void) //右上电机
- {
- if(pwm_val_right2<=push_val_right2)
- END=1;
- else
- END=0;
- if(pwm_val_right2>=20)
- pwm_val_right2=0;
- else
- END=0;
- }
- void timer1 () interrupt 3 //中断产生pwm信号
- {
- TH1=0xFC;
- TL1=0x18; //1ms延时
- pwm_val_left1++;
- pwm_val_right1++;
- pwm_val_left2++;
- pwm_val_right2++;
- pwm_out_left1_moto();
- pwm_out_right1_moto();
- pwm_out_left2_moto();
- pwm_out_right2_moto();
- }
- //舵机控制方向函数
- void COMM(void)
- {
- count=1; //舵机向左转90度
- Delay1ms(1000); //延时1000ms让舵机转到位置
- StartModule(); //启动测距
- Conut();
- S2=S; //得到左边距离
- count=9; //舵机右转
- Delay1ms(1000); //延时1000ms让舵机转到位置
- StartModule(); //启动测距
- Conut();
- S3=S; //得到右边距离
- count=5; //舵机归中
- Delay1ms(1000); //延时1000ms让舵机转到位置
- StartModule(); //启动测距
- Conut();
- S1=S; //得到中间距离
- if((S2<10)||(S3<10)) //只要左右各有距离小于10CM小车后退
- {
- backrun();
- Delay1ms(1000);
- }
- if(S2>S3) //车的左边比车的右边距离小右转
- {
- rightrun();
- Delay1ms(1000);
- }
- else //车的左边比车的右边距离大 左转
- {
- leftrun();
- Delay1ms(1000);
- }
- }
- void Timer2() interrupt 5
- {
- TF2=0;
- TH2=(65536-200)>>8;
- TL2=(65536-200);
- count=count+1;
-
- if(count >100)
- {
-
- count = 0;
- }
- if(count<=compare)
- {
- SG_PWM=1;
- }
- else
- {
- SG_PWM=0;
- } //次数始终保持为40即保持周期为20ms
- }
- /***************初始化定时器************/
- void init_T0()
- {
- TMOD=0x01; //设T0为方式1,GATE=1;
- TH0=0;
- TL0=0;
- ET0=1; //允许T0中断
- EA=1; //开启总中断
- }
- void init_T1()
- {
- TMOD=0x11; //设T1为方式1,GATE=1;
- TH1=0xFC;
- TL1=0x18; //1ms延时
- ET1=1; //允许T1中断
- EA=1; //开启总中断
- TR1=1; //t1开启及时
- }
- void init_T2()
- {
- T2CON=0;
- TH2=0xfe;
- TL2=0x0c; //0.5ms
- ET2=1; //允许T1中断
- EA=1; //开启总中断
- TR2=1; //t2开启及时
- }
- void main()
- {
- init_T0();
- init_T1();
- init_T2();
-
- LcdInit();
- LcdShowStr(0,0,table);
- Delay1ms(5);
- count=5;
- while(1)
- {
- StartModule();
- Conut();
- feng();
- if(S<=10)
- {
- stop();
- COMM();
- }
- else
- {
- run();
- }
- }
- }
复制代码
|