电子说
一、软件E4A5 APP部署方法
E4A5的部署文件有两个,


编辑后缀为e4a为编程文件,技术人员代码编辑文件,部署文件为apk。使用E4A5时候在设置处可以设置png格式的图标以及apk文件名,在调试程序前,需要下载


编辑雷电模拟器作为手机模拟发生器(官网可以下载),E4A5为中文编程,其APK文件通过QQ附件形式可以直接下载安装在手机上,有些手机为了安全会在QQ下载时候后缀名改了,这个时候在手机默认的文档里找到该APK,将后缀名修改为APK后可以下载安装,下载前由于签字唯一性,需要将之前的程序先卸载,切记。
二、软件飞讯语音功能技术部署方法
讯飞语音组件在E4A5的example例子文件里中级历程有例子,在编程的媒体类软件处可以找到


编辑,同时也需要在扩展库找到权限操作


编辑,将例程里将里面的libsarm64-v8alibmsc.so 和 libsarmeabi-v7alibmsc.so 文件导入到E4A左侧的工程里的SO库中,并将Msc.jar文件导入到工程里的JAR包中

然后讯飞语音可以用,如果手机有拦截警告,可以予以信任,讯飞语音的准确度一直在平台更新,准确率达90%。但是有一点需要注意,就是识别结束时候以逗号结束,所以一定在代码要加上“。”比如:时间设置为10分钟。
核心代码:
事件 窗口1.创建完毕()
如果 权限操作1.取系统版本号() >=23 则
权限操作1.申请全部权限()
结束 如果
讯飞语音1.初始化("5cf517a5") '!!!请替换成你自己的APPID,并到左侧的工程选项卡中的 引入SO库 那里替换你自己申请到的SDK开发包中的libmsc.so库文件和Msc.jar文件
讯飞语音1.初始化语音识别()
讯飞语音1.设置语音识别参数(1,真)
讯飞语音1.初始化语音合成()
讯飞语音1.设置语音合成参数(1,50,50,50)
结束 事件
事件 讯飞语音1.语音识别初始化完毕(初始化结果 为 逻辑型)
如果 初始化结果 = 真 则
语音识别.可用=真
弹出提示("语音识别初始化成功")
否则
语音识别.可用=假
弹出提示("语音识别初始化失败")
结束 如果
结束 事件
事件 讯飞语音1.语音合成初始化完毕(初始化结果 为 逻辑型)
如果 初始化结果 = 真 则
弹出提示("语音合成初始化成功")
否则
弹出提示("语音合成初始化失败")
结束 如果
结束 事件
事件 语音识别.被单击()
讯飞语音1.开始语音识别()
结束 事件
事件 讯飞语音1.语音识别完毕(识别结果 为 逻辑型,识别内容 为 文本型)
变量 分割 为 文本型()
如果 识别结果 = 真 则
分割 = 分割文本(识别内容,"n")
如果 取数组下标(分割,1) > 0 则
如果 分割(0)="时间设置为10分钟。" 则
分=10
结束 如果
如果 分割(0)="时间设置为20分钟。" 则
分=20
结束 如果
如果 分割(0)="时间设置为30分钟。" 则
分=30
结束 如果
如果 分割(0)="强度增大。" 则
强度=强度+1
如果 到数值(强度) > 9 或 到数值(强度) < 0 则
弹出提示("请输入0-9数字" )
强度=强度-1
结束 如果
结束 如果
如果 分割(0)="强度减小。" 则
强度=强度-1
如果 到数值(强度) > 9 或 到数值(强度) < 0 则
弹出提示("请输入0-9数字" )
强度=强度+1
结束 如果
结束 如果
如果 分割(0)="模式选择为针灸模式。" 则
模式="针灸模式"
结束 如果
如果 分割(0)="模式选择为腰部模式。" 则
模式="腰部模式"
结束 如果
如果 分割(0)="模式选择为腿部模式。" 则
模式="腿部模式"
结束 如果
如果 分割(0)="模式选择为脑部模式。" 则
模式="脑部模式"
结束 如果
如果 分割(0)="启动。" 则
启动状态=1
如果 分 > 0 则
秒=59
毫秒=100
分=分-1
时间设置.可用=假
强度设置.可用=假
模式选择.可用=假
蓝牙1.发送数据(文本到字节(启动状态,"GBK"))
如果 分< 10 则
蓝牙1.发送数据(文本到字节(",0"&分,"GBK"))
否则
蓝牙1.发送数据(文本到字节(","&分,"GBK"))
结束 如果
如果 秒< 10 则
蓝牙1.发送数据(文本到字节(",0"&秒,"GBK"))
否则
蓝牙1.发送数据(文本到字节(","&秒,"GBK"))
结束 如果
蓝牙1.发送数据(文本到字节(","&强度,"GBK"))
蓝牙1.发送数据(文本到字节(","&模式序号,"GBK"))
启动.可用=假
按钮暂停.可用=真
时钟1.时钟周期 = 1
结束 如果
如果 分 = 0 则
弹出提示("请先设置时间")
结束 如果
结束 如果
如果 分割(0)="暂停。" 则
如果 按钮暂停.标题="暂停" 则
按钮暂停.标题="继续"
时间设置.可用=真
强度设置.可用=真
模式选择.可用=真
时钟1.时钟周期 = 0
启动状态=2
否则
时钟1.时钟周期 = 1
按钮暂停.标题="暂停"
时间设置.可用=假
强度设置.可用=假
模式选择.可用=假
启动状态=1
结束 如果
蓝牙1.发送数据(文本到字节(启动状态,"GBK"))
如果 分< 10 则
蓝牙1.发送数据(文本到字节(",0"&分,"GBK"))
否则
蓝牙1.发送数据(文本到字节(","&分,"GBK"))
结束 如果
如果 秒< 10 则
蓝牙1.发送数据(文本到字节(",0"&秒,"GBK"))
否则
蓝牙1.发送数据(文本到字节(","&秒,"GBK"))
结束 如果
蓝牙1.发送数据(文本到字节(","&强度,"GBK"))
蓝牙1.发送数据(文本到字节(","&模式序号,"GBK"))
结束 如果
如果 分割(0)="停止。" 则
秒 = 0
分 = 0
时 = 0
强度=0
启动状态=0
时间设置.可用=真
强度设置.可用=真
模式选择.可用=真
蓝牙1.发送数据(文本到字节(启动状态,"GBK"))
蓝牙1.发送数据(文本到字节(",0"&分,"GBK"))
蓝牙1.发送数据(文本到字节(",0"&秒,"GBK"))
蓝牙1.发送数据(文本到字节(","&强度,"GBK"))
蓝牙1.发送数据(文本到字节(","&模式序号,"GBK"))
启动.可用=真
按钮暂停.可用=假
结束 如果
标签1.标题 = "时间:"&到文本(时) & ":" & 到文本(分) & ":" & 到文本(秒)&"n"&"强度:"&到文本( 强度 )&" "&"模式:"&模式
结束 如果
弹出提示(分割(0))
否则
弹出提示("识别失败")
结束 如果
结束 事件
三、软件E4A5蓝牙技术说明
(一)使用串口助手或者HID转串口小助手

可以对HC-4或者更高级版本进行AT指令编辑。当HC-4蓝牙连接电脑时候,需要HC-USB-T 参数架配合使用,但当跟单片机具体硬件时候则可以HC-4蓝牙直接与单片机TXD和RXD通讯。具体执行图如图1 图2 图3

图1

图3
(二)在ESA5里需要三个控件,分别是蓝牙、位置传感器、权限操作,蓝牙初始化程序:
事件 主窗口.创建完毕()
如果 权限操作1.检查权限("android.permission.BLUETOOTH") = 真 且 权限操作1.检查权限("android.permission.BLUETOOTH_ADMIN") = 真 且 权限操作1.检查权限("android.permission.READ_PHONE_STATE") = 真 则
弹出提示("已获得权限,直接初始化蓝牙")
初始化蓝牙()
否则
弹出提示("未获得权限,开始申请权限")
权限操作1.申请全部权限()
结束 如果
结束 事件
事件 权限操作1.申请完毕(权限数组 为 文本型(),申请结果 为 整数型())
如果 权限操作1.检查权限("android.permission.BLUETOOTH") = 真 且 权限操作1.检查权限("android.permission.BLUETOOTH_ADMIN") = 真 且 权限操作1.检查权限("android.permission.READ_PHONE_STATE") = 真 则
初始化蓝牙()
否则
信息框("信息","蓝牙权限没有开启,请在应用的权限设置页面开启蓝牙权限!","确定")
权限操作1.打开权限设置()
结束 如果
结束 事件
过程 初始化蓝牙()
如果 蓝牙1.是否存在() = 假 则
信息框("信息","本机找不到蓝牙设备,程序将退出!","确定")
结束程序()
结束 如果
如果 蓝牙1.是否已开启() = 假 则
蓝牙1.开启蓝牙()
否则
蓝牙1.置工作模式(2)
结束 如果
结束 过程
事件 蓝牙1.蓝牙设置完毕(设置结果 为 整数型)
如果 设置结果 = 2则
蓝牙1.置工作模式(2)
结束 如果
结束 事件
蓝牙搜索:
事件 按钮1.被单击()
位置传感器1.开始监测() '在新版的安卓系统中,必须开启GPS定位才能搜索到蓝牙设备
列表框1.清空项目()
蓝牙1.搜索设备() '搜索设备
弹出提示("正在搜索")
结束 事件
发现蓝牙
发现蓝牙陈列:
事件 蓝牙1.发现设备(设备名称 为 文本型,设备地址 为 文本型,是否已配对 为 逻辑型)
列表框1.添加项目("理疗" & 列表框1.取项目数() & "-" & 设备地址 & "-" & 是否已配对)
列表框1.置项目标记(列表框1.取项目数()-1,设备地址)
结束 事件
选择列表框里蓝牙:
事件 列表框1.表项被单击(项目索引 为 整数型)
变量 设备地址 为 文本型
蓝牙索引=项目索引
设备地址 = 列表框1.取项目标记(项目索引)
标签1.标题=设备地址
保存对象("标签1",标签1)
'蓝牙1.连接设备(设备地址)'连接设备
'弹出提示("正在连接:" & 设备地址)
保存窗口("窗口1",创建 窗口1)'这句话很重要,要刷新作用,也是声明创新窗口
切换窗口(读取窗口("窗口1"))
结束 事件
关闭蓝牙:
事件 关闭蓝牙.被单击()
蓝牙1.断开连接() '退出处理,释放资源,结束内部处理线程
结束程序()
结束 事件
事件 蓝牙1.连接完毕(连接结果 为 逻辑型,设备名称 为 文本型,设备地址 为 文本型,连接模式 为 整数型)
变量 设备信息 为 文本型
变量 文本数组 为 文本型()
变量 启动窗口 为 主窗口
如果 连接结果 = 真 则
窗口1.标题 = "已连接:"
标签2.标题 = "已连接"
弹出提示("连接成功")
否则
标签2.标题 = "未连接"
弹出提示("连接失败")
结束 如果
结束 事件
值得注意是这两句全局定义控件,只有保持对象了,在其他窗口才可以引用,蓝牙功能就可以跨窗口操作:
保存对象("蓝牙1",蓝牙1)'这句话很重要,否则权限无法保存
保存窗口("主窗口",本对象) '本对象是当前窗口
四、软件E4A5串口发送和接收
发收具体命令:
蓝牙1.发送数据(文本到字节(启动状态,"GBK")),
其中启动状态是整数型或者文本型,字符可以直接接收,但是数字需要转换,单片机接收是ASCII值,所以接收不能直接接收,需要ASCII码转换,我是全部将命令以数字形式发送给单片机,单片机有ASCII码1-9转换表:uchar shijian[10]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};单片机接收只能是一个字符一个字符接收,ascii码减去字符0刚好等于对应的数字,一定要记得。
Recive_table[i]=SBUF;
摘取字符接收:if(Recive_table[i]=='x')//接到需要汇报
摘取数字接收:minute=(Recive_table[1]-'0')*10+(Recive_table[2]-'0');
接收具体命令:
E4A5接收字符串后需要用寻找文本(分割数据,"rp",0) >=0来分割字符,其中rp是寻找标记的起始位置,它的起始开始数字位为0,所以找一个字符其实就是到0那个位置就是准确位置。我们的字符串格式为zifu="rpm10Ms58Sq4Qa2Ab0B",分别代表分钟、秒、强度、模式、启动状态,例:如果 寻找文本(分割数据,"q",0) >0 则 强度= 取指定文本2(分割数据,"q","Q") 结束 如果
事件 蓝牙1.收到数据(数据 为 字节型(),设备名称 为 文本型,设备地址 为 文本型)
变量 收到数据 为 文本型
分割数据=字节到文本(数据,"GBK") ’串口通讯接收字符串
如果 寻找文本(分割数据,"y",0) >=0 则
弹出提示("程序已启动")
结束 如果
如果 寻找文本(分割数据,"n",0) >=0 则
弹出提示("程序已停止")
结束 如果
如果 寻找文本(分割数据,"z",0) >=0 则
弹出提示("程序已暂停")
结束 如果
'rpm10Ms58Sq4Qa2Ab0B
如果 寻找文本(分割数据,"rp",0) >=0 则
如果 寻找文本(分割数据,"m",0) >0 则
分=取指定文本2(分割数据,"m","M")
结束 如果
如果 寻找文本(分割数据,"s",0) >0 则
秒= 取指定文本2(分割数据,"s","S")
结束 如果
如果 寻找文本(分割数据,"q",0) >0 则
强度= 取指定文本2(分割数据,"q","Q")
结束 如果
如果 寻找文本(分割数据,"a",0) >0 则
模式数额= 取指定文本2(分割数据,"a","A")
如果 模式数额=0 则
模式="针灸模式"
结束 如果
如果 模式数额=1 则
模式="腰部模式"
结束 如果
如果 模式数额=2 则
模式="腿部按摩"
结束 如果
如果 模式数额=3 则
模式="脑部按摩"
结束 如果
结束 如果
如果 寻找文本(分割数据,"b",0) >0 则
启动状态= 取指定文本2(分割数据,"b","B")
如果 启动状态=0 则
按钮暂停.可用=假
启动.可用=真
时钟1.时钟周期 = 0
秒 = 0
分 = 0
时 = 0
强度=0
结束 如果
如果 启动状态=1 则
时钟1.时钟周期 = 1
按钮暂停.可用=真
启动.可用=假
结束 如果
如果 启动状态=2 则
时钟1.时钟周期 = 0
如果 按钮暂停.标题="暂停" 则
按钮暂停.标题="继续"
时钟1.时钟周期 = 0
否则
时钟1.时钟周期 = 1
按钮暂停.标题="暂停"
结束 如果
结束 如果
结束 如果
结束 如果
标签1.标题 = "时间:"&到文本(时) & ":" & 到文本(分) & ":" & 到文本(秒)&"n"&"强度:"&到文本( 强度 )&" "&"模式:"&模式
结束 事件
单片机发送字符串:
fasong_table[1]='r';
fasong_table[2]='p';
fasong_table[3]='m';
fasong_table[4]=shijian[minute/10];
fasong_table[5]=shijian[minute%10];
fasong_table[6]='M';
fasong_table[7]='s';
fasong_table[8]=shijian[second/10];
fasong_table[9]=shijian[second%10];
fasong_table[10]='S';
fasong_table[11]='q';
fasong_table[12]=shijian[stre];
fasong_table[13]='Q';
fasong_table[14]='a';
fasong_table[15]=shijian[mod];
fasong_table[16]='A';
fasong_table[17]='b';
fasong_table[18]=shijian[star_bol];
fasong_table[19]='B';
//zifu="rpm10Ms58Sq4Qa2Ab0B";
for(j=0;j<=19;j++)
{
TI=0; //请求发送标志位
SBUF=fasong_table[j];
while(!TI);
}
五、单片机几个定时器和中断器使用说明
定时器在该项目中非常重要,STC12C5A60S2只有两个定时器T0和T1,项目里T0当倒计时,对应中断3,T1当串口,对应中断4。但是2路模块PCA模块有独立2个16位定时器,可以很好释放T0和T1的工作压力。PCA模块里启用PWM模块时候需要启用寄存器TMR2和AUXR1特殊功能寄存器。这样才能启动独立的定时器。定时器有12T和1T的晶振频率,本项目使用是AUXR |= 0x04; 1T的晶振频率,使用12T启动不了PCA的PWM模块,具体如何我也没研究透。
串口初始化:
#define Timer0_Reload 18432 //T0 interrupt at 10ms @22.1184MHZ
sfr AUXR1 = 0xA2;
sfr AUXR = 0x8E;
sfr S2CON = 0x9A; //12C5A60S2双串口系列
sfr S2BUF = 0x9B; //12C5A60S2双串口系列
sfr IE2 = 0xAF; //STC12C5A60S2系列
sfr BRT = 0x9C;
/////////////
//sfr AUXR = 0x8E;
sfr CCON = 0xD8;
sfr CMOD = 0xD9;
sfr CCAPM0 = 0xDA; //PCA module 0 work mode
sfr CCAPM1 = 0xDB; //PCA module 1 work mode
sfr CL = 0xE9; //PCA counter
sfr CCAP0L = 0xEA; //PCA模块0的捕捉/比较寄存器低8位。
sfr CCAP1L = 0xEB; //PCA模块1的捕捉/比较寄存器低8位。
sfr PCA_PWM0 = 0xF2; //PCA模块0 PWM寄存器。
sfr PCA_PWM1 = 0xF3; //PCA模块1 PWM寄存器。
sfr CH = 0xF9;
sfr CCAP0H = 0xFA; //PCA模块0的捕捉/比较寄存器高8位。
sfr CCAP1H = 0xFB; //PCA模块1的捕捉/比较寄存器高8位。
sbit CCF0 = CCON^0; //PCA 模块0中断标志,由硬件置位,必须由软件清0。
sbit CCF1 = CCON^1; //PCA 模块1中断标志,由硬件置位,必须由软件清0。
sbit CR = CCON^6; //1: 允许PCA计数器计数,必须由软件清0。
sbit CF = CCON^7; //PCA计数器溢出(CH,CL由FFFFH变为0000H)标志。PCA计数器溢出后由硬件置位,必须由软件清0。
#define PWM0_NORMAL() PCA_PWM0 = 0 //PWM0正常输出(默认)
#define PWM0_OUT_0() PCA_PWM0 = 3 //PWM0一直输出0
#define PWM1_NORMAL() PCA_PWM1 = 0 //PWM1正常输出(默认)
#define PWM1_OUT_0() PCA_PWM1 = 3 //PWM1一直输出0
/************* 本地函数声明 **************/
void en_PCA(void);
void en_PWM(uchar channel,uchar start_value);
bit B_T0_interrupt;
void Uart_Init()
{
PCON &= 0x7F; //波特率不倍速https://blog.csdn.net/lzxiaotu/article/details/117666450
SCON = 0x50; //8位数据,可变波特率
AUXR |= 0x04; //独立波特率发生器时钟为Fosc,即1T
BRT = 0xDC; //设定独立波特率发生器重装值
AUXR |= 0x01; //串口1选择独立波特率发生器为波特率发生器
AUXR |= 0x10; //启动独立波特率发生器
EA = 1;//开总中断
ES = 1;//开串口中断
}
PWM初始化:
void pwm_init()
{
uint i;
en_PWM(0,pwmH_num); //load PWM value
en_PWM(1,pwmL_num); //load PWM value
en_PCA(); //enable PCA
EA = 1; //enable all interrupt
TMOD = 0x02; //T0 as 8 bit reload
TH0 = 0 - 10; //Reload time
AUXR |= 0x80; //T0 as 1T
ET0 = 0; //disable T0 interrupt
TR0 = 1; //enable T0
PWM0_NORMAL(); //PWM0 normal output
PWM1_NORMAL(); //PWM1 normal output
for(i=0; i< 10000; i++) ; //delay for output PWM
TR0 = 0; //disable T0
PWM0_OUT_0(); //PWM0 stop and putput 0
PWM1_OUT_0(); //PWM1 stop and putput 0
TMOD = 0x01; //T0 as 16bit timer
TL0 = (0 - Timer0_Reload) % 256; //load the 16bit time
TH0 = (0 - Timer0_Reload) / 256;
AUXR &= ~0x80; //T0 as 12T
ET0 = 1; //enable T0 interrupt
TR0 = 1; //enable T0
B_T0_interrupt = 0; //clear the T0 interrupt flag
while(!B_T0_interrupt); //wait the T0 interrupt
TR0 = 0; //disable T0
}
定时器初始化:
void TIM2Inital(void)
{
TMOD=0x10;//T1设置为定时器
TH1=(65536-50000)/256;//设定初值
TL1=(65536-50000)%256;
ET1=1;
EA=1;
TR1=0;//启动TR
}
六、单片机STC12C5A60S2芯片的pwm模块介绍与使用
单片机只有s2结尾才代表有独立的两个PCB模块,那么pwm是怎么发出呢?根据手册,本项目的串口大概是默认 RXD2为P1.2,可以切换到P4.2 ,TXD2默认为-P1.3,可以切换到P4.3。
本研究采用STC12C5A60S2单片机实现CCP脉冲波的精确控制。与传统51单片机相比,该单片机具有专用的AUXR辅助寄存器,使CCP脉冲波计时更为独立和准确[16]。本研究通过以下公式计算PWM频率初始值:

理疗仪的各种调制波形根据所需治疗效果进行定制,包括脉宽、脉冲间隔、持续时间和关断时间。实验中,共80名测试者分为A、B两组进行治疗效果对比。A组仅采用传统医疗手法,而B组则结合了本设备的辅助治疗。两周的治疗后,本研究对比了两组的效果,如表1所示。
表1 常规手法与设备辅助治疗效果的对比
| 组别 | 治疗部位 | 理疗手法 | 效果(%) | 汇总(%) |
| A组 | 腰部 | 锤击、揉捏 | 60 | 55 |
| A组 | 腿部 | 针刺、揉捏 | 50 | - |
| A组 | 手部 | 针刺、叩击、揉捏 | 70 | - |
| A组 | 头部 | 针刺、揉捏 | 40 | - |
| B组 | 腰部 | 锤击、揉捏 + 设备 | 80 | 82.5 |
| B组 | 腿部 | 针刺、揉捏 + 设备 | 90 | - |
| B组 | 手部 | 针刺、叩击、揉捏 + 设备 | 90 | - |
| B组 | 头部 | 针刺、揉捏 + 设备 | 70 | - |
研究利用示波器捕获了设备输出的治疗波形,以此验证设备的性能和治疗波形的一致性,如图4所示。

图4 PWM调制成治疗波形展示
具体代码:
void mol_methor()
{
switch(mod)
{
case 0:
pwmH_num=120;
pwmL_num=50;
if(jishi >15)
{
pwmH_num=50;
pwmL_num=120;
if(jishi==30)
{
jishi=0;
}
}
break;
case 1:
pwmH_num=130;
pwmL_num=100;
if(jishi >15)
{
pwmH_num=199;
pwmL_num=130;
if(jishi==30)
{
jishi=0;
}
}
break;
case 2:
pwmH_num=80;
pwmL_num=110;
if(jishi >15)
{
pwmH_num=110;
pwmL_num=80;
if(jishi==30)
{
jishi=0;
}
}
break;
default:
pwmH_num=160;
pwmL_num=110;
if(jishi >15)
{
pwmH_num=110;
pwmL_num=160;
if(jishi==30)
{
jishi=0;
}
}
break;
}
}
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !