大家好,欢迎来到IT知识分享网。
#define SET_BIT(REG, BIT) ((REG) |= (BIT))//设置寄存器的第bit位值为1,SET_BIT(RCC->AHB2ENR,1) 或者 SET_BIT(RCC->AHB2ENR,2) #define CLEAR_BIT(REG, BIT) ((REG) &= ~(BIT))//清除寄存器的第bit位值为1的值,即将第bit位置0,CLEAR_BIT(RCC->CR, 64) #define READ_BIT(REG, BIT) ((REG) & (BIT))//读取寄存器中的值,分两种情况:1.REG为FF,BIT为任意数,结果为BIT对应的数据,2.REG为固定数,BIT为任意数,结果0或者固定数,第三种情况不考虑。 #define CLEAR_REG(REG) ((REG) = (0x0))//清空寄存器值 #define WRITE_REG(REG, VAL) ((REG) = (VAL))//对寄存器写入VAL值 #define READ_REG(REG) ((REG)) //读取寄存器内容 ok #define MODIFY_REG(REG, CLEARMASK, SETMASK) WRITE_REG((REG), (((READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK))) //对寄存器REG 写入值(清除和设置掩码)
2、对modebus 中RTU模式的应用理解。
modebus为工业领域的一种通信协议。
其占应用层,数据链路层,物理层等3大数据通信层。
同时其遵循一主机对多从机的通信方式。
而却分从机主要从,从机的地址进行区分。
同时存在功能码实现主机和从机的通信功能的控制。
物理层上(485,232等物理上通信芯片为基础)。
从地址 | 功能码 | 寄存器地址高低 | 寄存器数量 | CRC |
---|---|---|---|---|
0x01 | 0x1 | 0x00 0x02 | 0x00 0x008 | 0x9c 0x0c |
从机端:
从地址 | 功能码 | 数据长度 | 数据 | CRC |
---|---|---|---|---|
0x01 | 0x1 | 0x01 | 0xb3 | 0x9c 0x0c |
2.通信时对应的功能码含意
公用功能码:
线圈,8bit(r),
离散输入8bit(rw),
寄存器 16bit®,
保持寄存器 16bit(rw),
功能码 | 含义 |
---|---|
01h | 读线圈 |
02h | 读离散量输入 |
03h | 读保持(多个)寄存器 |
04h | 读输入寄存器 |
05h | 写单个线圈 |
06h | 写多个线圈 |
0fh | 写多个线圈 |
10h | 写多个寄存器 |
14h | 记录读文件 |
15h | 写文件记录 |
16h | 屏蔽写寄存器 |
17h | 读写多个寄存器 |
3.通信时的数据中每个字符于每段数据帧间的时间控制 (需要控制并检测超过1.5个字符的时间是否收到数据 ,同时对超过3.5个字符的时间没收到数据,认为是空闲状态)。
即: T1.5 <x && T3.5<x
当超过1.5个字符的时间未收到数据即数据出现异常,该帧数据异常。
在通信时RTU方式传输的每帧数据长度需要在256之内。
4.在主机端:
需要考虑的是对从机的发送指令,(对从机的响应接收通过串口的中断来处理)。
第一类: 主机要读取从机的信息。 函数功能: 读输入状态状态(InputStatue) * 输入参数: _addr:从站地址,_reg:寄存器地址,_num:待读取的输入数量 * 返 回 值: 无 * 说 明: 填充数据发送缓存区,然后发送 void MB_ReadInput_02H(uint8_t _addr, uint16_t _reg, uint16_t _num) {
uint16_t TxCount = 0; uint16_t crc = 0; Tx_Buf[TxCount++] = _addr; /* 从站地址 */ Tx_Buf[TxCount++] = 0x02; /* 功能码 */ Tx_Buf[TxCount++] = _reg >> 8; /* 寄存器地址 高字节 */ Tx_Buf[TxCount++] = _reg; /* 寄存器地址 低字节 */ Tx_Buf[TxCount++] = _num >> 8; /* 开关(Input)个数 高字节 */ Tx_Buf[TxCount++] = _num; /* 开关(Input)个数 低字节 */ crc = MB_CRC16((uint8_t*)&Tx_Buf,TxCount); Tx_Buf[TxCount++] = crc; /* crc 低字节 */ Tx_Buf[TxCount++] = crc>>8; /* crc 高字节 */ HAL_UART_Transmit(&husart_debug, (uint8_t *)&Tx_Buf, TxCount, 0xffff); } 第二类是写指令到从机 * 函数功能: 写N个保持寄存器(HoldingRegister) * 输入参数: _addr:从站地址,_reg:寄存器地址,_num:待写入的寄存器数量,_databuf:待写入的寄存器数据 * 返 回 值: 无 * 说 明: 填充数据发送缓存区,然后发送._databuf的长度需 >= _num*2 void MB_WriteNumHoldingReg_10H(uint8_t _addr, uint16_t _reg, uint16_t _num,
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/109747.html