上下位机设置:匿名上位机 V7,TFMiniPlus 激光雷达测距
匿名上位机V7通信协议
#include <string.h>
#define BYTE0(dwTemp) (*( (char *)(&dwTemp) )) /* !< uint32_t 数据拆分 byte0 */
#define BYTE1(dwTemp) (*( (char *)(&dwTemp) + 1)) /* !< uint32_t 数据拆分 byte1 */
#define BYTE2(dwTemp) (*( (char *)(&dwTemp) + 2)) /* !< uint32_t 数据拆分 byte2 */
#define BYTE3(dwTemp) (*( (char *)(&dwTemp) + 3)) /* !< uint32_t 数据拆分 byte3 */
#define USERDATALEN 2 // 数据长度
uint8_t waveform[6 + USERDATALEN] = {0}; // 数据帧缓存
/*
* @name: void Wireless_Send(void)
* @notion: V7
*/
void Wireless_Send(void)
{
uint8_t waveform[6 + UserDataLen] = {0}; // 数据帧缓存
uint8_t _cnt = 0;
memset(waveform, 0, sizeof(waveform));
waveform[_cnt++] = 0xAA; // 帧头
waveform[_cnt++] = 0xFF; // 目标地址
waveform[_cnt++] = 0xF1; // 功能码ID
// waveform[_cnt++] = sizeof(waveform) - 6; // 有效数据长度
// waveform[_cnt++] = UserDataLen;
waveform[_cnt++] = 0;
int16_t UserData_1 = (int16_t)(Mortor1.Speed_Read);
//数据区使用小端模式, 低字节在前。
waveform[_cnt++] = BYTE0(UserData_1); // 数据内容
waveform[_cnt++] = BYTE1(UserData_1);
waveform[3] = _cnt - 4; // 写入有效数据字节数
uint8_t sumcheck = 0; // 和校验SC
uint8_t addcheck = 0; // 附加校验AC
for(uint8_t i = 0; i < waveform[3] + 4; i++) {
sumcheck += waveform[i]; // 从帧头开始, 一直到 data 区结束, 对每一字节进行累加操作, 只取低8位
addcheck += sumcheck; // 计算和校验时, 每进行一字节的加法运算, 同时进行一次 sumcheck 的累加操作, 只取低8位
}
waveform[_cnt++] = sumcheck;
waveform[_cnt++] = addcheck;
// 串口发送数据
seekfree_wireless_send_buff(waveform, sizeof(waveform));
// HAL_UART_Transmit(&huart1, (uint8_t*)waveform, _cnt, 2);
}
- 定义USERDATALEN为要发送的数据长度。比如要发送一个int16就是两位,以此类推叠加。
- 需要在匿名上位机高级收码 - 点击右侧绿色的竖条 - 展开用户帧F1 - 设置数据类型,依次设置要发送的发送的几个数据的数据类型。记得勾选使能F1帧
- 浮点数可以数值放大100倍转化成int16处理,提高传输效率
waveform[_cnt++] = BYTE0(float * 100.000f); waveform[_cnt++] = BYTE1(float * 100.000f);
然后在匿名上位机高级收码 - 点击右侧绿色的竖条 - 展开用户帧F1再把数据缩放设为1.0E+2,这样即可显示原始的浮点数据
- 逐飞无线串口一次发送数据最好不要超过30字节。要是单片机有额外的io建议开启无线串口的控流引脚
- 双击匿名上位机波形显示右侧的实时值数字,可以在波形上显示具体数值
TFMiniPlus 激光雷达测距接收协议
#define TFMINI_DATA_Len 9
#define TFMINT_DATA_HEAD (0x59)
uint16_t TFmin_Dist = 0; // 距离信息 单位 cm
uint16_t TFmin_Strength = 0;// 信号强度 小于 100 或等于 65535 时, Dist的测量值被认为不可信输出置0
uint16_t TFmin_Temp = 0; // 表征芯片内部温度值 摄氏度 = Temp / 8 - 256
uint8_t TFminiPlus_buf[TFMINI_DATA_Len] = {0}; // 暂存数据帧
uint8_t TFminiPlus_num = 0; // 暂存本字节数据编码
uint8_t TFminiPlus_flag = 0; // 接收数据标志位 1-成功;2-帧头错误;3-SC校验错误
/*
* @name: void TFminiPlus_Proc2(uint8_t date)
* @function: TFminiPlus单字节接收方式
* @example: TFminiPlus_Proc2(rx_receive);
*/
void TFminiPlus_Proc2(uint8_t data)
{
uint8_t i = 0;
uint8_t checksum = 0;
if (TFminiPlus_num == 0 && data == TFMINT_DATA_HEAD) { // 校验并记录帧头
TFminiPlus_buf[0] = TFMINT_DATA_HEAD;
TFminiPlus_num = 1;
} else if (TFminiPlus_num == 1 && data == TFMINT_DATA_HEAD) { // 校验并记录帧头
TFminiPlus_buf[1] = TFMINT_DATA_HEAD;
TFminiPlus_num = 2;
} else if (TFminiPlus_num >= 2 && TFminiPlus_num <= (TFMINI_DATA_Len - 2)) {
TFminiPlus_buf[TFminiPlus_num] = data;
TFminiPlus_num++;
} else if (TFminiPlus_num == (TFMINI_DATA_Len - 1)) {
for (i = 0; i < (TFMINI_DATA_Len - 1); i++) {
checksum += TFminiPlus_buf[i]; // 从帧头开始到数据区结束, 做checksum校验
}
if (checksum == data) { // 校验Checksum
//数据为小端模式, 低字节在前保存在数据帧的低地址中
TFmin_Dist = TFminiPlus_buf[2] | (TFminiPlus_buf[3] << 8);
TFmin_Strength = TFminiPlus_buf[4] | (TFminiPlus_buf[5] << 8);
TFmin_Temp = TFminiPlus_buf[6] | (TFminiPlus_buf[7] << 8);
TFminiPlus_flag = 1;
} else {
TFminiPlus_flag = 3;
}
TFminiPlus_num = 0;
} else {
TFminiPlus_flag = 2;
TFminiPlus_num = 0;
}
}
/*
* @name: void TFminiPlus_GetOnce(void)
* @function: TFminiPlus单次触发指令
* @notion: 将输出帧率设置为0后, 才可使用单次触发指令
*/
void TFminiPlus_GetOnce(void)
{
uint8_t TFminiPlus_cmd[4] = {0}; // 暂存命令帧
// memset(TFminiPlus_cmd, 0, sizeof(TFminiPlus_cmd));
TFminiPlus_cmd[0] = 0x5A; //指令帧帧头
TFminiPlus_cmd[1] = 0x04; //指令帧总长度
TFminiPlus_cmd[2] = 0x04; //ID
TFminiPlus_cmd[3] = 0x62; //Data
uart_putbuff(UART_3, TFminiPlus_cmd, sizeof(TFminiPlus_cmd)); //串口发送指令
}
- 使用的是TFMiniPlus的串口标准数据输出格式,没有用I2C和字符串数据格式(Pix Mode)
- 没有用沁恒的串口接收DMA,用的简易的单字节接收方式