项目四 智能小车
项目四 智能小车
实现串口通信控制小车
通过手机的蓝牙助手软件,给蓝牙发送信息,蓝牙接收到信息再通过串口传给单片机。
//串口中断函数
void uart_func() interrupt 4
{
	char tmp;
	//定义一个局部静态变量
	static char i = 0;
	if(RI)
	{
		//清空标志位
		RI = 0;
		tmp = SBUF;
		if(tmp == 'b' || tmp == 'g' || tmp == 'r' || tmp == 'l')
		{
			i = 0;
		}
		*(buffer+i) = tmp;
		i++;
		if((*buffer) == 'b' && (*(buffer+1)) == 'a')
		{
			make = 1;
			myMemset(buffer);
		}
		if((*buffer) == 'g' && (*(buffer+1)) == 'o')
		{
			make = 2;
			myMemset(buffer);
		}
		if((*buffer) == 'r' && (*(buffer+1)) == 'i')
		{
			make = 3;
			myMemset(buffer);
		}
		if((*buffer) == 'l' && (*(buffer+1)) == 'e')
		{
			make = 4;
			myMemset(buffer);
		}
		
		if(i == 12)
		{
			i = 0;
		}
	}
	if(TI);
}
51单片机串口接收到数据后进行检索,当收到想要的字符串后,会将标志位make进行修改,在main函数中会对make变量进行操作。
main函数
switch(make)
		{
			//make = 1 表示后退
			case 1:
				CarBack();
				Delay30ms();
				make = 0;
				break;
			//make = 2 表示前进
			case 2:
				CarGo();
				Delay30ms();
				make = 0;
				break;
			//make = 3 表示右转
			case 3:
				CarRight();
				Delay30ms();
				make = 0;
				break;
			//make = 4 表示右转
			case 4:
				CarLeft();
				Delay30ms();
				make = 0;
				break;
			//否则小车不动
			default :
				CarStop();
				break;
		}
串口有数据进来,首先会进入串口中断函数,对make的值进行修改,出来中断函数后,会进入main函数,根据make的值,对电机进行操作。
1.小车PWM调速
通过PWM进行调速就是对输出功率的一个改变,假设一个周期是20ms,有15ms的时间是前进,5ms的时间时间停止,那么输出的功率就是全功率的3/4。从而导致速度下降,因为只有5ms的停止时间,由于惯性的原因,必不会看到小车停止,只是速度降低。
void time0_func() interrupt 1
{
	//cnt记录进来的次数
	cnt++;
	//重新装初值 5ms进来一次
	TL0 = 0x00;
	TH0 = 0xEE;
	if(cnt < speed)
	{
		//小车前进
		CarGo();
	}
	else
	{
		//小车后退
		CarStop();
	}
	//进来4次为20ms 一个周期,进行下一个周期
	if(cnt == 4)
	{
		cnt = 0;
		CarGo();
	}
}
与控制舵机的当时类似
2.PWM对小车左右电机单独调速
与一下对小车两个轮子调速的方法类似,需要用到两个定时器同时工作(定时0和定时器1),定时器0负责控制左轮的速度,定时器1负责控制右轮的速度,两个轮子速度一快一慢从未实现小车的转弯。
循迹小车的实现
循迹模块的使用
TCR5000传感器的红外发射二级管不断发射红外线
当发射的红外线没有被返回来或者被返回来但是强度不够大时候
红外接收管一直处于关断状态,起始模块输出端为高电平,指示二极管一直处于熄灭状态
被检测物体出现在检测范围内时,红外线被反射回来且强度足够大,红外接收管饱和,
此时模块的输出端为低电平,指示二极管被点亮
总结就是,没有反射回来发出的红外线,输出就是高电平,灯灭。
循迹小车原理
由于黑色具有较强的吸收能力,当循迹模块发射的红外线照射到黑线时,红外线将会被黑线吸收,导致循迹模块上光敏三极管处于关闭状态,此时模块上一个LED熄灭。在没有检测到黑线时,模块上两个LED常亮。
总结就是,检测到黑线就输出高电平,灯灭。

在左右循迹模块都输出低电平的时候,小车直走,当左侧的循迹模块输出为高点平时(碰到黑线),向左转弯,右侧的循迹模块输出为高电平时(碰到黑线),小车向右转弯。
代码
sbit leftSensor  = P1^4;
sbit rightSensor = P1^5;
while(1)
	{
		if(leftSensor == 1 && rightSensor == 1)
		{
			speedLeft = 0;
			speedRight = 0;
		}
		if(leftSensor == 1 && rightSensor == 0)
		{
			speedLeft= 2;
			speedRight = 4;
		}
		if(leftSensor == 0 && rightSensor == 1)
		{
			speedLeft = 4;
			speedRight = 2;
		}
		if(leftSensor == 0 && rightSensor == 0)
		{
			speedLeft = 4;
			speedRight = 4;
		}
	}
这里采用的是使用PWM波控制小车的转弯,实现让小车转弯更平滑。分别使用了定时器0和定时器1单独的控制小车的两个轮子。
跟随小车的实现
与循迹模块的原理是一样的,如果发送红外线返回来了,输出的是低电平,如果没有回来输出的是高电平。
当左边输出的高电平,右边输出的是低电平,说明右边有人,小车右转
当右边输出的高电平,左边输出的是低电平,说明左边有人,小车左转
小车测速
测速模块的原理
有遮挡、输出高电平。无遮挡、输出低电平。
轮子走一圈的周长是:3.14*6.5 cm
一圈内一共有20个小格子平均分布,也就是说轮子走一圈会产生20个脉冲
一个脉冲对应的是 3.14*6.5/20  = 1.0205cm 一个脉冲相当于走了大约1cm
那么只需要统计 1s 内单片机接收了多少个脉冲(下降沿) ,就可以计算1s内走的总路程是多少。
oled显示小车的速度
1.用取模软件得到要显示的字符
2.创建字符数组
3.可以用一个指针数组保存字符数组名,数组名就是数组首元素的地址
4.用指针数组访问字符数组中的各个元素,减少main函数的代码量
/*--  文字:  s  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
code char s1[8] = {0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00};
code char s2[8] = {0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00};
/*--  文字:  p  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
code char p1[8] = {0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00};
code char p2[8] = {0x80,0xFF,0x91,0x20,0x20,0x11,0x0E,0x00};
/*--  文字:  e  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
code char e1[8] = {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00};
code char e2[8] = {0x00,0x1F,0x24,0x24,0x24,0x24,0x17,0x00};
/*--  文字:  e  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
code char e11[8] = {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00};
code char e22[8] = {0x00,0x1F,0x24,0x24,0x24,0x24,0x17,0x00};
/*--  文字:  d  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
code char d1[8] = {0x00,0x00,0x80,0x80,0x80,0x90,0xF0,0x00};
code char d2[8] = {0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20};
/*--  文字:  :  --*/
/*--  宋体12;  此字体下对应的点阵为:宽x高=8x16   --*/
code char sym1[8] = {0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00};
code char sym2[8] = {0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00};
char* pointArr1[6] = {s1,p1,e1,e11,d1,sym1};
char* pointArr2[6] = {s2,p2,e2,e22,d2,sym2};
*pointArr 就是 数组s1 的首元素的地址
**pointArr 是数组s1 的首元素
语音识别的实现
配置SU—03T语音模块网址 http://www.smartpi.cn/#/
在上面网址上配置好语音模块后,下载SDK,烧入语音模块即可。
接线方式:
- B6 :接串口工具的TX
- B7:接串口工具的RX
要注意下载SDK的路径不可以为中文
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号