后台做网站的题html5购物网站
news/
2025/9/23 1:24:58/
文章来源:
后台做网站的题,html5购物网站,北京专业做网站设计公司,公司建设网站的优势总结这两天研究的蓝牙串口。人话版资料不多#xff0c;主要靠翻别人的仓库和文档。
单片机部分#xff0c;与蓝牙串口通信是通过串口。比我想的要简单#xff0c;小程序部分#xff0c;有非常多的服务和特征#xff0c;而且人话版资料不多。
如果本文有什么问题#xf…总结这两天研究的蓝牙串口。人话版资料不多主要靠翻别人的仓库和文档。
单片机部分与蓝牙串口通信是通过串口。比我想的要简单小程序部分有非常多的服务和特征而且人话版资料不多。
如果本文有什么问题或仍有不理解的地方可以私信交流。
HC08蓝牙串口
蓝牙部分已经由硬件厂商完成对外只暴露了几根铁丝与主机通信。 HC08与主机通信的协议是串口。 控制蓝牙串口模块不需要轮询0011只需要通过串口的方式向从机HC08发送命令即可。 连接与断开交由外设完成。连接成功之后就是一个串口对蓝牙通过串口发送的数据会透传到另一端传入的数据也会被串口响应。 配置HC08其实就是配置UART。也可以通过USB转TTL连接到电脑上。
配置串口
现在原理图中找到引脚所在的位置。 PA9和PA10也是USART的输入输出引脚。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_TIM1,ENABLE);GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_ModeGPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_PinGPIO_Pin_9;
GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz;
GPIO_Init(GPIOA,GPIO_InitStructure);GPIO_InitStructure.GPIO_ModeGPIO_Mode_IPU;
GPIO_InitStructure.GPIO_PinGPIO_Pin_10;
GPIO_InitStructure.GPIO_SpeedGPIO_Speed_50MHz;
GPIO_Init(GPIOA,GPIO_InitStructure);GPIO_SetBits(GPIOA,GPIO_Pin_10);
这款stm32已经集成了USART的硬件只需要调用库函数初始化。 具体的参数含义在之前的文章中有介绍。
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate9600;
USART_InitStructure.USART_HardwareFlowControlENABLE;
USART_InitStructure.USART_ModeUSART_Mode_Rx|USART_Mode_Tx;
USART_InitStructure.USART_ParityUSART_Parity_No;
USART_InitStructure.USART_StopBitsUSART_StopBits_1;
USART_InitStructure.USART_WordLengthUSART_WordLength_8b;
USART_Init(USART1,USART_InitStructure);硬件只是完成了读入读出操作在收到串口发来的电平变化时自动把1个字节的数据放入移位寄存器将USART_IT_RXNE标志位置为高电平。 在设置为高电平时触发中断读出一个字节的数据并清除中断标志。如果不清除会导致无法接收下一个字节的数据。
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannelUSART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmdENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority1;
NVIC_Init(NVIC_InitStructure);发送来的数据往往是多个字节的如何判断消息是否结束 通常的做法包括约定好消息尾比如当结尾为\r\n时标注当前消息已结束。 在本文中采用的方法是定时器中断。如果一段时间都没有新数据那么表面当前数据已经结束。
void TIM1_UP_IRQHandler(){if(rxBufferPointermillis-lastTime10){rxBufferPointer0;isOK1;}millis;TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
}每毫秒触发一次定时器中断存储一个定时值。 rxBufferPointer是指向下一个字节数据的指针。 当前消息结束时该指针应复位为0标志isOK置一。外界判断消息是否结束就是通过查看isOK标志的状态。
void USART1_IRQHandler(){if(USART_GetFlagStatus(USART1,USART_IT_RXNE)SET){lastTimemillis;rxBuffer[rxBufferPointer]USART_ReceiveData(USART1);rxSizerxBufferPointer;USART_ClearITPendingBit(USART1,USART_IT_RXNE);}
}如果消息没有结束自动将当前接收的数据存入rxBufferPointer指向的下一个字节位置。 将extern修饰的变量放到头文件中之后可以在导入这个头文件后直接读取。 数组大小256指针为8位最多指向256个内存地址。 传递的消息没有结束标志为了标注结束位置需要通过rxSize存储结束读取时的消息长度。 字符串比较需要用strcmp而不能用简单的。 这一部分简单带过配置蓝牙串口其实就是配置USART因为stm32与HC08的通信方式就是串口。更详细的配置过程可以翻看我之前的博客。
微信小程序
通用项目搭建
有小程序搭建经验的可以跳过这一部分。 创建一个微信小程序 没有AppID的可以去注册一个配置成什么样子几乎不影响之后开发。 我的选择是不使用云服务、JS基础模板。 设置全局统一样式 把这段代码CV到app.wxss中
page {font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica,Segoe UI, Arial, Roboto, PingFang SC, miui, Hiragino Sans GB, Microsoft Yahei,sans-serif;
}通过这段代码实现在不同设备上一样的显示情况。 干掉用不到的页面 删除logs文件夹。 在app.json中删除pages/logs/logs这一行。 其实不删也不影响使用 一个纯净的App()和Page() 删除app.js、index.wxml、index.wxss、index.js中的全部内容。 然后选择带有方块□的初始化模板。初始化app.js和index.js。 本文一共配置了三个页面另外两个页面的初始化同上。
pages: [pages/index/index,pages/BLE/Services/Services,pages/BLE/control/control
],设备扫描界面
这一步的目标是在index页面显示扫描到的蓝牙设备。 根据微信官方的要求流程为
开启蓝牙适配器开启扫描
蓝牙的可用状态和扫描状态可以在wx.onBluetoothAdapterStateChange()回调中获取。 扫描的设备可以在wx.onBluetoothDeviceFound()回调中获取。 为了方便调试
在App.js中挂载全局工具方法fail。将onBluetoothAdapterStateChange的通知结果打印在页面上。 app.js挂载全局的fail处理方法 App({fail:(res){wx.showToast({title: res.errMsg,icon:none})}
})index.js响应适配器状态改变事件 这里把onBluetoothAdapterStateChange单独封装挂载在this下。是为了使代码结构更清晰避免在onLoad()下出现层层嵌套。
Page({data: {available: false,discovering: false},onLoad: function (options) {this.onBluetoothAdapterStateChange();},onBluetoothAdapterStateChange() {wx.onBluetoothAdapterStateChange(({available,discovering}) {this.setData({available,discovering})})}
})在前端显示部分值方便后续调试。 开启适配器之后需要开始扫描。在扫描之前先设置设备发现后的处理函数。 这里的处理方案是把发现的设备添加到数组中。如果报告了重复的设备那么需要通过数组的.splice()方法替换为新的设备。 为了方便判断是否重复可以创建一个数组_deviceIds挂载在this下存储设备的唯一标识deviceId。 为了简化代码结构避免层层嵌套将代码实现单独封装挂载在this下。 开始搜索的点击事件为onTapDiscover。
button bind:taponTapDiscover{{discovering?结束搜索:开始搜索}}/button这一事件要根据当前情况执行不同的策略
如果未打开适配器那么开启适配器并在success回调中搜索蓝牙设备。如果已打开适配器但没有处于扫描状态那么直接开启扫描。如果正在扫描那么关闭扫描。
对于前两种情况在执行前需要清空已扫描到的设备列表以保证扫描到的设备都是最新有效的。
onTapDiscover() {if (this.data.discovering) {wx.stopBluetoothDevicesDiscovery();} else {this.setData({devices: []})this._deviceIds []if (this.data.available) {wx.startBluetoothDevicesDiscovery({allowDuplicatesKey: true})} else {this.openBluetoothAdapter();}}
},
openBluetoothAdapter() {wx.openBluetoothAdapter({success: () {wx.startBluetoothDevicesDiscovery({allowDuplicatesKey: true})},fail: getApp().fail})
}对于前端界面这不是本文的重点粗略带过具体的wxss设置可翻代码根据需求自定义。 通过onTapDevice函数处理连接事件通过data-deviceId传入。通过deviceId获取服务列表。 在成功连接之后应停止扫描关闭这一耗费资源的操作。 服务列表操作在新的页面完成。
onTapDevice(e){let deviceIde.currentTarget.dataset.deviceidwx.showModal({title: Connected or not,content: deviceId,success (res) {if (res.confirm) {getApp().Toast(connecting);wx.createBLEConnection({deviceId,success:(){wx.stopBluetoothDevicesDiscovery();wx.navigateTo({url: /pages/BLE/Services/Services?deviceId${deviceId}})}})}}})
}服务列表界面 这一步的操作比较少所以可以直接将获取服务列表的方法定义在onLoad里。 如果返回上一页面意味着中断连接。所以需要在onUnload方法中断开当前连接。 onUnload方法会在当页面的生命周期结束时自动执行。 具体的代码将在之后的源代码中呈现。本项目未使用第三方组件库为原生的微信小程序兼容大多数环境。
控制界面
这是本文中最复杂的部分。理解之后不复杂 在一开始我扫描到多个服务每个服务又有多个特征对此不知道该怎么做。 尽管有些特征携带了notify属性但在尝试notify的时候还是报错。或者read、write没有任何响应。 目前的解决方案是遍历服务特征尝试read/write/notify在success回调中设置服务特征为当前成功的这个。 目前在HC08上可以正常通信。 我之前的理解是在一个特征上同时进行read/write/notify。但实际可能是分散在多个特征上的共同完成同一个服务。 为了简化代码结构采用Command命令模式每个按钮执行的是同一个方法只是传入的命令参数不同。 HC08发送来的数据在onBLECharacteristicValueChange中处理。而不是read目前read是干什么的我也不清除。 发送来的是ArrayBuffer发出去的时候也要转换成ArrayBuffer需要实现
ab2strab2hexstr2ab
str就是字符串hex就是十六进制最终表现形式也是字符串ab是ArrayBuffer这种数据流传输的形式。2就是to为了省事读音相同就简写作了2。 具体过程可翻看源代码。 代码仓库https://github.com/WuShFeng/BLE 年轻人的第一辆新能源四驱 本文正值开学季中断了很多次有好多想写的都忘了。想起来的时候再补充。
参考
HC-08V3.1.pdfhttps://developers.weixin.qq.com/miniprogram/dev/framework/device/bluetooth.htmlhttps://github.com/zengwangfa/BluetoothControl
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910991.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!