上位机图像处理和嵌入式模块部署(mcu项目1:实现协议)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
这种mcu的嵌入式模块理论上都是私有协议,因为上位机和下位机都是自己开发的,所以只需要自己保证上、下位机可以通讯上,没有问题就行。但是现在有一个情况,那就是如何实现这个协议。现在我们是选择了ttl作为通信的方式,下面要做的就是如何用ttl实现通信协议。
1、上、下位机分开测试
前面准备好了通信的协议,各自就可以独立开发了。上位机可以用利用虚拟com进行测试,自己写一个假的下位机。而下位机呢,则可以通过串口工具来进行测试。一般来说,下位机如果测试没有问题了,才会去找上位机进行联合调试,不然调试的效率就太低了。
对于下位机来说,只要串口工具ok了,那么上位机不管是qt,还是mfc、c# wpf,只要按照协议把数据发下来,那就应该没问题的。
2、调试的时候一般都是通过16进制调试的
通常来说,发送的协议就是8位无符号数据,不是字符串。所以这个时候调试的时候,不管是接收命令,还是发送命令,最好都是通过16进制进行调试。

3、上位机一般是主动的那一方
通常来说,上位机都是主动的那一方。不管是去读数据,还是写数据,上位机都是主动发起请求的一方。这个时候,对于下位机来说,回复好上位机的问题,给出相应的答案就可以了。
4、压力测试是一定要的
协议解析的过程有可能出现不对的地方,这是很常见的。而且,随着开发的进行,有可能添加各种不同样的协议内容。所以不管哪一种协议,我们在实现和验证的时候,一定要进行压力测试,即通过串口工具周期性发送一些命令,这些都是可以的。单挑发送、多条发送、随机发送,一般的上位机工具都会支持这样的测试。
5、使用fsm去解析协议
串口的属性,决定了我们是一个、一个去接收数据的。这个时候就要求我们,需要根据这些单个的数据来判断它是否符合协议的要求。要做到这一点,最好的方法就是用有限状态机fsm去实现。比如说,首先是什么状态,接收到一个数据,应该是什么状态,是继续维持,还是说继续走向下一个状态。一般来说,只要状态机设计好,基本上固件都是非常稳定的。
void receiveUartData(void) // receive data and parse data here
{int index = 0;if (USART_ReadIntFlag(USART_UX, USART_INT_RXBNE) == SET){g_rx_buffer[0] = USART_RxData(USART_UX); /* receive one byte data*/switch(uartState){case HEAD_STATE1: // wait 0x55if(g_rx_buffer[0] == 0x55){g_usart_rx_buf[0] = g_rx_buffer[0];g_usart_rx_sta ++;uartState = HEAD_STATE2;}else{g_usart_rx_sta = 0;}break;case HEAD_STATE2: // wait another 0x55if(g_rx_buffer[0] == 0x55){g_usart_rx_buf[1] = g_rx_buffer[0];g_usart_rx_sta ++;uartState = TAIL_STATE1;}else{g_usart_rx_sta = 0;uartState = HEAD_STATE1;}break;case TAIL_STATE1: // wait 0xaaif(g_usart_rx_sta >= 32){g_usart_rx_sta = 0;uartState = HEAD_STATE1;break;}g_usart_rx_buf[g_usart_rx_sta] = g_rx_buffer[0];g_usart_rx_sta ++;if(g_rx_buffer[0] == 0xaa){uartState = TAIL_STATE2;}break;case TAIL_STATE2: // wait another 0xaag_usart_rx_buf[g_usart_rx_sta] = g_rx_buffer[0];g_usart_rx_sta ++;if(g_rx_buffer[0] == 0xaa && useFlag == 0) /* if useFlag = 0 or not qualified data, just drop it directly*/{for(index = 0; index < g_usart_rx_sta; index++){transferBuf[index] = g_usart_rx_buf[index];}bufLen = g_usart_rx_sta;useFlag = 1;}g_usart_rx_sta = 0;uartState = HEAD_STATE1;break;default:break;}USART_ClearIntFlag(USART_UX, USART_INT_RXBNE);}
}
6、协议的处理可以放到main里面继续进行
中断部分只是负责数据的接收,具体命令的解析可以放到main函数里面继续执行。毕竟接收数据本身是在中断函数处理的,这部分花的时间越少越好。而具体的数据解析,实时性没那么高,慢一点都是没有关系的。
extern uint16_t voltage; // add by feixiaoxing
int parseData() // use app tool to test the data
{unsigned char str[32] = {0};if(useFlag == 0){return -1;}if(0 == bufLen){setFlag();return -1;}if(bufLen < 4){setFlag();return -1;}if(transferBuf[0] != 0x55 || transferBuf[1] != 0x55){setFlag();return -1;}if(transferBuf[bufLen-2] != 0xaa || transferBuf[bufLen-1] != 0xaa){setFlag();return -1;}if(bufLen != 10) // header + length + commandid + crc + tail{setFlag();return -1;}// restore flagsetFlag();// prepare datastr[ 0] = 0x55; // headerstr[ 1] = 0x55;str[ 2] = 0x00; // lengthstr[ 3] = 0x08;str[ 4] = 0x00; // command id;str[ 5] = 0x00;str[ 6] = voltage / 1000; // datastr[ 7] = voltage % 1000;str[ 8] = 0x00; // crcstr[ 9] = 0x00;str[10] = 0xaa; // tailstr[11] = 0xaa;outputData((char*)str, 12);return 0;
}
相关文章:
上位机图像处理和嵌入式模块部署(mcu项目1:实现协议)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 这种mcu的嵌入式模块理论上都是私有协议,因为上位机和下位机都是自己开发的,所以只需要自己保证上、下位机可以通讯上&…...
【NLP学习笔记】load_dataset加载数据
除了常见的load_dataset(<hf上的dataset名>)这种方式加载HF上的所有数据外,还有其他custom的选项。 加载HF上部分数据 from datasets import load_dataset c4_subset load_dataset("allenai/c4", data_files"en/c4-train.0000*-of-01024.js…...
企业如何选择好用的供应商管理系统
供应商管理系统软件(SRM)是企业用于管理供应链中各个供应商关系的重要工具。现如今竞争激烈的市场环境下,选择一款合适的SRM软件显得尤为重要。那么,如何选择一款好用的供应商管理系统呢? 企业在选择好用的供应商管理…...
震惊!运气竟能如此放大!运气的惊人作用,你了解吗?
芒格:得到你想要的东西,最保险的办法,就是让自己配得上你想要的那个东西。今天仔细想了想这句话,他其实说的是无数成功人士的心声 —— “我配得上!” 美剧《绝命毒师》有个导演叫文斯吉里根(Vince Gilliga…...
记录一次Apache Tomcat 处理返回自定义的404页面
记录工作中遇到处理访问tomcat 不存在的资源,返回自定义的404页面 删除webapps目录下的example、docs、manager、hta-manager目录,只保留 ROOT目录,应用部署在了这个目录 删除 manager、hta-manager 我没有发现有什么异常 制作404.jsp 或者 4…...
【piania 的用法】
piania 的用法 定义store建议使用箭头函数TypeScript插件扩展1、全局添加对象 定义store import { ref, computed } from vue import { defineStore } from pinia // pinia 以函数的形式暴露出去 export const useCounterStore defineStore(counter, () > {// 1、ref 相当…...
上海计算机考研炸了,这所学校慎报!上海大学计算机考研考情分析!
上海大学(Shanghai University),简称“上大”,是上海市属、国家“211工程”重点建设的综合性大学,教育部与上海市人民政府共建高校,国防科技工业局与上海市人民政府共建高校,国家“双一流”世界…...
面对全球新能源汽车合作发展创维汽车如何实现共赢
由全球新能源汽车合作组织(筹)主办、中国电动汽车百人会承办的首届全球新能源汽车合作发展论坛(GNEV2024)于6月27日,6月28日在新加坡金沙会议展览中心召开。创维汽车国际营销公司总经理齐奎源受邀参会并作出分享。 本届大会以推动全球新能源汽车产业协同发展与合作…...
安全和加密常识(1)对称加密和非对称加密以及相应算法
文章目录 对称加密(Symmetric Encryption)非对称加密(Asymmetric Encryption)使用场景和优缺点对称加密和非对称加密是信息安全领域中两种重要的加密方式,它们分别使用不同的加密算法和密钥管理方式来保护数据的机密性。下面我来简单介绍一下它们及其相应的算法。 对称加…...
afrog-漏洞扫描(挖洞)工具【了解安装使用详细】
★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与学习之用,读者将信息做其他用途,由Ta承担全部法律及连带责任,文章作者不承担任何法律及连带责任。 1、afrog介绍 afrog 是一款性能卓越、快速稳定、PoC可定…...
c++类模板--无法解析的外部符号
解决办法 文章目录 解决办法方法1(推荐).在主函数包含头文件时将实现模板类的函数也包含进来方法2.将模板类的实现方法写在头文件里面方法3.函数模板声明前加inline 可能错误2,类内实现友元输出重载 方法1(推荐).在主函数包含头文件时将实现模板类的函数也包含进来 …...
Postman介绍
Postman 是一款流行的 API 开发和测试工具,它提供了一个直观的用户界面,使开发者可以轻松地构建、测试和修改 HTTP 请求。Postman 不仅适用于测试人员,也广泛应用于开发人员、产品经理和API设计者中,以确保API的正确性和性能。 以…...
以智能化为舵手,引领现代计算机系统架构新航向
编者按:如今计算机系统承载的服务和算法逻辑日益复杂,理解、设计并改进计算机系统已成为核心挑战。面对系统复杂度和规模的指数级增长,以及新的大模型驱动场景下的分布式系统形态的涌现,人们亟需创新方法与技术来应对。在计算机系…...
揭秘品牌成功秘诀:品牌营销策略的核心要素大公开
品牌营销作为企业战略中至关重要的一环,其核心是建立和传播品牌的独特魅力,使其在消费者心目中占据重要位置。 一个成功的品牌营销策略能够提升品牌的知名度和影响力,带来持续的销售和忠诚客户群体。 在当今竞争激烈的市场环境中࿰…...
java如何把list转换成map
不废话,直接上代码 public static void main(String[] args) {List<UserxVO> list new ArrayList<>();for (int i 0; i < 10; i) {list.add(new UserxVO("n" i, "dd" i));}Map<String, String> map list.stream().co…...
vite typescript 配置跨域代理
打开工程目录下vite.config.ts文件 export default defineConfig({plugins: [vue(), topLevelAwait()],resolve: { alias },server:{proxy:{/api:{ //对以 /api 开头的请求跨域处理target:http://xxx.xxx.cn,//目标服务器changeOrigin: true,rewrite:(path)>{return path.…...
ArcGIS Pro SDK (七)编辑 10 捕捉
ArcGIS Pro SDK (七)编辑 10 捕捉 文章目录 ArcGIS Pro SDK (七)编辑 10 捕捉1 配置捕捉 - 打开或关闭捕捉2 配置捕捉 - 应用程序捕捉模式3 配置捕捉 - 图层捕捉可捕捉性4 配置捕捉 - 图层捕捉模式5 配置捕捉 - 组合示例6 捕捉选项…...
开始尝试从0写一个项目--后端(一)
创建文件的目录结构 利用这个界面创建 序号 名称 说明 1 SEMS maven父工程,统一管理依赖版本,聚合其他子模块 2 sems-common 子模块,存放公共类,例如:工具类、常量类、异常类等 3 sems-pojo 子模块&#x…...
STM32第十二课:ADC检测烟雾浓度(MQ2)
文章目录 需求一、MQ-2 气体传感器特点应用电路及引脚 二、实现流程1.开时钟,分频,配IO2.配置ADC的工作模式3.配置通道4.复位,AD校准5.数值的获取 需求实现总结 需求 使用ADC将MQ2模块检测到的烟雾浓度模拟量转化为数字量。 最后,…...
1975react社区问答管理系统开发mysql数据库web结构node.js编程计算机网页源码
一、源码特点 react 社区问答管理系统是一套完善的完整信息管理类型系统,结合react.js框架和node.js后端完成本系统,对理解react node编程开发语言有帮助系统采用node框架(前后端分离)),系统具有完整的源…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
conda相比python好处
Conda 作为 Python 的环境和包管理工具,相比原生 Python 生态(如 pip 虚拟环境)有许多独特优势,尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处: 一、一站式环境管理:…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...
