电子说
一、软件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条评论
快来发表一下你的评论吧 !