1/*!2 \file rs485_proto.h3 \brief 霍尔设备的 RS485 帧协议45 物理层:USART0,PA9 发、PA10 收,8N1。PB5 高电平发送,低电平接收6 (SIT3088 的 DE 与 RE# 接在一起)。默认 115200,设备号 1。78 帧格式,多字节小端:910 0 SOF0 0xA511 1 SOF1 0x5A12 2 DST 目标设备号,0xFF 广播13 3 SRC 源设备号,主机用 0x0014 4 TYPE 设备类型,0xFF 表示不限15 5 CMD 命令,应答时最高位置 116 6 SEQ 序号,应答原样带回17 7 LEN 载荷长度18 8 DATA LEN 字节19 . CRC16 Modbus,覆盖 DST 到载荷末尾2021 一条总线上设备号不能重复,编码器和以后的位置传感器也共用这套号。22 点名时写上具体类型,避免两台不同类型设备撞号时一起回答。23 广播只执行设置,不回答。2425 设备类型:26 0x01 角度编码器27 0x02 直线位置。同一套固件,用 0x07 切换,Flash 里记住28 0xFF 任意类型2930 设备只回答 0xFF 和当前类型。采样 int32 在角度模式下是 0.01°,31 在直线模式下是 0.01 mm,0 在中间那颗霍尔,正方向指向 U4。3233 命令(主机 -> 设备):34 0x01 读信息。载荷空。35 应答:类型、设备号、模式、波特率序号、上报周期、固件版本、36 校准有效、标志、机械零点。零点在角度模式是 uint16(0.01°),37 在直线模式是 int16(0.01 mm)。38 0x02 设置设备号。载荷 1 字节,1..254。应答带回新设备号。39 0x03 设置波特率。载荷 1 字节序号。先按旧波特率应答,再切换。40 0x04 设置上传模式。载荷:模式 1 字节,周期毫秒 uint16。41 0 主从,只在查询后回答;1 主动上报,同时仍回答查询。42 0x05 把当前参数写入 Flash。43 0x06 恢复出厂。设备号 1,115200,主从,20 ms,角度模式,44 清零点和校准。45 0x07 切换测量模式。载荷 1 字节:1 角度,2 直线。46 会清掉两种模式的零点和校准再写入 Flash。47 0x10 读一帧采样。应答在状态字节之后是 int32、幅度 int16、48 三路原码 uint16、标志。int32 的单位见上面的设备类型。49 0x21 设置机械零点。载荷空则把当前读数记为 0。50 角度模式载荷 uint16,范围 0..35999,单位 0.01°。51 直线模式载荷 int16,单位 0.01 mm。52 0x22 清除机械零点。53 0x23 开始校准。角度模式接着转满至少一圈。54 直线模式要先把磁铁拿开,开始对零磁场取平均。55 0x24 结束校准。数据不够时保持校准中。56 角度模式成功应答:三路偏置 int16、三路增益 uint16(Q12)。57 直线模式成功应答:三路基线 int16,随后 uint16 是敏感宽度58 (µm),另外两路增益为 0。59 0x25 清除校准。角度模式回到三路平均值;直线模式基线回到 2048。60 0x26 读取校准。标志、三路偏置或基线、三路增益或宽度。61 0x27 设置直线模式的敏感宽度。载荷 uint16,单位 µm,62 范围 2000..30000,默认 8000。只有直线模式能写。6364 设备主动帧:65 0x30 角度上报,没有状态字节,载荷与 0x10 应答里状态字节之后相同。66 目标固定 0x00,源是本机设备号。6768 应答命令 = 请求命令 | 0x80,载荷第一字节是状态:69 0x00 成功70 0x01 长度不对71 0x02 参数超出范围72 0x03 当前状态不允许73 0x04 校准数据不够74 0x05 Flash 写入失败75 0x06 不认识的命令7677 写 Flash 的命令应答可能要几十毫秒。主机超时建议不小于 100 ms。78 主动上报的总线上同时只让一台设备处于上报模式。7980 波特率序号:0=9600,1=19200,2=38400,3=57600,4=115200,81 5=230400,6=460800,7=921600。8283 标志位与 HALL_FLAG_* 相同:bit0 磁场弱,bit1 校准有效,bit2 正在校准,84 bit3 直线位置超出阵列两端。85*/8687#ifndef RS485_PROTO_H88#define RS485_PROTO_H8990#include <stdint.h>9192#define RS485_SOF0 0xA5U93#define RS485_SOF1 0x5AU94#define RS485_ADDR_HOST 0x00U95#define RS485_ADDR_BCAST 0xFFU9697#define RS485_TYPE_HALL_ENCODER 0x01U98#define RS485_TYPE_HALL_POSITION 0x02U99#define RS485_TYPE_ANY 0xFFU100101#define RS485_MODE_POLL 0U102#define RS485_MODE_REPORT 1U103104#define RS485_CMD_GET_INFO 0x01U105#define RS485_CMD_SET_ID 0x02U106#define RS485_CMD_SET_BAUD 0x03U107#define RS485_CMD_SET_MODE 0x04U108#define RS485_CMD_SAVE 0x05U109#define RS485_CMD_FACTORY 0x06U110#define RS485_CMD_SET_PROFILE 0x07U111#define RS485_CMD_GET_DATA 0x10U112#define RS485_CMD_SET_ZERO 0x21U113#define RS485_CMD_CLEAR_ZERO 0x22U114#define RS485_CMD_CAL_BEGIN 0x23U115#define RS485_CMD_CAL_END 0x24U116#define RS485_CMD_CAL_CLEAR 0x25U117#define RS485_CMD_GET_CAL 0x26U118#define RS485_CMD_SET_SIGMA 0x27U119#define RS485_CMD_REPORT 0x30U120#define RS485_CMD_RESPONSE 0x80U121122#define RS485_OK 0x00U123#define RS485_ERR_LEN 0x01U124#define RS485_ERR_PARAM 0x02U125#define RS485_ERR_STATE 0x03U126#define RS485_ERR_CAL 0x04U127#define RS485_ERR_FLASH 0x05U128#define RS485_ERR_CMD 0x06U129130#define RS485_BAUD_9600 0U131#define RS485_BAUD_19200 1U132#define RS485_BAUD_38400 2U133#define RS485_BAUD_57600 3U134#define RS485_BAUD_115200 4U135#define RS485_BAUD_230400 5U136#define RS485_BAUD_460800 6U137#define RS485_BAUD_921600 7U138#define RS485_BAUD_COUNT 8U139140#define RS485_FW_VERSION 0x0101U141142/*!143 \brief 从 Flash 恢复参数,打开 USART0,方向脚保持接收144 \param[in] none145 \param[out] none146 \retval none147*/148void rs485_proto_init(void);149150/*!151 \brief 解析收到的帧,到点则主动上报152 \param[in] none153 \param[out] none154 \retval none155*/156void rs485_proto_poll(void);157158/*!159 \brief USART0 中断里调用160 \param[in] none161 \param[out] none162 \retval none163*/164void rs485_usart_isr(void);165166/*!167 \brief 当前设备号168 \retval 1..254169*/170uint8_t rs485_proto_id(void);171172/*!173 \brief 当前波特率174 \retval bit/s175*/176uint32_t rs485_proto_baud(void);177178/*!179 \brief 当前上传模式180 \retval RS485_MODE_POLL 或 RS485_MODE_REPORT181*/182uint8_t rs485_proto_mode(void);183184/*!185 \brief 当前测量类型186 \retval RS485_TYPE_HALL_ENCODER 或 RS485_TYPE_HALL_POSITION187*/188uint8_t rs485_proto_type(void);189190#endif /* RS485_PROTO_H */