STC89C51基础及项目第15天:小车测速、添加语言识别控制

1. 小车测速的原理(281.126)

测速模块

STC89C51基础及项目第15天:小车测速、添加语言识别控制_第1张图片

  • 用途:
    • 广泛用于电机转速检测,脉冲计数,位置限位等。
  • 逻辑:
    • 有遮挡,输出高电平;无遮挡,输出低电平
  • 接线
    • VCC 接电源正极 3.3 - 5V
    • GND 接电源负极
    • DO TTL开关信号输出
    • AO 此模块不起作用

测试原理和单位换算

  • 轮子走一圈经过一个周长,C = 2 x 3.14 x 半径 = 3.14 x 直径(6.5cm)
  • 对应的码盘也转了一圈。码盘有20个格子,每经过一个格子,会遮挡(高电平)和不遮挡(低电平)
  • 那么一个脉冲就是走了 3.14 x 6.5 cm /20 = 1.0205cm
  • 定时器可以设计成一秒,统计一秒内的脉冲数,一个脉冲就是 1cm
  • 假设一秒有 80 脉冲,那么就是 80cm/s

2. 小车测速代码实现(282.127)

  • 代码(20./11. 测速数据通过串口发送到上位机01)
#include "motor.h"
#include "delay.h"
#include "uart.h"
#include "reg52.h"
#include "timer.h"


sbit speedIO = P3^2;		   //外部中断0
unsigned int speedCnt = 0; //统计格子,脉冲次数
extern unsigned int speed; //速度
extern char signal;			   //主程序1s后可以发速度数据的信号

void Ex0Init(){
	EX0 = 1;//允许中断
	//EA = 1;在串口初始化函数中已经打开了总中断
	IT0 = 1;//外部中断的下降沿触发
}

void main(){
	Timer0Init();
	UartInit();//串口相关初始化
	Ex0Init(); //外部中断初始化

	while(1){
		if(signal){//定时器1s到点,把signal置一,主程序发送速度
			SendString("speed:");
			SendByte(speed);//速度发出去//用sendByte不合理
			signal = 0;//清0
		}
	}
}

void speedHelper() interrupt 0{//下降沿触发,即轮子转的时候产生高电平再到低电平//外部中断处理函数
	speedCnt++;//码盘转动了一个格子
}
  • SendByte(speed) 并不合理,应该这么做:
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第2张图片

3. 小车测速代码验证和BUG修改(283.128)

  • 代码(20./11. 测速数据通过串口发送到上位机02)
#include "motor.h"
#include "delay.h"
#include "uart.h"
#include "reg52.h"
#include "timer.h"
#include "stdio.h"

sbit speedIO = P3^2;		   //外部中断0
unsigned int speedCnt = 0; //统计格子,脉冲次数
extern unsigned int speed; //速度
extern char signal;			   //主程序发速度数据的信号
char speedMes[24];  			 //主程序发速度数据的字符串缓冲区

void Ex0Init(){
	EX0 = 1;//允许中断
	//EA = 1;在串口初始化函数中已经打开了总中断
	IT0 = 1;//外部中断的下降沿触发
}

void main(){
	Timer0Init();
	UartInit();//串口相关初始化
	Ex0Init(); //外部中断初始化

	while(1){
		if(signal){//定时器1s到点,把signal置一,主程序发送速度
			sprintf(speedMes,"speed:%d cm/s",speed);//字符串拼装,speed的值格式化为字符串,写入speedMes字符串缓冲区
			SendString(speedMes);//速度发出去
			signal = 0;//清0
		}
	}
}

void speedHelper() interrupt 0{//下降沿触发,即轮子转的时候产生高电平再到低电平//外部中断处理函数
	speedCnt++;//码盘转动了一个格子
}

4. OLED二次开发为了显速度(284.129)

  • 代码(20./12. OLED代码二次开发)
#include "reg52.h"
#include "intrins.h"
#include "OLED.h"

void main(){
	Oled_Init();
	Oled_Clear();
	Oled_Show_Str(2,2,"speed:35cm/s");
	
	while(1);//不让程序结束
}

5. 蓝乐控制且OLED和蓝牙显示速度(285.130)

  • 代码(20./13. 蓝牙测速并本地显示的小车)
#include "motor.h"
#include "delay.h"
#include "uart.h"
#include "reg52.h"
#include "timer.h"
#include "stdio.h"
#include "OLED.h"


sbit speedIO = P3^2;		   //外部中断0
unsigned int speedCnt = 0; //统计格子,脉冲次数
extern unsigned int speed; //速度
extern char signal;			   //主程序发速度数据的信号
char speedMes[24];  			 //主程序发速度数据的字符串缓冲区

void Ex0Init(){
	EX0 = 1;//允许中断
	//EA = 1;在串口初始化函数中已经打开了总中断
	IT0 = 1;//外部中断的下降沿触发
}

void main(){
	Timer0Init();
	UartInit();//串口相关初始化
	Ex0Init(); //外部中断初始化
	Oled_Init();
  Oled_Clear();
	while(1){
		if(signal){//定时器1s到点,把signal置一,主程序发送速度
			sprintf(speedMes,"speed:%d cm/s",speed);//字符串拼装,speed的值格式化为字符串,写入speedMes字符串缓冲区
			SendString(speedMes);//速度发出去
			signal = 0;//清0
			Oled_Show_Str(2,2,speedMes);
		}
	}
}

void speedHelper() interrupt 0{//下降沿触发,即轮子转的时候产生高电平再到低电平//外部中断处理函数
	speedCnt++;//码盘转动了一个格子
}

6. wifi控制小车并发送速度(286.131)

  • 代码(20./14. wifi测速并本地显示的小车)
#include "motor.h"
#include "delay.h"
#include "uart.h"
#include "reg52.h"
#include "timer.h"
#include "stdio.h"
#include "OLED.h"
#include "esp8266.h"

sbit speedIO = P3^2;		   //外部中断0
unsigned int speedCnt = 0; //统计格子,脉冲次数
extern unsigned int speed; //速度
extern char signal;			   //主程序发速度数据的信号
char speedMes[24];  			 //主程序发速度数据的字符串缓冲区
//4 发送数据
code char sendData [] = "AT+CIPSEND=0,6\r\n";

void Ex0Init(){
	EX0 = 1;//允许中断
	//EA = 1;在串口初始化函数中已经打开了总中断
	IT0 = 1;//外部中断的下降沿触发
}

void main(){
	Timer0Init();
	UartInit();//串口相关初始化
	
	Delay1000ms();//给espwifi模块上电时间
	initWifi_AP();//初始化wifi工作在ap模式
	waitConnect();//等待客户端的连接
	
	Ex0Init();    //外部中断初始化
	Oled_Init();  //oled初始化
  Oled_Clear(); //OLED清屏
	while(1){
		if(signal){//定时器1s到点,把signal置一,主程序发送速度		
			SendString(sendData);//4 发送数据
			Delay1000ms();
			sprintf(speedMes,"speed:%d cm/s",speed);//字符串拼装,speed的值格式化为字符串,写入speedMes字符串缓冲区
			SendString(speedMes);//速度发出去
			signal = 0;//清0
			Oled_Show_Str(2,2,speedMes);
		}
	}
}

void speedHelper() interrupt 0{//下降沿触发,即轮子转的时候产生高电平再到低电平//外部中断处理函数
	speedCnt++;//码盘转动了一个格子
}

7. 4g模块控制小车(287.132)

  • 代码不做修改,直接复制蓝牙测速小车
  • 4g 模块只要做好内网穿透外网透传就可以了
  • 代码(20./15. 4g模块控制小车)

8. 非特定语音识别方案介绍(~.133)

  • SU-03T(还有 LD3320)
  • 购买地址:https://item.taobao.com/item.htm?spm=a1z09.2.0.0.4c9d2e8d7NyISY&id=660663988887&_u=nbdq6ut5ec8
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第3张图片
  • 此语音模块不需编程,不需二次开发:通过厂家给的网站配置后即可使用,傻瓜式操作
  • 想要稍微开发点语音相关代码,LD3320 模块需要二次开发,根据厂家给的源码并二次开发添加识别词条

9. SU-03T语音模块的配置使用(~.134)

  • 非特定人语音识别特征提取算法的研究
    • https://xueshu.baidu.com/usercenter/paper/show?paperid=1c530gm02v7400n0er5g08m07n159657
  1. 进入官网,注册并登陆

    • http://www.smartpi.cn/#/
  2. 创建产品

    • 其他产品、纯离线方案、SU-03T、名称、中文、下一步
      STC89C51基础及项目第15天:小车测速、添加语言识别控制_第4张图片
  3. Pin脚配置

    • A25-A27 改为默认高电平
      STC89C51基础及项目第15天:小车测速、添加语言识别控制_第5张图片
  4. 唤醒词自定义和唤醒回复配置
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第6张图片

  5. 命令词自定义
    1)“基础信息”配置
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第7张图片
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第8张图片

    2)“控制详情”配置:添加控制
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第9张图片
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第10张图片
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第11张图片

3)“识别灵敏度”配置:中
STC89C51基础及项目第15天:小车测速、添加语言识别控制_第12张图片
6. 发音人配置
STC89C51基础及项目第15天:小车测速、添加语言识别控制_第13张图片
7. 其他配置
STC89C51基础及项目第15天:小车测速、添加语言识别控制_第14张图片
8. 发布版本
STC89C51基础及项目第15天:小车测速、添加语言识别控制_第15张图片
9. 半小时左右后下载sdk固件
STC89C51基础及项目第15天:小车测速、添加语言识别控制_第16张图片
STC89C51基础及项目第15天:小车测速、添加语言识别控制_第17张图片

10. SU-03T固件烧录并语音识别测试(288.135)

  • 提前做 语言模块和 ttl 的接线:
    • B7 引脚 接 串口工具 RXD
    • B6 引脚 接 串口工具 TXD
    • GND 接 串口工具 GND
    • VCC 接 串口工具 5V
  1. 将上节课生成的文件解压
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第18张图片
  2. 将解压后的文件夹放至非中文路径下、以管理员身份打开 “UniOneUpdateTool.exe” 文件
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第19张图片
  3. 将 usb-ttl 插入电脑接口
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第20张图片
  4. 打开软件,选择镜像文件 “uni_app_release_update.bin”
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第21张图片
  5. 下电至 OFF
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第22张图片
  6. 点“烧录”
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第23张图片
  7. 上电至 ON
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第24张图片
  8. 开始烧录
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第25张图片
  9. 下载完成,烧录结束
    STC89C51基础及项目第15天:小车测速、添加语言识别控制_第26张图片
  10. 即可进行语音测试

11. 语音识别切换小车循迹避障跟随且OLED显示状态(289.136)

  • 代码(20./16. 语音识别切换小车寻迹避障跟随并oled显示)
#include "reg52.h"
#include "hc04.h"
#include "delay.h"
#include "sg90.h"
#include "motor.h"
#include "OLED.h"

#define MIDDLE 0
#define LEFT 1
#define RIGHT 2

#define XJ 3
#define GS 4
#define BZ 5
#define ST 6

sbit A25 = P1^5;
sbit A26 = P1^6;
sbit A27 = P1^7;

sbit leftSensorXJ = P2^7;
sbit rightSensorXJ = P2^6;

sbit leftSensorGS = P2^5;
sbit rightSensorGS = P2^4;

char dir;
double disMiddle;
double disLeft;
double disRight;

void xunjiMode(){
	if(leftSensorXJ == 0 && rightSensorXJ == 0){//左右都反射回来,都低电平,直走,灯都亮
		goForward();
	}
	
	if(leftSensorXJ == 1 && rightSensorXJ == 0){//左边没反射回来,左高电平,左转,右灯亮
		goLeft();
	}	
	
	if(leftSensorXJ == 0 && rightSensorXJ == 1){//右边没反射回来,右高电平,右转,左灯亮
		goRight();
	}
		
	if(leftSensorXJ == 1 && rightSensorXJ == 1){//左右都没反射回来,都高电平,停,灯都不亮
		stop();
	}
}

void gensuiMode(){
	if(leftSensorGS == 0 && rightSensorGS == 0){//两边都反射回来了,都低电平,直走
		goForward();
	}
	
	if(leftSensorGS == 1 && rightSensorGS == 0){//右边反射回来了,右低电平,右转
		goRight();
	}
		
	if(leftSensorGS == 0 && rightSensorGS == 1){//左边反射回来了,左低电平,左转
		goLeft();
	}
		
	if(leftSensorGS == 1 && rightSensorGS == 1){//两边都没反射回来,都高电平,停
		stop();
	}
}

void bizhangMode(){
	if(dir != MIDDLE){
		sgMiddle();
		dir = MIDDLE;
		Delay300ms();
	}
		disMiddle = getDistance();
			
		if(disMiddle > 35){
				//前进
			goForward();
		}else if(disMiddle < 10){
			goBack();
		}else{
			//停止
			stop();
			//sg左转 测左边距离
			sgLeft();
			Delay300ms();
			disLeft = getDistance();
				
			sgMiddle();
			Delay300ms();
				
			//sg右转 测右边距离
			sgRight();
			dir = RIGHT;
			Delay300ms();
			disRight = getDistance();
				
			if(disLeft < disRight){
				goRight();
				Delay150ms();
				stop();
			}
			if(disLeft > disRight){
				goLeft();
				Delay150ms();
				stop();
			}
		}
}

void main(){
	int mark = 0;
	
	Timer0Init();//定时器0初始化(为舵机)
	Timer1Init();//定时器1初始化(为超声波测距)
	sgMiddle();  //舵机初始化位置(避障)
	Delay2000ms();
	dir = MIDDLE;

	Oled_Init(); //OLED初始化
	Oled_Clear();
	Oled_Show_Str(2,2,"-----Ready----");
	
	while(1){
		//满足寻迹模式的条件
		if(A25 == 0 && A26 == 1 && A27 == 1){
			if(mark != XJ){
				Oled_Clear();
				Oled_Show_Str(2,2,"-----XunJi----");
			}
			mark = XJ;
			xunjiMode();
		}
		//满足跟随模式的条件
		if(A25 == 1 && A26 == 0 && A27 == 1){
			if(mark != GS){
				Oled_Clear();
				Oled_Show_Str(2,2,"-----GenSui----");
			}
			mark = GS;
			gensuiMode();
		}
		//满足避障模式的条件
		if(A25 == 1 && A26 == 1 && A27 == 0){
			if(mark != BZ){
				Oled_Clear();
				Oled_Show_Str(2,2,"-----BiZhang----");
				mark = BZ;
				bizhangMode();
			}
		}
		//满足stop的条件
		if(A25 == 0 && A26 == 0 && A27 == 0){
			if(mark != ST){
				Oled_Clear();
				Oled_Show_Str(2,2,"-----STOP----");
				mark = ST;
				stop();
			}
		}
	}
}

12. 效果演示(290.137)

你可能感兴趣的:(单片机,stm32,嵌入式硬件)