B43 - 基于STM32单片机的自动视力检测仪

2024-01-08 00:59

本文主要是介绍B43 - 基于STM32单片机的自动视力检测仪,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 任务
  • 实物
    • 主机
    • 从机
    • 手机APP
      • 蓝牙连接界面
      • 获取视力记录在手机上同步显示折线图
  • 原理图
    • 主机
    • 从机
  • 资源分配
    • 主机
    • 从机
  • 设计流程
  • 源程序
    • 主机主程序
    • 从机主程序
    • 语音模块代码
    • 主机蓝牙指令处理
    • 主机无线指令处理
    • 从机无线模块指令处理
    • 语音识别模块
    • QT设计蓝牙APP

任务

本系统设计了一个基于STM32单片机的自动视力检测系统,通过单片机控制LCD高清液晶显示屏显示“E”字形的开口方向和大小,来替代传统的视力测试面板;通过语音播放模块进行测试过程的提示语播放、语音识别模块进行识别测试者对于当前屏幕显示“E”形状的开口方向的回答,完成对测试者的自动视力检测过程;通过无线按钮为听力受损人员提供手动按下方向按键回答屏幕显示“E”行方向和大小的功能。本系统整体设计功能和参数如下。
设计功能:
(1)采用LCD高清液晶显示“E”字形,涵盖视力检测板所有“E”形状和大小。(2)自动化语音提示,确保检测者知道当前需要做什么。
(3)智能化语音识别,系统精准采集测试者的回答结果。
(4)无线按键,方便用户通过选择按下的方向按键回答显示屏“E”开口方向,扩大适用人群和使用环境。
(5)采用QT设计安卓程序,通过蓝牙和主控板连接,能够记录和显示测试者本人的近期视力检测结果,可以通过蓝牙应用程序或者在液晶屏上获取到对应的折线图,使用户方便直观的看到视力检测结果的变化。
(6)检测系统在调取检测结果时,可以根据历史检测结果做出温馨提醒,比如“近期视力检测下降,请注意适当休息哦!”。
设计参数:
(1)显示屏幕细腻,分辨率最低480*320,屏幕尺寸采用3.5寸。
(2)无线通讯距离不低于5米。
(3)语音识别:非特定人识别,2米内识别准确率95%以上,识别速度2秒以内。
(4)识别语种:中文。
(5)语音播放功率不小于3W。
(6)检测结果可存储不低于100人,可记录每人最低20条最近测试结果。

在这里插入图片描述

实物

主机

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

从机

在这里插入图片描述
在这里插入图片描述

手机APP

蓝牙连接界面

注意:本次使用的蓝牙模块是HC-05。
在这里插入图片描述

获取视力记录在手机上同步显示折线图

在这里插入图片描述

原理图

主机

在这里插入图片描述

从机

在这里插入图片描述

资源分配

主机

在这里插入图片描述

从机

在这里插入图片描述

设计流程

在这里插入图片描述

源程序

本系统程序过多,只放置可以参考的代码,在做此方面功能的可用于参考思路。

主机主程序

/*******************************************************************************\* 文件名称:基于STM32单片机的自动视力检测仪\* 实验目的:1.\* 2.\* 程序说明:完整程序Q:277 227 2579;@: itworkstation@ hotmail.com\* 日期版本:本项目分享关键细节,熟悉使用单片机的可做参考代码。完整讲解+源代码工程可联系获取,可定制。*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "main.h"   
#include "lcdUart.h"
#include "key.h" 
#include "bsp_timer3.h"  
#include "usart3.h" 
#include "wireless.h"
#include "e2prom.h" 
#include "usart1.h" 
#include "bluetooth.h"
#include <math.h>
#include <stdlib.h>u8 EPROM[10][18]; //10个测试者,每个20空间。1-10, 21-40,...
extern u8 E2ReadNowUserTab[18];/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void StoreEpRom(void) //将结果存储
{u8 i=0;for(i=0;i<18;i++){if(EPROM[LCD_InfoStru.TestUser-1][i] == 0){break; //找到数组最近的为0的位置}}if(i==18) //已经存储了18次测试记录,删掉最久存储的一次{for(i=0;i<17;i++){EPROM[LCD_InfoStru.TestUser-1][i] = EPROM[LCD_InfoStru.TestUser-1][i+1];}EPROM[LCD_InfoStru.TestUser-1][17] = LCD_InfoStru.Hang_Now+1; //改变一下存储值,因为显示时1.2应该是15,原值为14}else{EPROM[LCD_InfoStru.TestUser-1][i] = LCD_InfoStru.Hang_Now+1; //改变一下存储值,因为显示时1.2应该是15,原值为14}for(i=0;i<10;i++){E2WriteStr(1+i*20,EPROM[i],18);}
}
/*** @说明     主函数* @参数     None * @返回值   None*/
int main(void)
{u8 EpPos=0,EpPosY=0;LED_Init();Proc_Init();USART2_Init(); Delay_ms(1000);//上电等待 1 秒是串口屏模块正常工作的前提,如果没有足够的等待时间模块有可能无法正常的接收指令而导致系统出错。	printf("CLR(%d);DIR(3);BL(%d);\r\n",LCD_BackColor,LCD_Light);  //CLR(16);DIR(1);BL(10);  //白色,横屏,背光10(0-255:最亮:最暗)LCD_CheckBusy(); Key_Init();TIM4_Init();  LCD_Menu = LCD_DEFAULT; LCD_Display();USART3_Init();USART1_Init();E2Init();for(EpPos=0;EpPos<10;EpPos++) // 清空数据,初始化数组{for(EpPosY=0;EpPosY<18;EpPosY++){EPROM[EpPos][EpPosY] = 0;}}if(e2Struct.is_newE2){for(EpPos=0;EpPos<10;EpPos++)//0-10  0-17{E2WriteStr(1+EpPos*20,EPROM[EpPos],18);}}else{for(EpPos=0;EpPos<10;EpPos++){E2ReadStr(1+EpPos*20,EPROM[EpPos],18); //获得历史检测结果}}TIM3_Init();while(1){		 if(TIM4_FlagStatus.Flag_500MS == TRUE){TIM4_FlagStatus.Flag_500MS = FALSE;LED_Control(REVERSE);    			   }parseBLUETOOTHBuffer();if(LCD_Menu == LCD_TEST) {parseWIRELESSBuffer();if(WIRELESS_Data.isUsefull){if(WIRELESS_Data.isResultRight) //收到从机数据,且结果为真{			LCD_InfoStru.is_ResultRight = 1;LCD_Display();Delay_ms(3000);LCD_InfoStru.is_ResultRight = 0;LCD_InfoStru.Hang_Time ++;if(LCD_InfoStru.Hang_Time>=5) //结束{LCD_InfoStru.Hang_RightTime = 0;LCD_InfoStru.Hang_ErrorTime = 0;LCD_InfoStru.Hang_Time = 0;StoreEpRom();LCD_Menu = LCD_TESTEND;if(LCD_InfoStru.Hang_Now<13)WIRELESS_sendMessage("$O1@");elseWIRELESS_sendMessage("$O2@");}LCD_InfoStru.Hang_RightTime ++;if(LCD_InfoStru.Hang_RightTime > 2){if(LCD_InfoStru.Hang_Now < Hang_Init)		{							//初始化行上面,正确3次,结束StoreEpRom();LCD_Menu = LCD_TESTEND;WIRELESS_sendMessage("$O1@");}else{//3次正确,下一行LCD_InfoStru.Hang_Now ++;if(LCD_InfoStru.Hang_Now >Hang_END){LCD_InfoStru.Hang_Now = Hang_END;//1.2视力,结束StoreEpRom();LCD_Menu = LCD_TESTEND;WIRELESS_sendMessage("$O2@");}}					LCD_InfoStru.Hang_RightTime = 0;LCD_InfoStru.Hang_ErrorTime = 0;LCD_InfoStru.Hang_Time = 0;}}else{LCD_InfoStru.is_ResultRight = 2;LCD_Display();Delay_ms(3000);LCD_InfoStru.is_ResultRight = 0;//从机识别错误LCD_InfoStru.Hang_Time ++;if(LCD_InfoStru.Hang_Time>=5) //结束{LCD_InfoStru.Hang_RightTime = 0;LCD_InfoStru.Hang_ErrorTime = 0;LCD_InfoStru.Hang_Time = 0;StoreEpRom();LCD_Menu = LCD_TESTEND;if(LCD_InfoStru.Hang_Now<13)WIRELESS_sendMessage("$O1@");elseWIRELESS_sendMessage("$O2@");}LCD_InfoStru.Hang_ErrorTime ++;if(LCD_InfoStru.Hang_ErrorTime > 2){if(LCD_InfoStru.Hang_Now <= Hang_Init)						{//3次错误,初始行或者小于初始行,退到上一行LCD_InfoStru.Hang_Now --;if(LCD_InfoStru.Hang_Now < 1){WIRELESS_sendMessage("$O1@");//最上行,结束StoreEpRom();LCD_Menu = LCD_TESTEND;}							}else{if(LCD_InfoStru.Hang_Now<13)WIRELESS_sendMessage("$O1@");elseWIRELESS_sendMessage("$O2@");//往下检测时,3次错误,结束StoreEpRom();LCD_Menu = LCD_TESTEND;}LCD_InfoStru.Hang_RightTime = 0;LCD_InfoStru.Hang_ErrorTime = 0;LCD_InfoStru.Hang_Time = 0;}}LCD_InfoStru.rand_E = rand()%4;  WIRELESS_Clear_Data(); //使用一次,清空数据sprintf(WIRELESS_Data.SendDire,"$D%1d@",LCD_InfoStru.rand_E+1);WIRELESS_sendMessage(WIRELESS_Data.SendDire);TIM3_DateClear(); // 重新计时LCD_Display(); //刷新}if(TIM3_FlagStatus.Flag_1000MS == TRUE){TIM3_FlagStatus.Flag_1000MS = FALSE;TIM3_FlagStatus.Time_jishi --;if(TIM3_FlagStatus.Time_jishi<0){		TIM3_FlagStatus.Time_jishi = 0;	LCD_InfoStru.is_ResultRight = 2;LCD_Display();Delay_ms(3000);LCD_InfoStru.is_ResultRight = 0;LCD_InfoStru.Hang_Time ++;if(LCD_InfoStru.Hang_Time>=5) //结束{LCD_InfoStru.Hang_RightTime = 0;LCD_InfoStru.Hang_ErrorTime = 0;LCD_InfoStru.Hang_Time = 0;StoreEpRom();LCD_Menu = LCD_TESTEND;if(LCD_InfoStru.Hang_Now<13)WIRELESS_sendMessage("$O1@");elseWIRELESS_sendMessage("$O2@");}LCD_InfoStru.Hang_ErrorTime ++;if(LCD_InfoStru.Hang_ErrorTime > 2){if(LCD_InfoStru.Hang_Now <= Hang_Init)						{//3次错误,初始行或者小于初始行,退到上一行LCD_InfoStru.Hang_Now --;if(LCD_InfoStru.Hang_Now < 1){WIRELESS_sendMessage("$O1@");//最上行,结束StoreEpRom();LCD_Menu = LCD_TESTEND;}														}else{//往下检测时,3次错误,结束StoreEpRom();LCD_Menu = LCD_TESTEND;if(LCD_InfoStru.Hang_Now<13)WIRELESS_sendMessage("$O1@");elseWIRELESS_sendMessage("$O2@");}LCD_InfoStru.Hang_RightTime = 0;LCD_InfoStru.Hang_ErrorTime = 0;LCD_InfoStru.Hang_Time = 0;}					LCD_InfoStru.rand_E = rand()%4;  WIRELESS_Clear_Data(); //使用一次,清空数据sprintf(WIRELESS_Data.SendDire,"$D%1d@",LCD_InfoStru.rand_E+1);WIRELESS_sendMessage(WIRELESS_Data.SendDire);TIM3_DateClear();  //重新计时,计算}LCD_Display(); //刷新}			}Proc_Key();		 		}     
}

从机主程序

/*******************************************************************************  
* 文件名称:最小系统板STM32C8T6
* 实验目的:1.
*           2.
* 程序说明:
* 日期版本:
*******************************************************************************//* Includes ------------------------------------------------------------------*/
#include "main.h"   
#include "usart1.h" 
#include "JQ_8400.h" 
#include "key.h" 
#include "usart2.h" 
#include "wireless.h"
#include "usart3.h" 
#include "Lu_ASR01.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*//*** @说明     主函数* @参数     None * @返回值   None*/
int main(void)
{u8 keyValue=0xff;LED_Init();LED_Control(ON);Delay_ms(1000);LED_Control(OFF);Proc_Init();USART1_Init();JQ8400_Init();Key_Init();USART2_Init();USART3_Init();TIM4_Init();  while(1){		 if(TIM4_FlagStatus.Flag_200MS == SET){TIM4_FlagStatus.Flag_200MS = RESET;LED_Control(REVERSE);    Proc_200Ms();  }parseWIRELESSBuffer();if(WIRELESS_Data.isUsefull) // 只有接收到方向后才启动语音识别{parseASR01Buffer(); if(ASR01_Data.isUsefull){//无线接收到方向,语音识别到方向if(ASR01_Data.Direction == WIRELESS_Data.Direction){				WIRELESS_SendStr("$T@");}else{					WIRELESS_SendStr("$F@");}ASR01_Clear_Data();WIRELESS_Clear_Data();}keyValue = Key_Scan();if(keyValue != 0xff){if(WIRELESS_Data.Direction == keyValue){JQ8400_6x00SendCmd(SELECTE_PLAY,2); WIRELESS_SendStr("$T@");}else{JQ8400_6x00SendCmd(SELECTE_PLAY,3); WIRELESS_SendStr("$F@");}WIRELESS_Clear_Data();}}else{ASR01_Clear_Data();}		}     
}

语音模块代码

#ifndef __Lu_ASR01_H
#define __Lu_ASR01_H#include "stm32f10x.h"
#include "Def_config.h"#define ASR01_Buffer_Length 50
#define ASR01_Length 5typedef struct
{char ASR01_Rec_Buffer[ASR01_Buffer_Length];ENUM_JUDGE isGetData;		//是否获取到数据ENUM_JUDGE isParseData;	//是否解析完成ENUM_JUDGE isUsefull;		//信息是否有效uint16_t Direction;
} _ASR01Data;extern _ASR01Data ASR01_Data;void ASR01_RecHandle(u8 Res);
void ASR01_Clear_Data(void);
void parseASR01Buffer(void);#endif 
#include "Lu_ASR01.h"
#include <string.h>
#include <stdio.h>#include "JQ_8400.h" _ASR01Data ASR01_Data;
char  ASR01_RX_BUF[ASR01_Buffer_Length]; //接收缓冲,最大ASR01_Buffer_Length个字节.末字节为换行符 
u8 LuAsr_point2 = 0;
void ASR01_RecHandle(u8 Res)
{if(Res == '$'){LuAsr_point2 = 0;	}ASR01_RX_BUF[LuAsr_point2++] = Res;if(Res == '@' || LuAsr_point2 >3)									   {memset(ASR01_Data.ASR01_Rec_Buffer, 0, ASR01_Buffer_Length);      //清空memcpy(ASR01_Data.ASR01_Rec_Buffer, ASR01_RX_BUF, LuAsr_point2); 	//保存数据ASR01_Data.isGetData = TRUE; LuAsr_point2 = 0;memset(ASR01_RX_BUF, 0, ASR01_Buffer_Length);      //清空}		if(LuAsr_point2 >= ASR01_Buffer_Length){LuAsr_point2 = ASR01_Buffer_Length;}	
}
u8 ASR01_Find(char *a)                   // 串口命令识别函数
{ if(strstr(ASR01_Data.ASR01_Rec_Buffer,a)!=NULL)return 1;elsereturn 0;
}
void ASR01_Clear_Data(void)
{ASR01_Data.isGetData = FALSE;ASR01_Data.isParseData = FALSE;ASR01_Data.isUsefull = FALSE;memset(ASR01_Data.ASR01_Rec_Buffer, 0, ASR01_Buffer_Length);      //清空memset(ASR01_RX_BUF, 0, ASR01_Buffer_Length);ASR01_Data.Direction = 0;
}
void parseASR01Buffer(void)
{if (ASR01_Data.isGetData)  //获得语音模块的数据 --- $1@   : $4@{ASR01_Data.isGetData = FALSE;if(ASR01_Find("$D1@")){ASR01_Data.isParseData = TRUE;ASR01_Data.isUsefull = TRUE;ASR01_Data.Direction = 1;
//			JQ8400_6x00SendCmd(SELECTE_PLAY,1); //选择指定曲目播放}else if(ASR01_Find("$D2@")){ASR01_Data.isParseData = TRUE;ASR01_Data.isUsefull = TRUE;ASR01_Data.Direction = 2;}else if(ASR01_Find("$D3@")){ASR01_Data.isParseData = TRUE;ASR01_Data.isUsefull = TRUE;ASR01_Data.Direction = 4; //右}else if(ASR01_Find("$D4@")){  	ASR01_Data.isParseData = TRUE;ASR01_Data.isUsefull = TRUE;ASR01_Data.Direction = 3;}else{ASR01_Clear_Data(); //清空接收到的数据---数据帧无效}}
}

主机蓝牙指令处理

#ifndef __BLUETOOTH_h
#define __BLUETOOTH_h#include "stm32f10x.h"
#include <string.h>
#include <stdio.h>
#include "Def_config.h"#include "usart1.h" 
#define BLUETOOTH_SendStr  USART1_SendString#define BLUETOOTH_Buffer_Length 100
#define BLUETOOTH_Length 50
#define BLUETOOTH_IntLength 4
typedef struct
{char BLUETOOTH_Rec_Buffer[BLUETOOTH_Buffer_Length];ENUM_JUDGE isGetData;		//是否获取到数据ENUM_JUDGE isParseData;	//是否解析完成ENUM_JUDGE isUsefull;		//信息是否有效char sendMessage[BLUETOOTH_Buffer_Length];char userIDchar[BLUETOOTH_IntLength];u16 userIDInt;
} _BLUETOOTHData;
extern _BLUETOOTHData BLUETOOTH_Data;void BLUETOOTH_sendMessage(void);
void BLUETOOTH_RecHandle(u8 Res);
void BLUETOOTH_Clear_Data(void);
void parseBLUETOOTHBuffer(void);#endif 
#include "bluetooth.h"
_BLUETOOTHData BLUETOOTH_Data;
char  BLUETOOTH_RX_BUF[BLUETOOTH_Buffer_Length]; //接收缓冲,最大BLUETOOTH_Buffer_Length个字节.末字节为换行符 
u8 BLUETOOTH_point2 = 0;
void BLUETOOTH_RecHandle(u8 Res)
{if(Res == '$'){BLUETOOTH_point2 = 0;	}BLUETOOTH_RX_BUF[BLUETOOTH_point2++] = Res;if(Res == '@')									   {memset(BLUETOOTH_Data.BLUETOOTH_Rec_Buffer, 0, BLUETOOTH_Buffer_Length);      //清空memcpy(BLUETOOTH_Data.BLUETOOTH_Rec_Buffer, BLUETOOTH_RX_BUF, BLUETOOTH_point2); 	//保存数据BLUETOOTH_Data.isGetData = TRUE; BLUETOOTH_point2 = 0;memset(BLUETOOTH_RX_BUF, 0, BLUETOOTH_Buffer_Length);      //清空}		if(BLUETOOTH_point2 >= BLUETOOTH_Buffer_Length){BLUETOOTH_point2 = BLUETOOTH_Buffer_Length;}	
}
void BLUETOOTH_Clear_Data(void)
{BLUETOOTH_Data.isGetData = FALSE;BLUETOOTH_Data.isParseData = FALSE;BLUETOOTH_Data.isUsefull = FALSE;memset(BLUETOOTH_Data.BLUETOOTH_Rec_Buffer, 0, BLUETOOTH_Buffer_Length);      //清空memset(BLUETOOTH_Data.sendMessage, 0, BLUETOOTH_Buffer_Length);      //清空memset(BLUETOOTH_Data.userIDchar, 0, BLUETOOTH_IntLength); BLUETOOTH_Data.userIDInt = 0;
}
u8 BLUETOOTH_Find(char *a)                   // 串口命令识别函数
{ if(strstr(BLUETOOTH_Data.BLUETOOTH_Rec_Buffer,a)!=NULL)return 1;elsereturn 0;
}
u16 transform(u8 dat)
{u16 date_shili = 0;switch(dat){case 1:date_shili=5;break;case 2:date_shili=6;break;case 3:date_shili=8;break;case 4:date_shili=10;break;case 5:date_shili=12;break;case 6:date_shili=15;break;case 7:date_shili=20;break;case 8:date_shili=25;break;case 9:date_shili=30;break;case 10:date_shili=40;break;case 11:date_shili=50;break;case 12:date_shili=60;break;case 13:date_shili=80;break;case 14:date_shili=100;break;case 15:date_shili=120;break;default:break;}return date_shili;
}
extern u8 EPROM[10][18]; 
void BLUETOOTH_sendMessage(void)
{u8 i=0;u8 length=0;u16 E2ReadNowUserTab[18];for(i=0;i<18;i++){E2ReadNowUserTab[i] = 0;}for(i=0;i<18;i++){E2ReadNowUserTab[i] = transform(EPROM[BLUETOOTH_Data.userIDInt-1][i]);if(E2ReadNowUserTab[i] == 0){break;}		}if(i==0)length = 0;elselength = i;memset(BLUETOOTH_Data.sendMessage, 0, BLUETOOTH_Buffer_Length);      //清空sprintf(BLUETOOTH_Data.sendMessage,"$%d,%d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,%03d,@",BLUETOOTH_Data.userIDInt,length,E2ReadNowUserTab[0],E2ReadNowUserTab[1],E2ReadNowUserTab[2],E2ReadNowUserTab[3],E2ReadNowUserTab[4],E2ReadNowUserTab[5],E2ReadNowUserTab[6],E2ReadNowUserTab[7],E2ReadNowUserTab[8],E2ReadNowUserTab[9],E2ReadNowUserTab[10],E2ReadNowUserTab[11],E2ReadNowUserTab[12],E2ReadNowUserTab[13],E2ReadNowUserTab[14],E2ReadNowUserTab[15],E2ReadNowUserTab[16],E2ReadNowUserTab[17]);BLUETOOTH_SendStr(BLUETOOTH_Data.sendMessage);
}
uint16_t CharToInt(char *dat)
{uint16_t date=0;while((*dat) != '\0'){if(((*dat) > 0x30)&&((*dat) <= 0x39))date = ((*dat)-0x30) + date*10;dat++;}return date;
}
void parseBLUETOOTHBuffer(void)
{char *str = NULL, *strNext = NULL;if (BLUETOOTH_Data.isGetData)  //获得语音模块的数据 --- $1@   : $4@{BLUETOOTH_Data.isGetData = FALSE;str = strstr(BLUETOOTH_Data.BLUETOOTH_Rec_Buffer,"ID");if(str != NULL)  //$ID1@  -  $ID10@{BLUETOOTH_Data.isParseData = TRUE;BLUETOOTH_Data.isUsefull = TRUE;str = str+2;strNext = strstr(str,"@");if(strNext != NULL){memset(BLUETOOTH_Data.userIDchar, 0, BLUETOOTH_IntLength);memcpy(BLUETOOTH_Data.userIDchar,str, strNext - str); //				BLUETOOTH_SendStr(BLUETOOTH_Data.userIDchar);BLUETOOTH_Data.userIDInt = CharToInt(BLUETOOTH_Data.userIDchar); //1-10if(BLUETOOTH_Data.userIDInt > 0 && BLUETOOTH_Data.userIDInt < 11){BLUETOOTH_sendMessage();}	}							}else{
//			BLUETOOTH_Clear_Data(); //清空接收到的数据---数据帧无效}}
}/*******************参考处理设计,自行添加内容*****************************
void Proc_Bluethooth(void)
{parseBLUETOOTHBuffer();if(BLUETOOTH_Data.isUsefull == TRUE){BLUETOOTH_Data.isUsefull = FALSE;}
}
************************************************/

主机无线指令处理

#ifndef __WIRELESS_h
#define __WIRELESS_h#include "stm32f10x.h"
#include <string.h>
#include <stdio.h>
#include "Def_config.h"#include "usart3.h" 
#define WIRELESS_SendStr       USART3_SendString #define WIRELESS_Buffer_Length 100
#define WIRELESS_Length 50typedef struct
{char WIRELESS_Rec_Buffer[WIRELESS_Buffer_Length];ENUM_JUDGE isGetData;		//是否获取到数据ENUM_JUDGE isParseData;	//是否解析完成ENUM_JUDGE isUsefull;		//信息是否有效char SendDire[WIRELESS_Length];ENUM_JUDGE isResultRight;
} _WIRELESSData;
extern _WIRELESSData WIRELESS_Data;void WIRELESS_sendMessage(char *p);
void WIRELESS_RecHandle(u8 Res);void WIRELESS_Clear_Data(void);void parseWIRELESSBuffer(void);#endif 
#include "wireless.h"_WIRELESSData WIRELESS_Data;
char  WIRELESS_RX_BUF[WIRELESS_Buffer_Length]; //接收缓冲,最大WIRELESS_Buffer_Length个字节.末字节为换行符 
u8 point2 = 0;
void WIRELESS_RecHandle(u8 Res)
{if(Res == '$'){point2 = 0;	}WIRELESS_RX_BUF[point2++] = Res;if(Res == '@')									   {memset(WIRELESS_Data.WIRELESS_Rec_Buffer, 0, WIRELESS_Buffer_Length);      //清空memcpy(WIRELESS_Data.WIRELESS_Rec_Buffer, WIRELESS_RX_BUF, point2); 	//保存数据WIRELESS_Data.isGetData = TRUE; point2 = 0;memset(WIRELESS_RX_BUF, 0, WIRELESS_Buffer_Length);      //清空}		if(point2 >= WIRELESS_Buffer_Length){point2 = WIRELESS_Buffer_Length;}	
}
void WIRELESS_Clear_Data(void)
{WIRELESS_Data.isGetData = FALSE;WIRELESS_Data.isParseData = FALSE;WIRELESS_Data.isUsefull = FALSE;memset(WIRELESS_Data.WIRELESS_Rec_Buffer, 0, WIRELESS_Buffer_Length);      //清空memset(WIRELESS_RX_BUF, 0, WIRELESS_Buffer_Length);      //清空WIRELESS_Data.isResultRight = FALSE;memset(WIRELESS_Data.SendDire, 0, WIRELESS_Length); 	
}
u8 WIRELESS_Find(char *a)                   // 串口命令识别函数
{ if(strstr(WIRELESS_Data.WIRELESS_Rec_Buffer,a)!=NULL)return 1;elsereturn 0;
}
void WIRELESS_sendMessage(char *p)
{WIRELESS_SendStr(p); 
}
void parseWIRELESSBuffer(void)
{if (WIRELESS_Data.isGetData)  //获得模块的数据 --- $D1@   : $D4@{WIRELESS_Data.isGetData = FALSE;if(WIRELESS_Find("$T@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	WIRELESS_Data.isResultRight = TRUE;}else if(WIRELESS_Find("$F@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	WIRELESS_Data.isResultRight=FALSE;}else{WIRELESS_Clear_Data(); //清空接收到的数据---数据帧无效}}
}/*******************参考处理设计,自行添加内容*****************************
void Proc_Bluethooth(void)
{parseWIRELESSBuffer();if(WIRELESS_Data.isUsefull == TRUE){WIRELESS_Data.isUsefull = FALSE;}
}
************************************************/

从机无线模块指令处理

#ifndef __WIRELESS_h
#define __WIRELESS_h#include "stm32f10x.h"
#include <string.h>
#include <stdio.h>
#include "Def_config.h"#include "usart2.h" 
#define WIRELESS_SendStr       USART2_SendString #define WIRELESS_Buffer_Length 100
#define WIRELESS_Length 50typedef struct
{char WIRELESS_Rec_Buffer[WIRELESS_Buffer_Length];ENUM_JUDGE isGetData;		//是否获取到数据ENUM_JUDGE isParseData;	//是否解析完成ENUM_JUDGE isUsefull;		//信息是否有效uint16_t Direction;
} _WIRELESSData;
extern _WIRELESSData WIRELESS_Data;void WIRELESS_sendMessage(char *p);
void WIRELESS_RecHandle(u8 Res);void WIRELESS_Clear_Data(void);void parseWIRELESSBuffer(void);#endif 
#include "wireless.h"
#include "JQ_8400.h" _WIRELESSData WIRELESS_Data;
char  WIRELESS_RX_BUF[WIRELESS_Buffer_Length]; //接收缓冲,最大WIRELESS_Buffer_Length个字节.末字节为换行符 
u8 point2 = 0;
void WIRELESS_RecHandle(u8 Res)
{if(Res == '$'){point2 = 0;	}WIRELESS_RX_BUF[point2++] = Res;if(Res == '@')									   {memset(WIRELESS_Data.WIRELESS_Rec_Buffer, 0, WIRELESS_Buffer_Length);      //清空memcpy(WIRELESS_Data.WIRELESS_Rec_Buffer, WIRELESS_RX_BUF, point2); 	//保存数据WIRELESS_Data.isGetData = TRUE; point2 = 0;memset(WIRELESS_RX_BUF, 0, WIRELESS_Buffer_Length);      //清空}		if(point2 >= WIRELESS_Buffer_Length){point2 = WIRELESS_Buffer_Length;}	
}
void WIRELESS_Clear_Data(void)
{WIRELESS_Data.isGetData = FALSE;WIRELESS_Data.isParseData = FALSE;WIRELESS_Data.isUsefull = FALSE;memset(WIRELESS_Data.WIRELESS_Rec_Buffer, 0, WIRELESS_Buffer_Length);      //清空memset(WIRELESS_RX_BUF, 0, WIRELESS_Buffer_Length);      //清空WIRELESS_Data.Direction = 0;
}
u8 WIRELESS_Find(char *a)                   // 串口命令识别函数
{ if(strstr(WIRELESS_Data.WIRELESS_Rec_Buffer,a)!=NULL)return 1;elsereturn 0;
}
void WIRELESS_sendMessage(char *p)
{WIRELESS_SendStr(p); 
}
void parseWIRELESSBuffer(void)
{if (WIRELESS_Data.isGetData)  //获得模块的数据 --- $D1@   : $D4@{WIRELESS_Data.isGetData = FALSE;if(WIRELESS_Find("$D1@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	WIRELESS_Data.Direction = 1;}else if(WIRELESS_Find("$D2@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	WIRELESS_Data.Direction=2;}else if(WIRELESS_Find("$D3@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	WIRELESS_Data.Direction =3; //右}else if(WIRELESS_Find("$D4@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	WIRELESS_Data.Direction = 4;
//			WIRELESS_SendStr("$OK@");}else if(WIRELESS_Find("$O1@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	JQ8400_6x00SendCmd(SELECTE_PLAY,4);WIRELESS_Clear_Data();}else if(WIRELESS_Find("$O2@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	JQ8400_6x00SendCmd(SELECTE_PLAY,5);WIRELESS_Clear_Data();}else if(WIRELESS_Find("$OK@")){WIRELESS_Data.isParseData = TRUE;WIRELESS_Data.isUsefull = TRUE;	JQ8400_6x00SendCmd(SELECTE_PLAY,6);WIRELESS_Clear_Data();}else{WIRELESS_Clear_Data(); //清空接收到的数据---数据帧无效}}
}/*******************参考处理设计,自行添加内容*****************************
void Proc_Bluethooth(void)
{parseWIRELESSBuffer();if(WIRELESS_Data.isUsefull == TRUE){WIRELESS_Data.isUsefull = FALSE;}
}
************************************************/

语音识别模块

LU-ASR01鹿小班智能语音识别模块是由鹿小班开源电子厂家设计生产的一款高性能语音识别模组。该模块支持天问公司的block软件,是天问ASR主板系列之一,支持以可视化代码积木的方式配置语音指令、设定语音识别提示、串口输出指令信息等。模块扩展了8个输出I/O口用于直接和控制设备相连,且支持DHT11温湿度模块直接采集的特性。该模块支持10米超远距离唤醒功能、超过98%的超高识别准确率。本系统将LU-ASR01语音模块的输出串口TXD连接到了从机的串口3对应的PB11引脚用于接收语音识别后的输出指令。通过LU-ASR01语音识别模块的开发平台设定好语音识别指令词和识别到关键词的串口输出内容,当语音模块接收到测试者的语音并处理解析到对应的指令词后,通过串口向从机输出设定的指令对应数据用于系统的逻辑处理。
在这里插入图片描述
在这里插入图片描述

QT设计蓝牙APP

在此占位,后期有时间整理了再开源。

这篇关于B43 - 基于STM32单片机的自动视力检测仪的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/581821

相关文章

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

零基础STM32单片机编程入门(一)初识STM32单片机

文章目录 一.概要二.单片机型号命名规则三.STM32F103系统架构四.STM32F103C8T6单片机启动流程五.STM32F103C8T6单片机主要外设资源六.编程过程中芯片数据手册的作用1.单片机外设资源情况2.STM32单片机内部框图3.STM32单片机管脚图4.STM32单片机每个管脚可配功能5.单片机功耗数据6.FALSH编程时间,擦写次数7.I/O高低电平电压表格8.外设接口

WordPress网创自动采集并发布插件

网创教程:WordPress插件网创自动采集并发布 阅读更新:随机添加文章的阅读数量,购买数量,喜欢数量。 使用插件注意事项 如果遇到404错误,请先检查并调整网站的伪静态设置,这是最常见的问题。需要定制化服务,请随时联系我。 本次更新内容 我们进行了多项更新和优化,主要包括: 界面设置:用户现在可以更便捷地设置文章分类和发布金额。代码优化:改进了采集和发布代码,提高了插件的稳定

【青龙面板辅助】JD商品自动给好评获取京豆脚本

1.打开链接 开下面的链接进入待评价商品页面 https://club.jd.com/myJdcomments/myJdcomments.action?sort=0 2.登陆后执行脚本 登陆后,按F12键,选择console,复制粘贴以下代码,先运行脚本1,再运行脚本2 脚本1代码 可以自行修改评价内容。 var content = '材质很好,质量也不错,到货也很快物流满分,包装快递满

AI炒股:自动画出A股股票的K线图并添加技术指标

在deepseek中输入提示词: 你是一个Python编程专家,要完成一个编写Python脚本的任务,具体步骤如下: 用AKShare库获取股票贵州茅台(股票代码:600519)在2024年3月7日到2024年6月5日期间的历史行情数据-前复权。 然后绘制K线图,并在K线图上添加布林线、MACD 注意: 每一步都要输出信息到屏幕上; 日期格式是YYYYMMDD; 设置中文字体,以解决

XMG 自动提示宏 #define keyPath(objc,keyPath) @(((void)objc.keyPath,#keyPath));

1. int a=((void)5,4)  C语言逗号表达式默认会取右边的内容 如果不写void的话 a会被报警告,写上void标明请忽略左边的内容 插曲刚才弄得,已经上线的苹果产品如果需要下架的话,点击 价格与销售范围,然后点击下架。这个产品就会在AppStore 中移除。如果想再让改产品重新在Apple store中显示,那么再次让他上线就可以了。但是会有一定的时间延迟 /

自动驾驶---Perception之Lidar点云3D检测

1 背景         Lidar点云技术的出现是基于摄影测量技术的发展、计算机及高新技术的推动以及全球定位系统和惯性导航系统的发展,使得通过激光束获取高精度的三维数据成为可能。随着技术的不断进步和应用领域的拓展,Lidar点云技术将在测绘、遥感、环境监测、机器人等领域发挥越来越重要的作用。         目前全球范围内纯视觉方案的车企主要包括特斯拉和集越,在达到同等性能的前提下,纯视觉方

STM32单片机PWR电源控制详解

文章目录 1. PWR概述 2. 电源结构框图 3. 上电复位和掉电复位 4. 可编程电压监测器 5. 低功耗模式 6. 模式选择 6.1 睡眠模式 6.2 停止模式 6.3 待机模式 7. 代码示例 1. PWR概述 PWR(Power Control)电源控制,负责管理STM32内部的电源供电部分,可以实现可编程电压监测器和低功耗模式的功能。 可编程电压监测器

Linux开机自动启动ORACLE设置

Redhat init简介: Linux启动时,会运行一个init程序,然后由init来启动后面的任务,包括多用户环境(inittab中设定)和网络等。运行级就是当前程序运行的功能级别,这个级别从1到6,具有不同的功能。这些级别在/etc/inittab(其他发行版这个文件位置不同)中指定,该文件就是init程序寻找的主要文件。最先运行的服务放在/etc/rc.d目录下。

自动驾驶规划中使用 OSQP 进行二次规划 代码原理详细解读

目录 1 问题描述 什么是稀疏矩阵 CSC 形式 QP Path Planning 问题 1. Cost function 1.1 The first term: 1.2 The second term: 1.3 The thrid term: 1.4 The forth term: 对 Qx''' 矩阵公式的验证 整体 Q 矩阵(就是 P 矩阵,二次项的权重矩阵)