第十三届蓝桥杯物联网试题(国赛)

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

还是那句话不能掉以轻心,全力以赴吧,遇事不要慌,该做的都做了,冷静沉稳的处理,看看配置,看看代码,还是不行就重启,都没问题换个板子

下面对比较复杂的部分的处理过程进行展现:

在这里插入图片描述
这个我是配合定时器和中断按键处理的,大致思路,按下按键在按键中断函数中将相应标志位置1

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){  // 按键//OLED_ShowString(0, "victory");STARTTEST = 1;MEMFLAG = 1;
}

主函函数识别标志位变为1则做相应ADC获取,以及OLED显示

void Function_StartAdc(){  if(STARTTEST == 1){//Function_OledInit(10);HAL_TIM_Base_Start_IT(&htim7);Function_GetAdc();Function_OledShow();HAL_GPIO_WritePin(K1_GPIO_Port, K1_Pin, GPIO_PIN_SET);}else {HAL_GPIO_WritePin(K1_GPIO_Port, K1_Pin, GPIO_PIN_RESET);OLED_Clear();//HAL_GPIO_WritePin(OLED_Power_GPIO_Port, OLED_Power_Pin, GPIO_PIN_SET);}
}

检测数值是否稳定,在第一次获取ADC数值的时候备份一下,在定时器里去分析是否稳定,不稳定定时器计数值归零否者继续计数

void Function_GetAdc(){uint16_t AdcData[2];for(unsigned char i = 0; i < 2; i ++){HAL_ADC_Start(&hadc);HAL_ADC_PollForConversion(&hadc, 0xff);AdcData[i] = HAL_ADC_GetValue(&hadc);HAL_Delay(5);}HAL_ADC_Stop(&hadc);RP1Value = AdcData[1] * 3.30f / 4095;RP2Value = AdcData[0] * 3.30f / 4095;if(MEMFLAG == 1){  // 做备份MEMFLAG = 0;MEMRP1VALUE = RP1Value;MEMRP2VALUE = RP2Value;}if(RP1Value <= 3.3) WT = RP1Value * 80 / 3.3;else WT = 80;if(RP2Value <= 1) BF = 5;else if(RP2Value > 1 && RP2Value < 2) BF = RP2Value * 40 - 35;else BF = 45;
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  // 10ms//OLED_ShowString(0, "victory");if(STARTTEST == 1){ // 测量体重if(COUNTNUMBER >= 300){//HAL_TIM_Base_Stop_IT(&htim7);STARTTEST = 0;TESTVICTORY  = 1;COUNTNUMBER = 0;sprintf((char* )SENDMSG, "#%.1f#%.1f", WT, BF);LORA_Tx(SENDMSG, 20);}			DERTARP1 = RP1Value - MEMRP1VALUE;DERTARP2 = RP2Value  - MEMRP2VALUE;if(DERTARP1 > -0.1 && DERTARP1 < 0.1 && DERTARP2 > -0.1 && DERTARP2 < 0.1) COUNTNUMBER ++;else {MEMRP1VALUE = RP1Value;MEMRP2VALUE = RP2Value;COUNTNUMBER = 0;}}if(TESTVICTORY == 1){  // LD5闪烁if(COUNTNUMBER <= 300) {COUNTNUMBER ++;if(COUNTNUMBER % 10 == 0) HAL_GPIO_TogglePin(LD5_GPIO_Port, LD5_Pin);}else{TESTVICTORY = 0;HAL_TIM_Base_Stop_IT(&htim7);HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_SET);COUNTNUMBER = 0;}}
}

LD5是每0.1s反转一次,也就是整10位反转,所以直接%10即可

够3s后OLED直接清屏就行,断开电源开启还要初始化很麻烦

在这里插入图片描述
储存用结构体

typedef struct{unsigned char MEMWT[10];unsigned char MEMBF[10];
}MEMO;

符合要求得数据直接memcpy过来就行

在这里插入图片描述

对于LORA传输的数据要做一些处理,再判断

void Function_LorRxHandle(){if(RECEIVEMSG[0] == '#'){Function_ArrayClean(RXWT, sizeof(WT));Function_ArrayClean(RXBF, sizeof(BF));unsigned char i = 1;unsigned char j = 0;while(RECEIVEMSG[i] != '#') RXWT[j ++] = RECEIVEMSG[i ++];i ++;j = 0;while(RECEIVEMSG[i] != '\0') RXBF[j ++] = RECEIVEMSG[i ++];//OLED_ShowString(0, WT);//OLED_ShowString(2, BF);TPRXBF = strtof((char* )RXBF, NULL);TPMAXBF = strtof((char* )MAXBF, NULL);TPMINBF = strtof((char* )MINBF, NULL);if(!(TPRXBF >= TPMINBF && TPRXBF <= TPMAXBF)){HAL_TIM_Base_Start_IT(&htim7);}else{HAL_TIM_Base_Stop_IT(&htim7);HAL_GPIO_WritePin(LD5_GPIO_Port, LD5_Pin, GPIO_PIN_SET);Function_ArrayClean(WT, sizeof(WT));Function_ArrayClean(BF, sizeof(BF));memcpy(BF, RXBF, 10);memcpy(WT, RXWT, 10);memcpy(MEMORX[INDEX].MEMBF, BF, 10);memcpy(MEMORX[INDEX].MEMWT, WT, 10);INDEX = (INDEX + 1) % 20;}}if(RECEIVEMSG[0] != '\0') Function_ArrayClean(RECEIVEMSG, sizeof(RECEIVEMSG));
}
        unsigned char i = 1;unsigned char j = 0;while(RECEIVEMSG[i] != '#') RXWT[j ++] = RECEIVEMSG[i ++];i ++;  // 跳过'#'j = 0;while(RECEIVEMSG[i] != '\0') RXBF[j ++] = RECEIVEMSG[i ++];

这一步部分的作用是将例如#value1#value2分别取出来,因为value1和2的位数不知道所以用memcpy是不行的,这就要用算法来操作了

操作之前记得将数组里的值清除一下,防止这次的数据被前面接收的数据污染:

void Function_ArrayClean(unsigned char* array, uint16_t len){for(unsigned char i = 0; i < len; i ++) array[i] = '\0';
}
if(RECEIVEMSG[0] != '\0') Function_ArrayClean(RECEIVEMSG, sizeof(RECEIVEMSG));

将处理函数放外面是因为,比赛可能有其他人发送的数据可能会被误收,更要清除

在这里插入图片描述

对串口数据的处理更是将神器strtof函数运用到极致,真是不得不佩服大佬写的函数

void Function_UartRxMsgHandle(){if(UARTRXMSG[0] != '\0'){HAL_Delay(10);//OLED_ShowString(0, UARTRXMSG);TEMP = strtof((char* )UARTRXMSG, &p);if(*p == '\0'){  // 查询指令if(TEMP >= 1 && TEMP <= 20){Function_ArrayClean(SENDMSG, sizeof(SENDMSG));sprintf((char* )SENDMSG, "WT:%sKG,BF:%s%%", MEMORX[(int)TEMP - 1].MEMWT, MEMORX[(int)TEMP - 1].MEMBF);HAL_UART_Transmit(&huart2, SENDMSG, sizeof(SENDMSG), 0xff);}else{HAL_UART_Transmit(&huart2, (unsigned char* )SDERREOR, strlen(SDERREOR), 0xff);}}else if(*p == ','){  // 改变指令Function_ArrayClean(TEMPUARTRX, sizeof(TEMPUARTRX));unsigned char i = 0;unsigned char j = 0;while(UARTRXMSG[i ++] != ',');while(UARTRXMSG[i] != '\0') TEMPUARTRX[j ++] = UARTRXMSG[i ++];TEMP1 = strtof((char* )TEMPUARTRX, &q);if(*q == '\0' && TEMP <= TEMP1 && TEMP >= 0 && TEMP <= 45 && TEMP1 >= 0 && TEMP1 <= 45){sprintf((char* )MINBF, "%d", (int)TEMP);sprintf((char* )MAXBF, "%d", (int)TEMP1);}else HAL_UART_Transmit(&huart2, (unsigned char* )SDERREOR, strlen(SDERREOR), 0xff);}else HAL_UART_Transmit(&huart2, (unsigned char* )SDERREOR, strlen(SDERREOR), 0xff);Function_ArrayClean(UARTRXMSG, sizeof(UARTRXMSG));}
}

延时10ms是因为是DMA接收,所以让CPU别急着处理让DMA将数据接受完再处理

之前讲过strtof的性质,将字符串转换成浮点型直到不能转换为止,所以利用这个性质:
将数据先全部转换一次,如果全部都能转换即指针指向空字符,那么就是查询语句,如果指针指向’,‘那就说明是设置值命令,如果指向的是其他字符,则可返还错误,如果指向‘,’此时可利用上面分割#字符的方式将’,'字符分割到另一个数组做分析,再次分析另一个设置数据合不合法

            while(UARTRXMSG[i ++] != ',');while(UARTRXMSG[i] != '\0') TEMPUARTRX[j ++] = UARTRXMSG[i ++];

先跳过第一个‘,’再对后一个字符串做处理

这个处理过程让我找到了后端开发的感觉,先写主体判断框架,再实现框架内部内容

这一部分得慢慢来慢慢调试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/19334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git报错prohibited by Gerrit: not permitted: update

git push报错&#xff1a; Push to refs/for/[branch] to create a review, or get Push rights to update the branch. Contact an administrator to fix the permissions (prohibited by Gerrit: not permitted: update)原因&#xff1a; 使用Gerrit代码审核时&#xff0c;本…

CentOS 7基础操作02_优化Linux操作系统中的服务

1、实验环境 公司在文件服务器中新安装了CentOS系统.由于默认启动的服务程序较多&#xff0c;系统运行缓慢。现需要对系绞服务进行适当优化&#xff0c;减少一些不必要的自启动服务.并设置系统在开机后直接进入字符模式。 2、需求描述 根据实际使用需求对CentOS 7操作系统中的…

postgressql——PGPROC XLOG(6)

PGPROC相关结构 在共享内存中,核心数据结构围绕PROC_HDR指向的两个list:PROC和XACT PRCO内存连续,维护链表结构方便申请释放,对应每个后台服务进程,PID为OS标识、PGPROCNO为内部标识 XACT内存连续,维护快照需要的xmin和xid,XACT从PROC拆出来是为了更高的cache line命中…

IBM开源Granite Code模型,多尺寸可选,支持多种代码任务,性能媲美 CodeLlama

前言 近年来&#xff0c;大型语言模型&#xff08;LLM&#xff09;在代码领域展现出惊人的潜力&#xff0c;为软件开发流程带来了革命性的改变。代码 LLM 不仅能够生成高质量代码&#xff0c;还能帮助程序员修复错误、解释代码、编写文档等等&#xff0c;极大地提高了软件开发…

【kubernetes】探索k8s集群的存储卷、pvc和pv

目录 一、emptyDir存储卷 1.1 特点 1.2 用途 1.3部署 二、hostPath存储卷 2.1部署 2.1.1在 node01 节点上创建挂载目录 2.1.2在 node02 节点上创建挂载目录 2.1.3创建 Pod 资源 2.1.4访问测试 2.2 特点 2.3 用途 三、nfs共享存储卷 3.1特点 3.2用途 3.3部署 …

Web程序设计-实验05 DOM与BOM编程

题目 【实验主题】 影视网站后台影视记录管理页设计 【实验任务】 1、浏览并分析多个网站后台的列表页面、编辑页面&#xff08;详见参考资源&#xff0c;建议自行搜索更多后台页面&#xff09;的主要元素构成和版面设计&#xff0c;借鉴并构思预期效果。 2、新建 index.h…

正则匹配优化:匹配排除多个字符串的其他字符串

(^entity|^with|...)\w优化 (?!entity|with|has|index|associations|input)\w(?!): 匹配排除项 效果 继续优化 匹配会过滤掉带有关键字的字段&#xff0c;在过滤的时候是可以加上尾部结束匹配符的 效果&#xff1a;

thinkphp6 自定义的查询构造器类

前景需求&#xff1a;在查询的 时候我们经常会有一些通用的&#xff0c;查询条件&#xff0c;但是又不想每次都填写一遍条件&#xff0c;这个时候就需要重写查询类&#xff08;Query&#xff09; 我目前使用的thinkphp版本是6.1 首先自定义CustomQuery类继承于Query <?p…

【C语言回顾】预处理

前言1. 简单概要2. 预处理命令讲解结语 上期回顾: 【C语言回顾】编译和链接 个人主页&#xff1a;C_GUIQU 归属专栏&#xff1a;【C语言学习】 前言 各位小伙伴大家好&#xff01;上期小编给大家讲解了C语言中的编译和链接&#xff0c;接下来我们讲解一下预处理&#xff01; …

【香橙派 AIpro】新手保姆级开箱教程:Linux镜像+vscode远程连接

香橙派 AIpro 开发板 AI 应用部署测评 写在最前面一、开发板概述官方资料试用印象适用场景 二、详细开发前准备步骤1. 环境准备2. 环境搭建3. vscode安装ssh插件4. 香橙派 AIpro 添加连接配置5. 连接香橙派 AIpro6. SSH配置 二、详细开发步骤1. 登录 juypter lab2. 样例运行3. …

【IDEA】-使用IDEA查看类之间的依赖关系

1、父子类的继承、实现关系 1.1、使用CTRL Alt U 选择 java class 依据光标实际指向的类位置 用实心箭头表示泛化关系 是一种继承的关系&#xff0c;指向父类 可以提前设置需要显示的类的属性、方法等信息 快捷键 Ctrl Alt S &#xff0c;然后搜索 Diagrams 1.2、使用…

python知识继续学习

1、计算机表示小数是有误差的&#xff0c;下面的5就是误差 2、在python中&#xff0c;所有的非0数字都是True&#xff0c;零是False。所有的非空字符串都是True&#xff0c;空字符串是False。空列表是False。在python的基本数据类型中&#xff0c;表示空的东西都是False&#x…

数据结构(三)循环链表 约瑟夫环

文章目录 一、循环链表&#xff08;一&#xff09;概念&#xff08;二&#xff09;示意图&#xff08;三&#xff09;操作1. 创建循环链表&#xff08;1&#xff09;函数声明&#xff08;2&#xff09;注意点&#xff08;3&#xff09;代码实现 2. 插入&#xff08;头插&#x…

【linux】运维-基础知识-认知hahoop周边

1. HDFS HDFS&#xff08;Hadoop Distributed File System&#xff09;–Hadoop分布式文件存储系统 源自于Google的GFS论文&#xff0c;HDFS是GFS的克隆版 HDFS是Hadoop中数据存储和管理的基础 他是一个高容错的系统&#xff0c;能够自动解决硬件故障&#xff0c;eg&#xff1a…

【Linux 网络编程】网络的背景、协议的分层知识!

文章目录 1. 计算机网络背景2. 认识 "协议"3. 协议分层 1. 计算机网络背景 网络互联: 多台计算机连接在一起, 完成数据共享; &#x1f34e;局域网&#xff08;LAN----Local Area Network&#xff09;: 计算机数量更多了, 通过交换机和路由器连接。 &#x1f34e; 广…

多模态模型入门:BLIP与OWL-ViT

BLIP 数据预处理 CapFilt&#xff1a;标题和过滤 由于多模态模型需要大量数据集&#xff0c;因此通常必须使用图像和替代文本 (alt-text) 对从互联网上抓取这些数据集。然而&#xff0c;替代文本通常不能准确描述图像的视觉内容&#xff0c;使其成为噪声信号&#xff0c;对于…

MAC M1 —— Install

文章目录 MAC M1 —— Install安装IDEA安装JDK安装Maven安装brew无法创建文件 /data/serverMac 修改终端用户名&#xff08;主机名&#xff09;PyCharm MAC M1 —— Install 安装IDEA 关键词&#xff1a;2020到2021.3的激活步骤。找下Download文件夹 安装JDK 在个人的电脑上…

《探索Stable Diffusion:AI绘画的创意之路与实战秘籍》

《Stable Diffusion AI 绘画从提示词到模型出图》介绍了 Stable Diffusion AI 绘画工具及其使用技巧。书中内容分为两部分&#xff1a;“基础操作篇”&#xff0c;讲解了 SD 文生图、图生图、提示词、模型、ControlNet 插件等核心技术的应用&#xff0c;帮助读者快速从新手成长…

java中,怎样用最简单方法实现写word文档

在跨平台环境中实现写word时&#xff0c;如果用现成的库&#xff0c;就会涉及跨平台兼容性问题&#xff0c;比如在安卓与java中实现写word的功能。还有一个问题就是&#xff0c;完全用程序生成word文档&#xff0c;工作量较大。所以采用了模板替换的方法。 docx文档本质就是一…

算法与数据结构:二叉排序树与AVL树

ACM大牛带你玩转算法与数据结构-课程资料 本笔记属于船说系列课程之一&#xff0c;课程链接&#xff1a; 哔哩哔哩_bilibilihttps://www.bilibili.com/cheese/play/ep66799?csourceprivate_space_class_null&spm_id_from333.999.0.0 你也可以选择购买『船说系列课程-年度会…