#ifndef __MTCOMM_H__ #define __MTCOMM_H__ #include "config.h" //------------------------------------------------------------------------ /* 闭环电机的通讯控制接口 // 协议: 通过485通讯,总线上可以挂在多个闭环步进电机。 485串行通讯 波特率: 115200 bps 数据帧: 1个起始位,8个数据位,1个停止位,没有校验位。 8个数据位是通讯的有效数据内容(1个字节)。 多个数据帧构成一个数据包 按照固定的8个字节组成一个数据包。 |---------------------------------------------------------------------------------------| | B0 | B1 | B2 | B3 | B4 | B5 | B6 | B7 | |---------------|---------------|-----------|-------------------------------|-----------| | 数据包头 | 目标站号 | 命令 | 数据内容 | 校验字 | |---------------|---------------|-----------|-------------------------------|-----------| | 固定字节 | 目标站号 | 命令 | 数据内容 | 校验字 | | | | |-------------------------------|-----------| | | 0 主站 | | | B1--B6的 | | 0xEB | 1--250 从站 | 1--255 | 4个字节,内容根据命令来定义 | 8位CRC校验 | | | 255 广播 | | | | | | 251--254 保留 | | | | |---------------|---------------|-----------|-------------------------------|-----------| | | | | | | |---------------------------------------------------------------------------------------| 数据包按照从B0--B7的顺序传输,网络上的通讯以数据包为单位。 传输流程 默认情况下,如果没有通讯发生,主站处于发送状态,从站处于接收状态。 如果是有回包的通讯,通讯的过程描述如下: 主站: 1.设置为发送状态,给某个站点或全部站点发送命令。 2.发送完成后,设置为接收状态。 3.等待回包,如果10ms内没有收到回包,则认为通讯超时。 4.返回步骤1 从站: 1.设置为接收状态,等待主站命令。 2.接收到新命令后,等待1ms。 3.设置为发送状态,发送回包给主站,。 4.等待发送完成后,转到步骤1 如果没有回包,则主站发送,不需要切换为接收状态。 从站接收到数据后,只执行响应,不再切换为发送状态 */ //------------------------------------ #define MT_SYNC_LEN 1 // 数据识别序列长度 #define MT_ADDR_LEN 1 // 地址长度 #define MT_CMD_LEN 1 // 命令长度 #define MT_CONT_LEN 4 // 数据内容长度 #define MT_CHK_LEN 1 // 校验字长度 #define MT_CHECK_LEN (MT_ADDR_LEN+MT_CMD_LEN+MT_CONT_LEN) #define LEN_MTCOMM_PKT (MT_SYNC_LEN+MT_ADDR_LEN+MT_CMD_LEN+MT_CONT_LEN+MT_CHK_LEN) //------------------------------------ #ifdef _IN_MTCOMM_C const u8 MTCOMM_SYNC[MT_SYNC_LEN] = { 0xEB, }; #endif //------------------------------------ // 数据结构 typedef struct { u8 sync[MT_SYNC_LEN]; //-------- u8 addr; u8 cmd; //----- u8 content[MT_CONT_LEN]; //-------- u8 crc8; } __attribute__ ((packed)) MtCommPacket; //------------------------------------ #define MTTS_ADDR_MAIN 0 // 主站地址 #define MTTS_ADDR_BROADCAST 0xFF // 广播地址 //------------------------------------ // 命令定义 // 主站到从站 #define MTCMD_ADDR_INIT 0x01 // 站号初始化 #define MTCMD_SET_NEW_AD 0x02 // 设置新站号 #define MTCMD_GET_INFO 0x03 // 查询从站信息 #define MTCMD_READ_DATA 0x04 // 读取数据 #define MTCMD_WRITE_DATA 0x05 // 设置数据 // 从站到主站 #define MTCMD_REV_INFO 0x83 // 查询从站信息命令的回包 #define MTCMD_REV_DATA 0x84 // 读取数据命令的回包 //------------------------------------------------------ #define MTCOMM_NONE 0 #define MTCOMM_MASTER 1 // 主节点 #define MTCOMM_SLAVE 2 // 从节点 // 节点配置 #ifndef MTCOMM_AS #define MTCOMM_AS MTCOMM_NONE #endif #if (MTCOMM_AS != MTCOMM_NONE && MTCOMM_AS != MTCOMM_MASTER && MTCOMM_AS != MTCOMM_SLAVE) #undef MTCOMM_AS #define MTCOMM_AS MTCOMM_NONE #endif //------------------------------------------------------ // 通讯函数 typedef struct { int (*SendMtCommData)(u8 *, int); // 发送数据函数 int (*GetMtCommData)(u8 *, int); // 接收数据函数 int (*GetMtRsvLen)(void); // 得到已接收数据长度函数 int (*GetTrsFreeLen)(void); // 得到发送数据缓冲区长度函数 void (*Set485TxEnOn)(void); // 发送允许打开函数 void (*Set485TxEnOff)(void); // 发送允许关闭函数 }MtCommExFuncs; //------------------------------------------------------ // 初始化 // 注册收发函数和485开关函数 void InitMtComm(MtCommExFuncs * pExFuncs); // 异步收发过程,完成数据的收发过程。 // 需要在控制流程中不停调用 void MtCommAsyncTask(void); // 打包命令 // 添加同步字,生成CRC int PacketAMtComm(MtCommPacket * pPacket); // 校验一个数据包 // 验证同步字和CRC int CheckAMtPacket(MtCommPacket * pPacket); // 启动一次发送任务 // 返回传输ID int SendAMtPacket(MtCommPacket * pPacket, int hasback); // 获取发送状态 int GetSendStatus(int id); // 获取发送结果 int GetSendResult(int id); // 读取一个数据包 // 如果接收到, 数据在pPacket中 int GetAMtPacket(MtCommPacket * pPacket); #endif