求解决:在显示距离同时可以按键调整小车速度
完整程序如下:
#include<reg52.h>
#include<1602.h>
#include<pwm.h>
sfr T2MOD=0XC9;
sbit Trig = P2^0;
sbit Echo = P2^1;
/*void UsartConfiguration();
unsigned char i; */
sbit IN1 = P3^7;
sbit IN2 = P3^6;
sbit IN3 = P3^5;
sbit IN4 = P3^4;
/************函数声明**************/
void forword();
void back();
void right();
void left();
void stop();
unsigned char BiaoTi[]=" distance: ";
unsigned char code ShuZiBiao[15] = {'0','1','2','3','4','5','6','7','8','9','.','C','M'};
unsigned char XianShi[7] ={ 0,0,0,0,0,0,0};
//2、设定发送时间
void Delay10us()
{
T2MOD = 0; //---- --00 初始化模式寄存器 默认向上计数
T2CON = 0; //0000 0000 初始化控制寄存器 一个中断源,16位自动重装模式
TL2 = (65536 - 10) / 256; //设置定时初值
TH2 = (65536 - 10) % 256; //设置定时初值
RCAP2L = (65536 - 10) / 256; //设置定时重载值
RCAP2H = (65536 - 10) % 256; //设置定时重载值
TR2 = 1; //定时器2开始计时
IE = 0xA0; //打开全局中断,定时器2中断
while(!TF2);
TF2 = 0;
/* TMOD |= 0x01;
TH0 = 0xFF;
TL0 = 0xF6;
TR0 = 1;
while(!TF0);
TF0 = 0; */
}
void Rstart() //启动超声波模块,初始化
{
Trig=0;
Trig=1;
Delay10us();
Trig=0;
}
//3、获取时间和距离
int gettime()//获取时间
{
unsigned int time = 0;
time = TH2<<8 | TL2; //TH0*256+TL0
return time;
}
int Getdis(unsigned int time) //获取距离
{
unsigned int distance;//整型的原因是方便后续LCD1602屏显示
distance = (int)time * 0.085;
TH2=0;
TL2=0;//清空计时器·
return distance;
}
void star()
{
TH2 = 0;
TL2 = 0;
TR2 = 1;
}
void end()
{
TR2 = 0;
}
void GetOnce() //获取一次超声波测距模块的距离
{
Rstart();
while(!Echo);//当Echo为零时等待
star();
while(Echo);//当Echo为1计数并等待
end();
}
void delay()
{
int i;
int j;
for(i=0;i<50;i++)
for(j = 0;j<1000;j++);
}
void main()
{
unsigned int time = 0;
unsigned int i,j;
unsigned int dis;
timer0_init();
delayxms(5);
/* UsartConfiguration(); //串口初始化 */
while(1)
{
GetOnce();
time = gettime();
dis = Getdis(time);//单位毫米,后面会用厘米显示
XianShi[0]=dis/1000;//厘米的百位
XianShi[1]=(dis/100)%10;//厘米的十位
XianShi[2]=(dis/10)%10;//厘米的个位
XianShi[3]=10;//显示小数点
XianShi[4]=dis%10;//厘米的小数点后一位
XianShi[5]=11;//显示‘C’
XianShi[6]=12;//显示'M'
Lcd1602_init(); //初始化函数
Lcd1602_WriteCom(0x80); //0x80是第一行的第一个字符的地址
for (i=0;i<11;i++)
{
Lcd1602_WriteData(BiaoTi[i]);
}
Lcd1602_WriteCom(0x80+0x40); //0xc0是第二行的第一个字符的地址
for (j=0;j<7;j++)
{
Lcd1602_WriteData(ShuZiBiao[XianShi[j]]);
}
Motor_add_left();
Motor_dec_left();
Motor_add_right();
Motor_dec_right();
forword();
/* if(dis < 150)
{
back();
delay();
right();
}
else
{forword();} */
// 避障
/* i = SBUF;
RI = 0;
if(i == 'q')
{
forword();
}
if(i == 'h')
{
back();
}
if(i == 'z')
{
left();
}
if(i == 'y')
{
right();
}
if(i == 't')
{
stop();
} */
}
}
void forword() //前进函数
{
//第一路电机 正转
IN1 = 0;
IN2 = 1;
//第二路电机 正转
IN3 = 0;
IN4 = 1;
}
void back() //后退
{
//第一路电机 反转
IN1 = 1;
IN2 = 0;
//第二路电机 反转
IN3 = 1;
IN4 = 0;
}
void right() //右转
{
// 第一路正转
IN1 = 0;
IN2 = 1;
// 第二路反转
IN3 = 0;
IN4 = 0;
}
void left() //左拐函数
{
IN1 = 1;
IN2 = 0;
IN3 = 0;
IN4 = 1;
}
void stop()
{
IN1 = 0;
IN2 = 0;
IN3 = 0;
IN4 = 0;
}
/***********定时器0初始化***********/
void timer0_init()
{
TMOD=0x01; //定时器0工作于方式1
TH0=(65536-10)/256;
TL0=(65536-10)%256;
EA = 1;
ET0=1;
TR0=1;
}
/**************定时0中断处理******************/
void timer0_int() interrupt 1
{
TH0=(65536-10)/256;
TL0=(65536-10)%256;
TIME++;
m1 = countA;
m2 = countB;
if(TIME < m1) //count为占空比
{
ENA = 1; //输出高电平
}
else
{
ENA = 0;
}
if(TIME < m2)
{
ENB = 1;
}
else
{
ENB = 0;
}
if(TIME>=100)
{
TIME=0;
}
} |