蓬山此去无多路,青鸟殷勤为探看。——唐·李商隐《无题》
青鸟编码器是一个数据编码/解码的工具库,可用于嵌入式系统间的数据通信:
- 编码:将 int16/uint16 数组编码为数据帧(字节数组)
- 解码:将数据帧(字节数组)解码为 int16/uint16 数组
- 开发 C51 版本,对 C51 版本进行测试
- 目前 C51 版本暂时不可用,测试未通过
- 合并 C 与 C51 版本
- 进行版本测试
- STM32
- STC89C52
- 进行版本测试
- 开发 Lua 版本
- C 语言版本只支持小端序的嵌入式系统,不支持大端序的硬件(如 51单片机)
- C51(大端序) 的版本的青鸟编码器正在开发中
- 如果不知道当前平台是大端序还是小端序,可以使用下列代码进行测试:
/** * 或取当前平台的字节序类型 * @return {int} 1:小端序,0:大端序,-1:获取出错 */intget_endianness()
{
union__Data
{
shortnum;
chardatas[2];
} Data;
Data.num=0x1234;
if(Data.datas[0] ==0x34)
{
// 小端序return1;
}
elseif(Data.datas[0] ==0x12)
{
// 大端序return0;
}
else
{
// 错误return-1;
}
}Python 版本同时兼容 MicroPython 和 Python3.X,支持的部分平台如下:
MicroPython
- OpenMV
- MaixPy(K210)
- CanMV
- 树莓派 Pico
- ESP32 等
Python3.X
- 树莓派
- 香橙派
- 各种 Linux 开发板 等
C 语言版本兼容各种小端序的嵌入式平台(51 单片机等大端序的硬件请使用 C51 版本),支持的部分平台如下(兼容 C++):
- STM32
- K210
- Arduino
- 树莓派 Pico
- ESP32
- ESP8266
- MSP430
- MSP432
- 各种 ARM 单片机
- 各种 RISC-V 单片机
- 各种 Linux 开发板 等
C51 版本兼容 51 单片机等大端序的硬件平台,支持的部分平台如下:
- AT89CXX
- STC89CXX
Lua 版本支持 LuatOS 平台。
- Air101
- Air103
- Air105 等支持 LuatOS 的单片机
importbluebird_encodersend_datas= [-1234, -567, 1456, 32767]
print("原数组:", send_datas)
bluebird=bluebird_encoder.BlueBird()
# 编码sended_bytes=bluebird.pack(send_datas, is_int16=True)
print("编码后的字节数组:", ",".join([hex(a) forainsended_bytes]))
# 通过串口发送编码后的字节数组# uart.send(sended_bytes) # 方法一# bluebird.send(uart.send) # 方法二# 解码recieved_bytes= [0xeb, 0x90, 0x9, 0x2e, 0xfb, 0xc9, 0xfd, 0xb0, 0x5, 0xff, 0x7f, 0x22, 0xbe]
forchar_inrecieved_bytes:
# 每次只处理一个字节# chr 是串口接收到的长度为 1 的字节数组,一般是 uart.read(1) 返回的值chr=bytes([char_])
unpacked_data=bluebird.unpack(chr)
ifunpacked_data: # 如果解码完成print("解码后的数组:", unpacked_data)#include<stdio.h>#include"bluebird_encoder/bluebird_encoder.h"/** * 串口发送函数,需要根据单片机的类型进行重写 * @param {uint8_t} *chr 要发送的字节数据 * @param {int} length 字节数组的长度 * @return {*} */voiduart_send(uint8_t*chr, intlength)
{
for (inti=0; i<length; i++)
{
printf("串口发送:0x%02X\n", chr[i]);
}
}
intmain()
{
Data_tdata_packed;
Data_tdata_unpacked;
// 初始化数据结构体bluebird_init(&data_packed);
bluebird_init(&data_unpacked);
#if1// 将数据编码为字节数组,并通过串口发送int16_ts[] = {-1234, -567, 1456, 32767};
bluebird_pack(&data_packed, s, 4, 1);
bluebird_send(&data_packed, uart_send);
#endif#if1// 将接收到的字节数组解码为数据uint8_tchars[] = {0xEB, 0x90, 0x09, 0x2E, 0xFB, 0xC9, 0xFD, 0xB0, 0x05, 0xFF, 0x7F, 0x22, 0xBE};
for (inti=0; i<sizeof(chars); i++)
{
// 每次只处理一个字节,如果数据解析完成,bluebird_unpack 函数会返回 1#if1// 一般将下列代码放在串口中断中(变量 chr 换成串口接收到的数据)charchr=chars[i];
if (bluebird_unpack(&data_unpacked, chr))
{
printf("\n解析数据完成,");
if (data_unpacked.type==0) // 接收的类型是uint16
{
printf("数据类型是 uint16!\n");
for(inti=0; i<data_unpacked.length; i++)
{
printf("data[%d]=%d\n", i, data_unpacked.data_union.data_u16[i]);
}
}
if (data_unpacked.type==1) // 接收的类型是int16
{
printf("数据类型是 int16!\n");
for(inti=0; i<data_unpacked.length; i++)
{
printf("data[%d]=%d\n", i, data_unpacked.data_union.data_i16[i]);
}
}
}
#endif
}
#endif
}青鸟编码器的数据帧格式如下,您可以根据该格式自行适配其他语言。
| 位数 | 意义 | 说明 |
|---|---|---|
| D0 | 帧头 | 固定值:0xEB |
| D1 | 帧头 | 固定值:0x90 |
| D2 | 传输数据的类型; 数据长度 N; | d0:数据类型(1-int16,0-uint16); d1-d7:数据的长度 N,范围0-127; |
| D3-D2N+2 | 数据 | int16 / uint16,小端序(低位在前) |
| D2N+3 | 校验和 | 数据位(D3-D2N+2)相加,和的低8位 |
| D2N+4 | 帧尾 | 固定值:0xBE |
提交 Pull Request 时请选择 develop 分支,请勿直接提交到主分支 main
