设备间的指令通信

指令通信的概念

在这里插入图片描述
要进行设备和设备之间的交流就需要通过串口发送数据进行交流 而串口发送简单的数据只需要传输介质
但是要发送复杂的数据就需要介质和传输的规则了
在这里插入图片描述
三种应用场景
在这里插入图片描述
比如在上位机和mcu之间 通过上位机管理控制器 从而控制电池
在这里插入图片描述
单片机和单片机之间 用户输入数据到达控制的单片机 把指令给到负责图形显示的单片机 控制单片机和图形显示单片机就需要串口来进行数据的通信和交流

在这里插入图片描述
单片机要实现没有的功能需要外部模块的实现 也需要串口来进行通信和数据的传输

指令通信的方案概述

在这里插入图片描述
无论是什么情景都需要类似于主机给从机发指令 从机接收完成任务发送数到主机 这个过程 所以指令的学习很重要

单字符指令在这里插入图片描述
单个字符 如果通过串口给小车发w就是前进一米
dw就是右转前进一米 类似与这样 但是也有缺陷 就是如果想让小车前进0.5米就无法实现
字符串指令
在这里插入图片描述
如walk forwa 1就是表明走 前进 一格 turn left 向左转 通过发送不同的字符就可以发送不同的指令
但是效率有点低
二进制指令
在这里插入图片描述
二进制指令的格式为一个字节的同步码 两个字节的消息ID 一个字节的数据长度 一个字节的头校验 n个字节的数据 一个字节的数据校验
同步码 就是标志着二进制指令的开始 接收方看到这个0x5a就知道要从这里开始向后接收二进制指令了
消息ID 表示二进制指令的身份和作用 如图中的行走
0x0000代表行走 0x0001代表转弯
数据长度就代表数据的长度
数据 数据的长度不确定 根据消息的多少不确定 接收方在读取到数据长度了之后就知道要接受多长的数据了
头校验 在这里插入图片描述
把指令分为头和数据两个部分 校验头的正确或者错误
比如说有一个行走指令 行走的方向和行走的距离 就可以把这两个参数放到数据里面进行传输
那么就可以给小车设置一套指令集就是如行走消息ID就是0x0000 参数就为两个DIR方向 DIS 距离 如果想要向前就传入数0x000 向后就传入0x01 距离就传入1代表走1m 转弯也是如此在这里插入图片描述
注意第三个指令 在我们使用二进制传输的时候肯定是低字节在前高字节在低 如0x00 01 肯定是0x00在前 0x01在后 所以传输时是0x01在前 0x00在后 效率高很多 准确性也高很多
AT指令
在这里插入图片描述
总结
在这里插入图片描述

单字符指令

闪灯实验
在这里插入图片描述
具体就是led灯在两种模式下进行切换 状态变量stage 在case语句中 在这里插入图片描述
如在b点需要由亮起转为熄灭状态 判断时间是否超时 如调用函数PAL_GetTick()获得此时b点的时间 如果这个时间大于上次切换状态的时间(a点由熄灭转化为亮起的状态的时间)也就是这个黄色段内的时间在这里插入图片描述
加上需要亮起的时间onTime 就熄灭 然后获取当前的时间 切换状态 超时条件 b点时间大于a点由熄灭转化为亮起的状态的时间+需要亮起的时间onTime
也就是程序case1的代码
在这里插入图片描述
通过这四个函数就可以控制亮灭的不同 控制不同模式的闪烁

单字符指令实验

在这里插入图片描述
指令进程的编码思路
在这里插入图片描述
首先需要明确进程函数 有两个并行的任务一个是LED闪烁 一个是指令的接收
一个接受命令的初始化 一个中断函数(接收命令是通过串口 使用PAL库接收数据需要用到中断)
接受指令的函数的编写
首先需要从串口读取一个字节 超时时间为0因为在进程函数中不允许使用延时 所以设置超时时间TimeOut为0 然后判断是否接收到的数据是有效的 然后把接收到的数据强制类型转换为字符类型(因为我们接收到的指令是字符指令) 然后判断字符执行命令
app_blinky_led.c

#include "app_blinky_led.h"
#include "stm32f10x_pal.h"static uint32_t onTime = 10;
static uint32_t offTime = 100;
static uint8_t stage = 0;
static uint64_t lastToggleTime = 0;void App_BlinkyLED_SetOnTime(uint32_t Val)
{onTime = Val;
}void App_BlinkyLED_SetOffTime(uint32_t Val)
{offTime = Val;
}uint32_t App_BlinkyLED_GetOnTime(void)
{return onTime;
}uint32_t App_BlinkyLED_GetOffTime(void)
{return offTime;
}void App_BlinkyLED_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;GPIO_Init(GPIOC, &GPIO_InitStruct);
}void App_BlinkyLED_Proc(void)
{switch(stage){case 0: // 当前是熄灭状态if(PAL_GetTick() >= lastToggleTime + offTime){GPIO_ResetBits(GPIOC, GPIO_Pin_13);lastToggleTime = PAL_GetTick();stage = 1;}break;case 1: // 当前是点亮状态if(PAL_GetTick() >= lastToggleTime + onTime){GPIO_SetBits(GPIOC, GPIO_Pin_13);lastToggleTime = PAL_GetTick();stage = 0;}break;default:break;}
}

app_blinky_led.h

#ifndef __APP_BLINKY_LED_H__
#define __APP_BLINKY_LED_H__#include "stm32f10x.h"void App_BlinkyLED_Init(void);
void App_BlinkyLED_Proc(void);
void App_BlinkyLED_SetOnTime(uint32_t Val);
void App_BlinkyLED_SetOffTime(uint32_t Val);
uint32_t App_BlinkyLED_GetOnTime(void);
uint32_t App_BlinkyLED_GetOffTime(void);#endif

app_cmd.c

#include "app_cmd.h"
#include "stm32f10x_pal_usart.h"
#include "app_blinky_led.h"static PalUSART_HandleTypeDef hUSART3;void App_Cmd_Init(void)
{hUSART3.Init.USARTx = USART3;hUSART3.Init.BaudRate = 115200;hUSART3.Init.USART_WordLength = USART_WordLength_8b;hUSART3.Init.USART_StopBits = USART_StopBits_1;hUSART3.Init.USART_Parity = USART_Parity_No;hUSART3.Init.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;hUSART3.Init.USART_IRQ_PreemptionPriority = 0;hUSART3.Init.USART_IRQ_SubPriority = 0;hUSART3.Init.RxBufferSize = 128;hUSART3.Init.TxBufferSize = 128;PAL_USART_Init(&hUSART3);
}void App_Cmd_Proc(void)
{int16_t tmp;tmp = PAL_USART_ReceiveByte(&hUSART3, 0);if(tmp >=0){char c = (char)tmp;switch(c){case 'q': App_BlinkyLED_SetOnTime(App_BlinkyLED_GetOnTime()+10); break;case 'w': App_BlinkyLED_SetOnTime(App_BlinkyLED_GetOnTime()-10); break;case 'e': App_BlinkyLED_SetOffTime(App_BlinkyLED_GetOffTime()+10); break;case 'r': App_BlinkyLED_SetOffTime(App_BlinkyLED_GetOffTime()-10); break;}PAL_USART_Printf(&hUSART3, "On=%dms, Off=%dms\r\n", App_BlinkyLED_GetOnTime(), App_BlinkyLED_GetOffTime());}
}void USART3_IRQHandler(void)
{PAL_USART_IRQHandler(&hUSART3);
}

app_cmd.h

#ifndef __APP_CMD_H__
#define __APP_CMD_H__#include "stm32f10x.h"void App_Cmd_Init(void);
void App_Cmd_Proc(void);#endif

main.c

#include "stm32f10x.h"
#include "stm32f10x_pal.h"
#include "app_blinky_led.h"
#include "app_cmd.h"int main(void)
{PAL_Init();App_BlinkyLED_Init();App_BlinkyLED_SetOnTime(50);App_BlinkyLED_SetOffTime(50);App_Cmd_Init();while(1){App_BlinkyLED_Proc();App_Cmd_Proc();}
}

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

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

相关文章

国产麒麟操作系统部署记录

前提:部署项目首先要安装各种软件,在内网环境下无法在线下载。 思路:首先部署一台能上网的系统,在此系统下只下载包,然后传到另一台内网系统下进行安装; 1、最开始yum未安装,因此需要先安装yu…

C语言中的动态内存管理

在C语言中,动态内存管理是通过一系列的标准库函数来实现的,这些函数包括malloc, free, calloc 和 realloc。它们允许程序在运行时动态地分配和释放内存,这是管理复杂数据结构(如链表、树等)时非常有用的功能。 为什么…

硬件基础:运放

理想运算放大器 理想运算放大器放大倍数无穷大;输入端阻抗无穷大,所以输入端电流为0;输出电压和负载无关,不管负载怎么变化,输出电压都是固定的。 还有个就是输出阻抗为0; 输出阻抗越小,输出时就…

Avalonia中如何实现文件拖拽上传

前言 前面我们讲了在Avalonia中如何将View事件映射到ViewModel层感兴趣的读者可以看一下,本章我们将讲一下在Avalonia框架下如何实现文件和文字的拖拽到指定区域进行处理和上传。 先看效果 界面设计比较简单,还是在前一张的基础上加了一个指定区域&…

基于springboot + vue的社区医院信息系统

qq(2829419543)获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:springboot 前端:采用vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件&#xf…

leetcode 622. 设计循环链表

这道题讲了两种方法,第一个代码是用数组实现的,第二个是用链表实现的,希望对你们有帮助 (最好在VS自己测试一遍,再放到 leetcode上哦) 下面的是主函数(作参考),静下心来…

Ubuntu安装向日葵【远程控制】

文章目录 引言下载向日葵安装向日葵运行向日葵卸载向日葵参考资料 引言 向日葵是一款非常好用的远程控制软件。这一篇博文介绍了如何在 Ubuntu Linux系统 中安装贝瑞向日葵。🏃💥💥💥❗️ 下载向日葵 向日葵官网: https://sunl…

动态规划学习——最长回文子序列,让字符串变成回文串的最小插入次数

一,最长回文串 1.题目 给你一个字符串 s ,找出其中最长的回文子序列,并返回该序列的长度。 子序列定义为:不改变剩余字符顺序的情况下,删除某些字符或者不删除任何字符形成的一个序列。 示例 1: 输入&…

【我爱C语言】详解字符函数isdigit和字符串转换函数(atoi和snprintf实现互相转换字符串)三种strlen模拟实现

🌈write in front :🔍个人主页 : 啊森要自信的主页 ✏️真正相信奇迹的家伙,本身和奇迹一样了不起啊! 欢迎大家关注🔍点赞👍收藏⭐️留言📝>希望看完我的文章对你有小小的帮助&am…

煤矿电力监控系统

煤矿电力监控系统是一种用于煤矿电力系统的监控解决方案。该系统在重点煤矿的矿井变电站、主运输、主通风、主排水、主副提升等重要设备上加装智能用电融合终端,实时监测煤矿重要设备的电流、电压、负载等主要数据变化。为管理人员提供实时监测、报表管理、告警中心…

Centos7中的mysql环境安装以及卸载【Linux】

Linux中的mysql环境安装【Linux】 一. 检测mysql和mariadb是否存在二. 安装mysql2.1查看自身系统版本2.2 查看yum源2.3 选择yum源头2.4 安装yum源2.5 安装mysql2.6 启动mysql服务2.7 首次登录mysql 三. 卸载mysql3.1 关闭mysql服务3.2 查找并删除组件服务3.2.1 查找组件服务3.2…

漏洞复现-速达软件全系产品存在任意文件上传漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复,敏感信息均已做打码处理,文章仅做经验分享用途,切勿当真,未授权的攻击属于非法行为!文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

阿里年薪50w和5w都是如何进行需求分析,过来围观!

工作中难免会遇到并不“完美”的需求文档,比如牵一发而动全身却不清晰的交互逻辑、子条目频繁的变更、交流缺失导致的歧义等,都会让测试在项目推进中手足无措。 一份好的需求文档,不止能够加速开发和测试的脚步,还能够提前发现风…

【尘缘送书第五期】Java程序员:学习与使用多线程

目录 1 多线程对于Java的意义2 为什么Java工程师必须掌握多线程3 Java多线程使用方式4 如何学好Java多线程5 参与方式 摘要:互联网的每一个角落,无论是大型电商平台的秒杀活动,社交平台的实时消息推送,还是在线视频平台的流量洪峰…

Unity中Batching优化的GPU实例化(3)

文章目录 前言一、UNITY_SETUP_INSTANCE_ID(v);二、在UnityInstancing.cginc文件中,看一下Unity这句话做了什么1、使用了该 .cginc 后,会自动预定义该函数2、需要满足GPU实例化条件,才会执行对应语句3、满足GPU实例化后,主要执行的…

在UniApp中使用uni.makePhoneCall方法调起电话拨打功能

目录 1.在manifest.json文件中添加权限 2. 组件中如何定义 3.如何授权 4.相关知识点总结 1.在manifest.json文件中添加权限 {"permissions": {"makePhoneCall": {"desc": "用于拨打电话"}} }2. 组件中如何定义 <template>…

创建第一个 Flink 项目

一、运行环境介绍 Flink执行环境主要分为本地环境和集群环境&#xff0c;本地环境主要为了方便用户编写和调试代码使用&#xff0c;而集群环境则被用于正式环境中&#xff0c;可以借助Hadoop Yarn、k8s或Mesos等不同的资源管理器部署自己的应用。 环境依赖&#xff1a; 【1】…

【论文合集】在非欧空间中的图嵌入方法(Graph Embedding in Non-Euclidean Space)

文章目录 1. Hyperbolic Models1.1 Hyperbolic Graph Attention Network1.2 Poincar Embeddings for Learning Hierarchical Representations.1.3 Learning Continuous Hierarchies in the Lorentz Model of Hyperbolic Geometry1.4 Hyperbolic Graph Convolutional Neural Net…

【开源】基于Vue.js的假日旅社管理系统

文末获取源码&#xff0c;项目编号&#xff1a; S 078 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S078。} 文末获取源码&#xff0c;项目编号&#xff1a;S078。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统介绍2.2 QA 问答 三、系统展示四…

【实用经验】如何根据CVE编号找到安全补丁

找到对应补丁页面 例如查找编号为 CVE-2019-0708 的漏洞&#xff0c;访问下面链接即可&#xff0c;替换末尾编号可获取其他漏洞更新补丁。 https://msrc.microsoft.com/update-guide/vulnerability/CVE-2019-0708根据实际情况点击右侧补丁链接即可跳转下载 最后根据实际情况下…