标题:
求大佬看下单片机程序的问题,在实物中小车不动
[打印本页]
作者:
我是靴子
时间:
2020-5-23 22:50
标题:
求大佬看下单片机程序的问题,在实物中小车不动
<避障小车的问题,在实物中小车不动
#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();
}
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1