C和Python的串口通信协议小技巧-创新互联
文章目录
由于进行串口通信的时候,只能传递 unsigned char(u8) 字节型的数据,所以就会有一些要将几个 u8 合并或者将 (unsigned int)u32 拆成4个 u8 的需求。
在此做一些总结归纳供大家参考,需要有一定嵌入式串口开发经验。在潞城等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供做网站、成都网站设计 网站设计制作按需定制网站,公司网站建设,企业网站建设,成都品牌网站建设,成都全网营销推广,成都外贸网站建设公司,潞城网站建设费用合理。C
分享文章:C和Python的串口通信协议小技巧-创新互联
文章路径:http://scgulin.cn/article/jcdhc.html
- C
- 取 u8
- 从 u8 数组取数据
- 使用联合体 union
- Python
- dict 功能帧
- struct 包
由于进行串口通信的时候,只能传递 unsigned char(u8) 字节型的数据,所以就会有一些要将几个 u8 合并或者将 (unsigned int)u32 拆成4个 u8 的需求。
在此做一些总结归纳供大家参考,需要有一定嵌入式串口开发经验。在潞城等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供做网站、成都网站设计 网站设计制作按需定制网站,公司网站建设,企业网站建设,成都品牌网站建设,成都全网营销推广,成都外贸网站建设公司,潞城网站建设费用合理。C
#define u32 unsigned int
#define s32 int
#define u16 unsigned short
#define s16 short
#define u8 unsigned char
#define s8 char
取 u8#define BYTE0(dwTemp) (*((char *)(&dwTemp)))
#define BYTE1(dwTemp) (*((char *)(&dwTemp) + 1))
#define BYTE2(dwTemp) (*((char *)(&dwTemp) + 2))
#define BYTE3(dwTemp) (*((char *)(&dwTemp) + 3))
例子:
u32 temp_data_32;
u8 buffer[4];
buffer[0] = BYTE0[temp_data_32];
buffer[1] = BYTE1[temp_data_32];
buffer[2] = BYTE2[temp_data_32];
buffer[3] = BYTE3[temp_data_32];
从 u8 数组取数据u8 data[num]; // 假设你所需的数据大量存在data数组中
// 取 8bit
u8 data_u8[num];
data_u8[0] = *(data);
data_u8[1] = *(data + 1);
...
// 取 16bit
u16 data_u16[num];
data_u16[0] = *((u16 *)(data));
data_u16[1] = *((u16 *)(data + 2));
data_u16[2] = *((u16 *)(data + 4));
...
s16 data_s16[num];
data_s16[0] = (*((s16 *)(data))) / 1.0f;
data_s16[1] = (*((s16 *)(data + 2))) / 1.0f;
data_s16[2] = (*((s16 *)(data + 4))) / 1.0f;
...
// 取 32bit
s32 data_s32[num];
data_s32[0] = *((s32 *)(data));
data_s32[1] = *((s32 *)(data + 4));
data_s32[2] = *((s32 *)(data + 8));
使用联合体 union使用联合体将float型数据拆分成字节数组
首先定义一个联合体
typedef union{float data;
uint8_t data8[4];
}data_u;
这个联合体中有两个成员,一个是32位的float数据data,另一个同样是占据了32位字长的字节数组data8,根据联合体的性质,这两个成员所在的内存位置是一样的,也就是说,改变其中任何一个成员的值,另一个也会被改变.利用这个性质,我们就可以实现float与字节数据的互换。
data_u _temp; // 声明一个联合体实例,使用它将待发送数据转换为字节数组
uint8_t data_to_send[100]; // 待发送的字节数组
data_to_send[_cnt++]=0xAA;
data_to_send[_cnt++]=0xBB;
// 将要发送的数据赋值给联合体的float成员
// 相应的就能更改字节数组成员的值
_temp.data = imu_data.yaw;
data_to_send[_cnt++]=_temp.data8[0];
data_to_send[_cnt++]=_temp.data8[1];
data_to_send[_cnt++]=_temp.data8[2];
data_to_send[_cnt++]=_temp.data8[3]; // 最高位
_temp.data = imu_data.pit;
data_to_send[_cnt++]=_temp.data8[0];
data_to_send[_cnt++]=_temp.data8[1];
data_to_send[_cnt++]=_temp.data8[2];
data_to_send[_cnt++]=_temp.data8[3]; // 最高位
_temp.data = imu_data.rol;
data_to_send[_cnt++]=_temp.data8[0];
data_to_send[_cnt++]=_temp.data8[1];
data_to_send[_cnt++]=_temp.data8[2];
data_to_send[_cnt++]=_temp.data8[3]; // 最高位
接收端同理,只要将接收到的数据逐个存入联合体的 data8[] 数组中就好,然后调用data进行使用。
Python dict 功能帧可以巧妙使用 Python 中的 dict 数据类型,以此来记入功能帧。
param_dic = {'speed': 0x01, 'voltage': 0x02, 'read': 0x03}
struct 包python struct
参考上面的官方文档,使用就好了
列举一些注意点:
- 注意本机字节顺序,可用
sys.byteorder
来检查你的系统字节顺序 - 解包(unpack)后,低字节在前,高字节在后
- 由于串口传递的是无符号字节型数据,若接收的变量是有符号类型如
h
格式,将自动进行如下操作。在C语言端的处理要注意
eg.
import struct
data = struct.pack('BBBBBBBB', 0xEA, 0xFF, 0x1E, 0x00, 0x64, 0x60, 0xEA, 0xFF) # 打包
print(data)
data = struct.unpack('
b'\xea\xff\x1e\x00d`\xea\xff'
-22
30
65514
data[0] = eaff = ffea = 65514-65536 = - 22
data[1] = 1e00 = 001e = 30
data[4] = eaff = ffea = 65514
因为有符号类型,最高位表示正负。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享文章:C和Python的串口通信协议小技巧-创新互联
文章路径:http://scgulin.cn/article/jcdhc.html