当前位置: 首页 > news >正文

住房城乡建设部网站主页制作网页链接的软件

住房城乡建设部网站主页,制作网页链接的软件,电信200m宽带做网站卡吗,网页游戏排行榜源码STM32HAL库RS485-ModBus协议控制伺服电机 一个月前#xff0c;接手了一个学长的毕设小车#xff0c;小车采用rs485通信的modbus协议驱动轮毂电机#xff0c;与往常我学习的pwm控制电机方法大相径庭#xff0c;在这里以这篇博客记录下该学习过程。 小车主要架构 电机型号 …STM32HAL库RS485-ModBus协议控制伺服电机 一个月前接手了一个学长的毕设小车小车采用rs485通信的modbus协议驱动轮毂电机与往常我学习的pwm控制电机方法大相径庭在这里以这篇博客记录下该学习过程。 小车主要架构 电机型号 中菱轮毂电机 轮毂驱动器ZLAC8015D ZLAC8015D 的 RS485 支持 Modbus RTU 协议。驱动器地址为 0-127 可设默认为 1波特率 9600、19200、38400、57600、115200、128000、256000 等 7 种 可通过软件设置。 默认 115200 数据位 8无奇偶校验停止位 1 RS485通信 RS485接口组成的半双工网络一般是两线制多采用屏蔽双绞线传输这种接线方式为总线式拓扑结构在同一总线上最多可以挂接32个结点。我们知道最初数据是模拟信号输出简单过程量后来仪表接口是RS232接口这种接口可以实现点对点的通信方式但这种方式不能实现联网功能随后出现的RS485解决了这个问题。为此本文通过问答的形式详细介绍RS485接口。 RS485_RE为高电平的时候DE为高电平有效允许发送数据 RS485_RE为低电平的时候RE为低电平有效允许接收数据 485转换芯片可以把输入的串口信号转化成差分信号,也可以差分信号转化成串口信号 信号线A、B AB0BA1 STM32实现主从机RS485通信 STM32F103ZET6 RS485接口 A接A B接B 从机 RS485发送 “Hello World” char Buff[30]; //******************* while (1){/* USER CODE END WHILE */HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET); //拉高发送sprintf(Buff,Hello World);HAL_UART_Transmit(huart2, Buff, sizeof(Buff), 0xffff); HAL_Delay(500);/* USER CODE BEGIN 3 */}主机 RS485接收 “Hello World” 虚拟串口打印 HAL_UART_Receive_IT(huart2, RxBuff,1); HAL_GPIO_WritePin(GPIOD,GPIO_PIN_7, GPIO_PIN_RESET); //拉低接收 //******************************* void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {uint8_t i;if(huart-InstanceUSART2){HAL_UART_Receive_IT(huart2,RxBuff,10);CDC_Transmit_FS(RxBuff, sizeof(RxBuff));} }Modbus协议 Modbus就是一种用在工业上的简单协议! 大致分为以下几种: Modbus-RTUModbus-ASCIIModbus-TCP 以上三种协议一个设备只会有一种协议该电机使用的是Modbus-RTU。 Modbus是主从方式通信也就是说不能同步进行通信总线上每次只有一个数据进行传输即主机发送从机应答主机不发送总线上就没有数据通信。 Modbus Poll主机Modbus Slave从机通信 第三方测试软件vspd、Modbus Poll、Modbus Slave 虚拟一个串口 修改配置 读取数据 发送 Tx:000024- 01 03 00 00 00 0A C5 CD 010300 0000 0AC5 CDID号功能码起始地址数据内容校验码 接收 Rx:000143- 01 03 0A 00 01 00 02 00 01 00 00 00 00 37 26 01030A00 01 00 02 00 01 00 00 00 0037 26ID号功能码字节长度数据内容校验位 发送单条数据 010600 0400 0388 0AID号功能码起始地址数据内容校验码 发送多条数据 主机TX ID功能码起始地址寄存器长度数据内容校验码0116(0X10)00 0000 0510字节XX XX Tx:001200- 01 10 00 03 00 01 02 00 04 A7 A0 ID功能码起始地址数据长度字节长度数据内容校验码011000 0300 010200 04A7 A0 功能码 03-读取数据06-发送单条数据10-发送多条数据 SSCOM主机Modbus Slave从机通信 读取数据 发送单条数据 发送多条数据 STM32通过RS485完成Modbus协议通信 移植Modbus协议 mbrtu_master.h #ifndef MBRTU_MASTER_H_ #define MBRTU_MASTER_H_#include stdint.h #include stdlib.h #include stdio.h #include mbrtu_master.h #include usart.h #include tim.h/ /// /// MODBUS RTU 主机控制结构 /// /// typedef struct {//// 收发数据缓存//uint8_t ucBuf[128];//// 收发数据状态//uint16_t usStatus;//// 如果使用了RTOS需要进行互斥,那么需要实现以下两个函数的绑定//void (*lock)(void);void (*unlock)(void);//// 微秒延时函数,用于等待超时//void (*delayms)(uint32_t nms);//// 定时器启动和停止函数//void (*timerStop)(void);void (*timerStart)(void);//// 发送数据函数,可以是串口、TCP等//uint32_t (*sendData)(const void* buf, uint32_t len);//// 以下四个回调函数分别是:读线圈、读离散量输入、读保持寄存器、读输入寄存器//void (*readCoilsCallback)(uint16_t usStartAddr, uint16_t usNum, const uint8_t* pucBitsOfCoilsState, uint16_t usLen);void (*readDiscreteInputsCallback)(uint16_t usStartAddr, uint16_t usNum, const uint8_t* pucBitsOfDiscreteInputsState, uint16_t usLen);void (*readHoldingRegistersCallback)(uint16_t usStartAddr, uint16_t usNum, const uint16_t* pusHoldingRegistersVal, uint16_t usLen);void (*readInputRegistersCallback)(uint16_t usStartAddr, uint16_t usNum, const uint16_t* pusInputRegistersVal, uint16_t usLen);}MBRTUMaterTypeDef;/ static void timerStop(void); static void timerStart(void); static void delayms(uint32_t nms); static uint32_t sendData(const void *buf, uint32_t len); static void readCoilsCallback(uint16_t usStartAddr, uint16_t usNum, const uint8_t *pucBitsOfCoilsState, uint16_t usLen); static void readDiscreteInputsCallback(uint16_t usStartAddr, uint16_t usNum, const uint8_t *pucBitsOfDiscreteInputsState, uint16_t usLen); static void readHoldingRegistersCallback(uint16_t usStartAddr, uint16_t usNum, const uint16_t *pusHoldingRegistersVal, uint16_t usLen); static void readInputRegistersCallback(uint16_t usStartAddr, uint16_t usNum, const uint16_t *pusInputRegistersVal, uint16_t usLen);/ /// /// MODBUS RTU 主机 API /// /// int MBRTUMasterReadCoils(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout); int MBRTUMasterReadDiscreteInputs(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout); int MBRTUMasterReadHoldingRegisters(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout); int MBRTUMasterReadInputRegisters(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout); int MBRTUMasterWriteSingleCoil(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint8_t ucState, uint16_t usTimeout); int MBRTUMasterWriteSingleRegister(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usRegVal, uint16_t usTimeout); int MBRTUMasterWriteMultipleCoils(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, const uint8_t* pucStateBitsBuf, uint16_t usTimeout); int MBRTUMasterWriteMultipleRegisters(MBRTUMaterTypeDef* psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, const uint16_t* pusRegVal, uint16_t usTimeout);/ /// /// MODBUS RTU 主机接收数据回调函数和超时回调函数 /// /// MBRTUMasterRecvByteISRCallback放置于串口接收中断中 /// MBRTUMasterTimerISRCallback放置于定时器超时中断中 /// void MBRTUMasterRecvByteISRCallback(MBRTUMaterTypeDef* psModbus, uint8_t ucByte); void MBRTUMasterTimerISRCallback(MBRTUMaterTypeDef* psModbus);#endif /* MBRTU_MASTER_H_ */ mbrtu_master.c /** mbrtu_master.c** Created on: 2022年4月29日* Author: hello*/#include mbrtu_master.hstatic uint16_t usMBCRC16(uint8_t *pucFrame, uint16_t usLen) {static const uint8_t aucCRCHi[] {0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40};static const uint8_t aucCRCLo[] {0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,0x41, 0x81, 0x80, 0x40};uint8_t ucCRCHi 0xFF;uint8_t ucCRCLo 0xFF;int iIndex;while (usLen--){iIndex ucCRCLo ^ *(pucFrame);ucCRCLo (uint8_t)(ucCRCHi ^ aucCRCHi[iIndex]);ucCRCHi aucCRCLo[iIndex];}return (uint16_t)(ucCRCHi 8 | ucCRCLo); }//读取数据 static uint32_t MBRTUMasterRead(MBRTUMaterTypeDef *pMaster, uint8_t ucSlaveAddr, uint8_t ucCmd, uint16_t usStartAddr, uint16_t usNum) {uint16_t crc;pMaster-ucBuf[0] ucSlaveAddr;pMaster-ucBuf[1] ucCmd;pMaster-ucBuf[2] ((usStartAddr 0XFF00) 8);pMaster-ucBuf[3] (usStartAddr 0XFF);pMaster-ucBuf[4] ((usNum 0XFF00) 8);pMaster-ucBuf[5] (usNum 0XFF);crc usMBCRC16((uint8_t *)pMaster-ucBuf, 6);pMaster-ucBuf[6] (uint8_t)(crc 0xFF);pMaster-ucBuf[7] (uint8_t)(crc 8);return pMaster-sendData(pMaster-ucBuf, 8); }/*** 主机读取线圈状态* param ucSlaveAddress 从机地址* param usAddress 要读取的线圈起始地址* param usCmd 0x01* param usNum 要读取的线圈数量* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/ int MBRTUMasterReadCoils(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout) {int ret -1;int delay;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-usStatus 0;MBRTUMasterRead(psModbus, ucSlaveAddress, 0X01, usAddress, usNum);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X01){psModbus-readCoilsCallback(usAddress, usNum, psModbus-ucBuf[3], psModbus-ucBuf[2]);ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }/*** 主机读取离散量输入* param ucSlaveAddress 从机地址* param usAddress 要读取的离散量起始地址* param usCmd 0x02* param usNum 要读取的离散量数量* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/ int MBRTUMasterReadDiscreteInputs(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout) {int ret -1;int delay;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-usStatus 0;MBRTUMasterRead(psModbus, ucSlaveAddress, 0X02, usAddress, usNum);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X02){psModbus-readDiscreteInputsCallback(usAddress, usNum, psModbus-ucBuf[3], psModbus-ucBuf[2]);ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }/*** 主机读取保持寄存器!!!!!!!!!!!!* param ucSlaveAddress 从机地址* param usAddress 要读取的保持寄存器起始地址* param usCmd 0x03* param usNum 要读取的保持寄存器数量* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/ int MBRTUMasterReadHoldingRegisters(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout) {int ret -1;int delay;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-usStatus 0;MBRTUMasterRead(psModbus, ucSlaveAddress, 0X03, usAddress, usNum);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X03){psModbus-readHoldingRegistersCallback(usAddress, usNum, (const uint16_t *)psModbus-ucBuf[3], psModbus-ucBuf[2] 1);ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }/*** 主机读取输入寄存器* param ucSlaveAddress 从机地址* param usAddress 要读取的输入寄存器起始地址* param usCmd 0x04* param usNum 要读取的输入寄存器数量* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/ int MBRTUMasterReadInputRegisters(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, uint16_t usTimeout) {int ret -1;int delay;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-usStatus 0;MBRTUMasterRead(psModbus, ucSlaveAddress, 0X04, usAddress, usNum);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X04){psModbus-readInputRegistersCallback(usAddress, usNum, (const uint16_t *)psModbus-ucBuf[3], psModbus-ucBuf[2] 1);ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }/*** 主机写单个线圈* param ucSlaveAddress 从机地址* param usAddress 线圈地址* param usCmd 0x05* param ucState 要设置的线圈状态1或者0* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/int MBRTUMasterWriteSingleCoil(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint8_t ucState, uint16_t usTimeout) {int ret -1;int delay;uint16_t crc;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-ucBuf[0] ucSlaveAddress;psModbus-ucBuf[1] 0X05;psModbus-ucBuf[2] usAddress 0XFF;psModbus-ucBuf[3] usAddress 8;psModbus-ucBuf[4] ucState ? 0XFF : 0X00;psModbus-ucBuf[5] 0X00;crc usMBCRC16((uint8_t *)psModbus-ucBuf, 6);psModbus-ucBuf[6] (uint8_t)(crc 0xFF);psModbus-ucBuf[7] (uint8_t)(crc 8);psModbus-usStatus 0;psModbus-sendData(psModbus-ucBuf, 8);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X05){ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }/*** 主机写单个寄存器!!!!!!!!!!!* param ucSlaveAddress 从机地址* param usAddress 寄存器地址* param usCmd 0x06* param usRegVal 寄存器值* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/ // MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, RUN_MODE_ADDR, 0x0003, 100); int MBRTUMasterWriteSingleRegister(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usRegVal, uint16_t usTimeout) {int ret -1;int delay;uint16_t crc;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-ucBuf[0] ucSlaveAddress;psModbus-ucBuf[1] 0X06;psModbus-ucBuf[2] usAddress 0XFF;psModbus-ucBuf[3] usAddress 8;psModbus-ucBuf[4] usRegVal 8;psModbus-ucBuf[5] usRegVal 0XFF;crc usMBCRC16((uint8_t *)psModbus-ucBuf, 6);psModbus-ucBuf[6] (uint8_t)(crc 0xFF);psModbus-ucBuf[7] (uint8_t)(crc 8);psModbus-usStatus 0;psModbus-sendData(psModbus-ucBuf, 8);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X06){ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }/*** 主机写多个线圈状态* param ucSlaveAddress 从机地址* param usAddress 线圈起始地址* param usNum 要写的线圈数量* param pucStateBitsBuf 存放线圈状态1比特代表一个线圈状态* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/ int MBRTUMasterWriteMultipleCoils(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, const uint8_t *pucStateBitsBuf, uint16_t usTimeout) {int ret -1;int delay;uint16_t crc;uint16_t usIndex 0, usBytes 0;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-ucBuf[usIndex] ucSlaveAddress;psModbus-ucBuf[usIndex] 0X0F;psModbus-ucBuf[usIndex] usAddress 0XFF;psModbus-ucBuf[usIndex] usAddress 8;psModbus-ucBuf[usIndex] usNum 8;psModbus-ucBuf[usIndex] usNum 0XFF;usBytes (usNum - 1) / 8 1;psModbus-ucBuf[usIndex] usBytes;while (usBytes--){psModbus-ucBuf[usIndex] *pucStateBitsBuf;}crc usMBCRC16((uint8_t *)psModbus-ucBuf, usIndex);psModbus-ucBuf[usIndex] (uint8_t)(crc 0xFF);psModbus-ucBuf[usIndex] (uint8_t)(crc 8);psModbus-usStatus 0;psModbus-sendData(psModbus-ucBuf, usIndex);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X0F){ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }/*** 主机写多个寄存器!!!!!!!!!!!* param ucSlaveAddress 从机地址* param usAddress 要写的寄存器起始地址* param usCmd 0x10* param usNum 要写的寄存器数量* param pusRegVal 存放要写的寄存器值* param usTimeout 超时时间,单位毫秒* return 0:成功 0:执行失败*/ int MBRTUMasterWriteMultipleRegisters(MBRTUMaterTypeDef *psModbus, uint8_t ucSlaveAddress, uint16_t usAddress, uint16_t usNum, const uint16_t *pusRegVal, uint16_t usTimeout) {int ret -1;int delay;uint16_t crc;uint16_t usIndex 0;if (psModbus-lock ! NULL){psModbus-lock();}psModbus-ucBuf[usIndex] ucSlaveAddress;psModbus-ucBuf[usIndex] 0X10;psModbus-ucBuf[usIndex] usAddress 0XFF;psModbus-ucBuf[usIndex] usAddress 8;psModbus-ucBuf[usIndex] usNum 8;psModbus-ucBuf[usIndex] usNum 0XFF;psModbus-ucBuf[usIndex] usNum 1;while (usNum--){psModbus-ucBuf[usIndex] *pusRegVal 8;psModbus-ucBuf[usIndex] *pusRegVal 0XFF;pusRegVal;}crc usMBCRC16((uint8_t *)psModbus-ucBuf, usIndex);psModbus-ucBuf[usIndex] (uint8_t)(crc 0xFF);psModbus-ucBuf[usIndex] (uint8_t)(crc 8);psModbus-usStatus 0;psModbus-sendData(psModbus-ucBuf, usIndex);while (usTimeout ! 0){if (psModbus-usStatus 0X8000){if (psModbus-ucBuf[0] ucSlaveAddress psModbus-ucBuf[1] 0X10){ret 0;}else{ret -2;}psModbus-usStatus 0;break;}delay usTimeout 5 ? 5 : usTimeout;usTimeout - delay;psModbus-delayms(delay);}if (psModbus-unlock ! NULL){psModbus-unlock();}return ret; }void MBRTUMasterRecvByteISRCallback(MBRTUMaterTypeDef *psModbus, uint8_t ucByte) {psModbus-timerStop();if (psModbus-usStatus sizeof(psModbus-ucBuf)){psModbus-ucBuf[psModbus-usStatus] ucByte;psModbus-timerStart();}else{psModbus-usStatus | 0X8000;} }void MBRTUMasterTimerISRCallback(MBRTUMaterTypeDef *psModbus) {psModbus-timerStop();psModbus-usStatus | 0X8000; }#ifdef USE_RTOSstatic void mutex_lock(void) { }static void mutex_unlock(void) { }#endifstatic void timerStop(void) {HAL_TIM_Base_Stop_IT(htim3); }static void timerStart(void) {__HAL_TIM_SET_COUNTER(htim3, 0);HAL_TIM_Base_Start_IT(htim3); }static void delayms(uint32_t nms) {HAL_Delay(nms); }static uint32_t sendData(const void *buf, uint32_t len) {if (HAL_UART_Transmit(huart2, (uint8_t *)buf, len, 100) ! HAL_OK){len 0;}return len; }static void readCoilsCallback(uint16_t usStartAddr, uint16_t usNum, const uint8_t *pucBitsOfCoilsState, uint16_t usLen) {uint8_t ucLoops (usNum - 1) / 8 1;uint8_t ucState, ucBits;printf( Read %d coils starting at start address %d: , usNum, usStartAddr);while (ucLoops ! 0){ucState *pucBitsOfCoilsState;ucBits 0;while (usNum ! 0 ucBits 8){printf(%d , ucState 0X01 ? 1 : 0);ucState 1;usNum--;ucBits;}ucLoops--;}printf(\r\n); }static void readDiscreteInputsCallback(uint16_t usStartAddr, uint16_t usNum, const uint8_t *pucBitsOfDiscreteInputsState, uint16_t usLen) {uint8_t ucLoops (usNum - 1) / 8 1;uint8_t ucState, ucBits;printf( Read %d discrete inputs starting at start address %d: , usNum, usStartAddr);while (ucLoops ! 0){ucState *pucBitsOfDiscreteInputsState;ucBits 0;while (usNum ! 0 ucBits 8){printf(%d , ucState 0X01 ? 1 : 0);ucState 1;usNum--;ucBits;}ucLoops--;}printf(\r\n); }static void readHoldingRegistersCallback(uint16_t usStartAddr, uint16_t usNum, const uint16_t *pusHoldingRegistersVal, uint16_t usLen) {uint16_t val;printf( Read %d hold registers starting at start address %d: , usNum, usStartAddr);while (usLen--){val *pusHoldingRegistersVal;val ((val 0X00FF) 8) | ((val 0XFF00) 8); // 转换大小端printf(%04X , val);}printf(\r\n); }static void readInputRegistersCallback(uint16_t usStartAddr, uint16_t usNum, const uint16_t *pusInputRegistersVal, uint16_t usLen) {uint16_t val;printf( Read %d input registers starting at start address %d: , usNum, usStartAddr);while (usLen--){val *pusInputRegistersVal;val ((val 0X00FF) 8) | ((val 0XFF00) 8); // 转换大小端printf(%04X , val);}printf(\r\n); }MBRTUMaterTypeDef MBRTUHandle {.delayms delayms,.timerStart timerStart,.timerStop timerStop,.sendData sendData,.readCoilsCallback readCoilsCallback,.readDiscreteInputsCallback readDiscreteInputsCallback,.readHoldingRegistersCallback readHoldingRegistersCallback,.readInputRegistersCallback readInputRegistersCallback,#ifdef USE_RTOS // 使用了RTOS那么需要实现互斥.lock mutex_lock,.unlock mutex_unlock, #endif};main.c TX extern MBRTUMaterTypeDef MBRTUHandle; void main(){ /*.............*/while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET); //拉高发送MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, 6, 0X0501, 100);HAL_Delay(1000);}} STM32主机Modbus Slave从机通信 #include mbrtu_master.hextern MBRTUMaterTypeDef MBRTUHandle; for(j0; j255;j) {for(i0;i8;i) {MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, i, j, 100);HAL_Delay(1000);} }STM32按键控制发送ZLAC8015D电机指令 if (HAL_GPIO_ReadPin(WK_UP_GPIO_Port, WK_UP_Pin) 1) {/*延时一小段时间消除抖动*/HAL_Delay(10);/*延时时间后再来判断按键状态如果还是按下状态说明按键确实被按下*/if (HAL_GPIO_ReadPin(WK_UP_GPIO_Port, WK_UP_Pin) 1) {/*等待按键弹开才退出按键扫描函数*/while (HAL_GPIO_ReadPin(WK_UP_GPIO_Port, WK_UP_Pin) 1);MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, 0X200D, 0x0003, 100);// MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, 0X2088, 0X0064, 100);}}if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) 0) {/*延时一小段时间消除抖动*/HAL_Delay(10);/*延时时间后再来判断按键状态如果还是按下状态说明按键确实被按下*/if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) 0) {/*等待按键弹开才退出按键扫描函数*/while (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) 0);MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, 0X200E, 0x0008, 100);HAL_Delay(10);MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, 0X200E, 0x0010, 100);}}if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) 0) {/*延时一小段时间消除抖动*/HAL_Delay(10);/*延时时间后再来判断按键状态如果还是按下状态说明按键确实被按下*/if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) 0) {/*等待按键弹开才退出按键扫描函数*/while (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) 0);MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, 0X2088, 0X0064, 100); // HAL_Delay(10);MBRTUMasterWriteSingleRegister(MBRTUHandle, 1, 0X2089, 0X0064, 100);HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5);}}}指令依次是 设置速度模式 使能 电机同步启动 设置左电机目标转速100RPM 设置右点击目标转速100RPM 、
文章转载自:
http://www.morning.pffqh.cn.gov.cn.pffqh.cn
http://www.morning.pbsqr.cn.gov.cn.pbsqr.cn
http://www.morning.hqbk.cn.gov.cn.hqbk.cn
http://www.morning.gdljq.cn.gov.cn.gdljq.cn
http://www.morning.mplb.cn.gov.cn.mplb.cn
http://www.morning.zwwhq.cn.gov.cn.zwwhq.cn
http://www.morning.lhyhx.cn.gov.cn.lhyhx.cn
http://www.morning.jfch.cn.gov.cn.jfch.cn
http://www.morning.mlycx.cn.gov.cn.mlycx.cn
http://www.morning.fqqlq.cn.gov.cn.fqqlq.cn
http://www.morning.fhkr.cn.gov.cn.fhkr.cn
http://www.morning.xmbhc.cn.gov.cn.xmbhc.cn
http://www.morning.lxmks.cn.gov.cn.lxmks.cn
http://www.morning.tfsyk.cn.gov.cn.tfsyk.cn
http://www.morning.dspqc.cn.gov.cn.dspqc.cn
http://www.morning.jxjrm.cn.gov.cn.jxjrm.cn
http://www.morning.xllrf.cn.gov.cn.xllrf.cn
http://www.morning.lnrhk.cn.gov.cn.lnrhk.cn
http://www.morning.pxtgf.cn.gov.cn.pxtgf.cn
http://www.morning.lylkh.cn.gov.cn.lylkh.cn
http://www.morning.hwycs.cn.gov.cn.hwycs.cn
http://www.morning.ctfh.cn.gov.cn.ctfh.cn
http://www.morning.ztmnr.cn.gov.cn.ztmnr.cn
http://www.morning.dhdzz.cn.gov.cn.dhdzz.cn
http://www.morning.xqqcq.cn.gov.cn.xqqcq.cn
http://www.morning.bpwfr.cn.gov.cn.bpwfr.cn
http://www.morning.mqffm.cn.gov.cn.mqffm.cn
http://www.morning.iqcge.com.gov.cn.iqcge.com
http://www.morning.dwfzm.cn.gov.cn.dwfzm.cn
http://www.morning.kpmxn.cn.gov.cn.kpmxn.cn
http://www.morning.fkflc.cn.gov.cn.fkflc.cn
http://www.morning.jtmql.cn.gov.cn.jtmql.cn
http://www.morning.pyswr.cn.gov.cn.pyswr.cn
http://www.morning.gpmrj.cn.gov.cn.gpmrj.cn
http://www.morning.mzwqt.cn.gov.cn.mzwqt.cn
http://www.morning.krdmn.cn.gov.cn.krdmn.cn
http://www.morning.yuanshenglan.com.gov.cn.yuanshenglan.com
http://www.morning.rnqrl.cn.gov.cn.rnqrl.cn
http://www.morning.tknqr.cn.gov.cn.tknqr.cn
http://www.morning.qbfs.cn.gov.cn.qbfs.cn
http://www.morning.lgtcg.cn.gov.cn.lgtcg.cn
http://www.morning.kkqgf.cn.gov.cn.kkqgf.cn
http://www.morning.mrncd.cn.gov.cn.mrncd.cn
http://www.morning.jzkqg.cn.gov.cn.jzkqg.cn
http://www.morning.kgqpx.cn.gov.cn.kgqpx.cn
http://www.morning.bpmdg.cn.gov.cn.bpmdg.cn
http://www.morning.gzxnj.cn.gov.cn.gzxnj.cn
http://www.morning.ymbqr.cn.gov.cn.ymbqr.cn
http://www.morning.rdmn.cn.gov.cn.rdmn.cn
http://www.morning.fykqh.cn.gov.cn.fykqh.cn
http://www.morning.dblgm.cn.gov.cn.dblgm.cn
http://www.morning.nqrdx.cn.gov.cn.nqrdx.cn
http://www.morning.wxlzr.cn.gov.cn.wxlzr.cn
http://www.morning.gllhx.cn.gov.cn.gllhx.cn
http://www.morning.dkgtr.cn.gov.cn.dkgtr.cn
http://www.morning.yqwsd.cn.gov.cn.yqwsd.cn
http://www.morning.kkysz.cn.gov.cn.kkysz.cn
http://www.morning.xlclj.cn.gov.cn.xlclj.cn
http://www.morning.hffpy.cn.gov.cn.hffpy.cn
http://www.morning.ltffk.cn.gov.cn.ltffk.cn
http://www.morning.xcjwm.cn.gov.cn.xcjwm.cn
http://www.morning.xjwtq.cn.gov.cn.xjwtq.cn
http://www.morning.lsnnc.cn.gov.cn.lsnnc.cn
http://www.morning.hqgkx.cn.gov.cn.hqgkx.cn
http://www.morning.qttg.cn.gov.cn.qttg.cn
http://www.morning.bmhc.cn.gov.cn.bmhc.cn
http://www.morning.mqdr.cn.gov.cn.mqdr.cn
http://www.morning.xbyyd.cn.gov.cn.xbyyd.cn
http://www.morning.mjgxl.cn.gov.cn.mjgxl.cn
http://www.morning.mywnk.cn.gov.cn.mywnk.cn
http://www.morning.tnmmp.cn.gov.cn.tnmmp.cn
http://www.morning.prls.cn.gov.cn.prls.cn
http://www.morning.jpjxb.cn.gov.cn.jpjxb.cn
http://www.morning.flmxl.cn.gov.cn.flmxl.cn
http://www.morning.ryysc.cn.gov.cn.ryysc.cn
http://www.morning.ddrdt.cn.gov.cn.ddrdt.cn
http://www.morning.ftnhr.cn.gov.cn.ftnhr.cn
http://www.morning.xkyst.cn.gov.cn.xkyst.cn
http://www.morning.kmjbs.cn.gov.cn.kmjbs.cn
http://www.morning.bpmnq.cn.gov.cn.bpmnq.cn
http://www.tj-hxxt.cn/news/242335.html

相关文章:

  • 免费公司网站蒙文网站建设情况汇报
  • 企业站官网青秀网站建设
  • 建设事业单位网站多少钱昆明有多少做网站的公司
  • 太原做网站推广的公司wordpress搬家步骤
  • 公司网站怎么设计外包加工网免押金
  • 网站建设的维护工作有哪些网站页面文案
  • 泰州网站制作专业从零开始学Wordpress建站
  • 域名已注册怎样建设网站地产政策最新消息
  • seo网站推广工作内容seo网站建设方案
  • 做的最好的门户网站网站建设如何去找客户
  • 私人定制哪个网站做的比较好织梦cms仿网站教程
  • 选网站建设要注意什么买域名去哪个网站
  • 网站建设运营工作业绩模仿网站建设站建设
  • 塔城网站seo项目计划书包括哪些内容
  • 微网站建设流程如何制作主页
  • 怎样做网站首页图片变换网站防封链接怎么做
  • 网站点击赚钱怎么做网站版权备案
  • 山东省住房和城乡建设网站wordpress 微官网主题下载
  • 帮人做传销网站违法吗wordpress the_excerpt()
  • 搜索引擎网站制作做门图网站
  • 专门做面包和蛋糕的网站义乌做网站的公司有哪些
  • 取消网站备案时间百度会收录双域名的网站么
  • 务川县住房和城乡建设局网站昆明网站制作内容
  • 公司网站建设服务公司公司注册核名
  • 用哪个程序做网站收录好wordpress如何做301跳转
  • zencart 网站迁移做计算机项目的网站
  • 珠海市规划建设局网站比亚迪新能源汽车车型及价格
  • 网站产品要如何做详情杭州市住房与城乡建设部网站
  • 盘锦网站建设重庆市建设工程信息网怎么录项目信息
  • 佛山企业建网站wordpress插件地图标记