当前位置:网站首页>仿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位的数据,传输前右移一位,传输后左移一位,便可以恢复。
边栏推荐
- Marketing Suggestions | You have an August marketing calendar to check! Suggest a collection!
- 今天是元宵节~~
- Dry goods!Generative Model Evaluation and Diagnosis
- The Seven Weapons of Programmers
- Neuron Newsletter 2022-07|新增非 A11 驱动、即将支持 OPC DA
- The Secrets of the Six-Year Team Leader | The Eight Most Important Soft Skills of Programmers
- 如何实现按键的短按、长按检测?
- 只有一台交换机,如何实现主从自动切换之nqa
- 【LeetCode】623. 在二叉树中增加一行
- 手写柯里化 - toString 理解
猜你喜欢
基于 Kubernetes 的微服务项目整体设计与实现
pytorch余弦退火学习率CosineAnnealingLR的使用
2.4G无线收发模块的应用
Creo 9.0 基准特征:基准平面
为什么我推荐使用智能化async?
营销建议 | 您有一份八月营销月历待查收! 建议收藏 !
Thinking and summary of the efficiency of IT R&D/development process specification
基因数据平台
Overall design and implementation of Kubernetes-based microservice project
开源一夏|OpenHarmony如何查询设备类型(eTS)
随机推荐
无题八
leetcode points to Offer 10- I. Fibonacci sequence
Xcode10的打包方式distribute app和启动项目报错以及Xcode 打包本地ipa包安装到手机上
链表中的数字相加----链表专题
my journal link
Thinking and summary of the efficiency of IT R&D/development process specification
Creo 9.0 基准特征:基准坐标系
Redis源码解析:Redis Cluster
EU | Horizon 2020 ENSEMBLE: D2.13 SOTIF Safety Concept (Part 2)
无题五
PAT乙级-B1020 月饼(25)
openpyxl to manipulate Excel files
工程制图知识点
flink cdc支持从oracle dg库同步吗
mysql进阶(二十七)数据库索引原理
19.服务器端会话技术Session
无题十
Example of Noise Calculation for Amplifier OPA855
无题四
新白娘子传奇系列