当前位置:网站首页>仿SBUS与串口数据固定转换
仿SBUS与串口数据固定转换
2022-08-05 09:26:00 【CaewarfeneggerCao】
写在前面
无论如何,数据肯定是在嵌入式中无法避免的一个问题。杂乱无章的数据没有太大的意义。因此我们需要在源头将数据打包,组帧,再进行传输;抵达终端后进行解包,还原,读取出原始数据。
编程思路
该函数运用于一个简易的环境检测项目,使用到了LoRa模块,直接用单片机的串口驱动即可。但是使用的STM32F1系列单片机ADC为12位,存储变量又只有8位或16位,这其中需要进行数据转换。SBUS协议中帧头为0x0F,帧尾为0x00,倒数第二个字节为标志字节,计划将其作为一个紧急标志字节,例如正常情况是间隔一段时间报告一次采集节点周围环境情况;但有火情或是其它数据超过阈值,则立即发送数据。不过此次重点在于如何转换,为求简便,不考虑校验。
构建结构
typedef struct _SBUSData_Struct
{
uint16_t Channel[8];
uint8_t FlagByte;
} SBUSData_Struct;
具体函数
1.将串口数据转换为仿SBUS数据。
ErrorStatus Map_SCOMtoSBUS(SBUSData_Struct *SBUSdata,uint8_t *SCOMdata)
{
uint8_t ii;
if((SCOMdata == NULL) | (SCOMdata[0] != 0x0F)|(SCOMdata[13] != 0x00))
{
return ERROR;
}
SBUSdata->FlagByte = *(SCOMdata +12);
SBUSdata->Channel[0] = ((*(SCOMdata +2)<<8) | (*(SCOMdata +1))>>0)&0x07FF;
SBUSdata->Channel[1] = ((*(SCOMdata +3)<<5) | (*(SCOMdata +2))>>3)&0x07FF;
SBUSdata->Channel[2] = ((*(SCOMdata +5)<<10) | ((*(SCOMdata +4))<<2) | ((*(SCOMdata +3))>>6))&0x07FF;
SBUSdata->Channel[3] = ((*(SCOMdata +6)<<7) | (*(SCOMdata +5))>>1)&0x07FF;
SBUSdata->Channel[4] = ((*(SCOMdata +7)<<4) | (*(SCOMdata +6))>>4)&0x07FF;
SBUSdata->Channel[5] = ((*(SCOMdata +9)<<9) | ((*(SCOMdata +8))<<1) | ((*(SCOMdata +7))>>7))&0x07FF;
SBUSdata->Channel[6] = ((*(SCOMdata +10)<<6) | (*(SCOMdata +9))>>2)&0x07FF;
SBUSdata->Channel[7] = ((*(SCOMdata +11)<<3) | (*(SCOMdata +10))>>5)&0x07FF;
for(ii = 0; ii < 8; ii++)
{
if(SBUSdata->Channel[ii] > 2047)
{
SBUSdata->Channel[ii] = 2047;
}
}
return SUCCESS;
}
2.将仿SBUS数据转换为串口数据。
ErrorStatus Map_SBUStoSCOM(uint8_t *SCOMdata,SBUSData_Struct *SBUSdata)
{
uint8_t ii;
uint16_t Tempdata[16];
if(SBUSdata == NULL)
{
return ERROR;
}
*(SCOMdata + 0) = 0x0F;
*(SCOMdata + 13) = 0x00;
*(SCOMdata + 12) = SBUSdata->FlagByte;
for(ii=0;ii<8;ii++)
{
Tempdata[ii] = SBUSdata->Channel[ii] & 0x07FF;
}
*(SCOMdata + 1) = Tempdata[0] & 0xFF;
*(SCOMdata + 2) = (Tempdata[0]>>8)|(Tempdata[1]<<3);
*(SCOMdata + 3) = (Tempdata[1]>>5)|(Tempdata[2]<<6);
*(SCOMdata + 4) = (Tempdata[2]>>2);
*(SCOMdata + 5) = (Tempdata[2]>>10)|(Tempdata[3]<<1);
*(SCOMdata + 6) = (Tempdata[3]>>7)|(Tempdata[4]<<4);
*(SCOMdata + 7) = (Tempdata[4]>>4)|(Tempdata[5]<<7);
*(SCOMdata + 8) = (Tempdata[5]>>1);
*(SCOMdata + 9) = (Tempdata[5]>>9)|(Tempdata[6]<<2);
*(SCOMdata + 10) = (Tempdata[6]>>6)|(Tempdata[7]<<5);
*(SCOMdata + 11) = (Tempdata[7]>>3);
return SUCCESS;
}
写在后面
帧头和帧尾是固定的,标志字节暂时没有考虑,因为如果仅是“紧急情况”与“普通情况”,数据位数足够满足。本质上就是11个8bit的数据转换成8个11bit的数据。虽然说定义变量的时候仍然是uint16_t,即unsigned short int。但那是因为计算机是二进制,我不能定义11位的数据,但我可以定义了16位的数据,但只用到11位。例如函数中也有一个大于2047便等于2047的操作。因为12位ADC,最大值应该是4095,但全统一为11位,所以有此操作。
单单一种仿制的通信格式,刚刚接触的时候也是焦头烂额,遑论更完备的协议,要斟酌的东西太多了。还是要继续学习。
若是对数据要求只在二进制下,11位也可以传输12位的数据,传输前右移一位,传输后左移一位,便可以恢复。
边栏推荐
猜你喜欢
mysql进阶(二十七)数据库索引原理
pytorch余弦退火学习率CosineAnnealingLR的使用
Creo 9.0 基准特征:基准轴
ECCV 2022 Oral 视频实例分割新SOTA:SeqFormer&IDOL及CVPR 2022 视频实例分割竞赛冠军方案...
基于 Kubernetes 的微服务项目整体设计与实现
Undefined symbols for architecture arm64解决方案
使用HBuilder离线本地打包ipa教程
嵌入式实操----基于RT1170 移植memtester做SDRAM测试(二十五)
使用稀疏 4D 卷积对 3D LiDAR 数据中的运动对象进行后退分割(IROS 2022)
放大器OPA855的噪声计算实例
随机推荐
轩辕实验室丨欧盟EVITA项目预研 第一章(四)
flink cdc支持从oracle dg库同步吗
正则表达式replaceFirst()方法具有什么功能呢?
动态内存开辟(C语言)
IDEA执行Test操作导致数据插入时出现了重复数据
PAT Level B - B1021 Single Digit Statistics (15)
Science bosses say | Hong Kong rhubarb KaiBin teacher take you unlock the relationship between the matrix and 6 g
工程制图知识点
shell脚本实例
无题十一
Voice conversion相关语音数据集综合汇总
CPU的亲缘性affinity
15.1.1、md—md的基础语法,快速的写文本备忘录
线程之Happens-before规则
施一公:科学需要想象,想象来自阅读
pytorch余弦退火学习率CosineAnnealingLR的使用
2022-08-01 Review the basic binary tree and operations
上海控安技术成果入选市经信委《2021年上海市网络安全产业创新攻关成果目录》
5.部署web项目到云服务器
C语言-数组