123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- #include "includes.h"
- unsigned char g_ucModbusRefreshEN = 1;//更新寄存器列表中的数据的使能标志位,1使能,和ModbusRecvProcess配合使用,用于控制收发
- unsigned char g_ucModbusRefreshSHUTDOWN = 0;//控制maintask中的更新寄存器列表中的数据的总开关,1关闭,0开启
- unsigned short g_ucModbusRefreshTimeOut = 5;//自动读取从机VALUE的等待超时时间,用于收发控制
- unsigned short g_ucRegNumCount = 0;//当前正在处理的寄存器地址在列表中的序号。用于控制收发逻辑
- SUT_MODBUS_REGPACK sutModbusRegPack = {0};
- /**********************************************************************************************************
- ModbusRecvProcess()
- 处理接收到的MODBUS数据 :slave(u8)|function(u8)|bytecount(u8)|value1H(u8)|value1L(u8)|value2H(u8)|value2L(u8)|......|valueNL(u8)|CRC(u16)
- 成功返回1
- 失败返回0
- num:代表寄存器列表里第几个元素
- ************************************************************************************************************/
- unsigned char ModbusRecvProcess(unsigned char *pMsg,int len,unsigned short num)
- {
- unsigned short crc,CRC16;
- unsigned char i;
- unsigned short value[MODBUS_REG_NUM_MAX];
-
- if(len < 5) return 0;//长度小于5的不是MODBUS数据,就不处理
- CRC16=crc16_calc(0xffff,pMsg,len-2);
- crc=((unsigned short)pMsg[len-1]&0xff)<<8;
- crc+=(unsigned short)pMsg[len-2]&0xff;
- if(crc != CRC16) return 0;//CRC校验不对,不处理
- if(pMsg[1] == HOLDINGREG){//功能码=0x03,保存进寄存器列表
- for(i = 0;i < pMsg[2]/2;i++){
- value[i]=((unsigned short)pMsg[i*2+3]&0xff)<<8;
- value[i]+=(unsigned short)pMsg[i*2+4]&0xff;
- }
- sutModbusRegPack.RegList[num].value = value[i-1];
- }else if(pMsg[1] == WRITESINGLEREG){//功能码=0x06,说明配置寄存器参数成功
- g_ucSetControlAckResult &= 1;
- }else{
- g_ucSetControlAckResult &= 0;
- }
-
-
- return 1;
- }
- /**********************************************************************************************************
- ModbusCmdReadOneValue()
- 发送请求,读MODBUS设备指定一个寄存器地址的参数
- num:代表寄存器列表里第几个元素
- ************************************************************************************************************/
- void ModbusCmdReadOneValue(SUT_MODBUS_REGLIST *pMsg,unsigned short num)
- {
- unsigned short crc,CRC16;
- unsigned char Pack[8],i;
- Pack[0] = (pMsg+num)->slave;
- Pack[1] = HOLDINGREG;
- Pack[2] = (unsigned char)((pMsg+num)->addr >> 8);
- Pack[3] = (unsigned char)((pMsg+num)->addr & 0xff);
- Pack[4] = 0;
- Pack[5] = 1;
- CRC16=crc16_calc(0xffff,Pack,6);
- Pack[6] = (unsigned char)(CRC16 & 0xff);
- Pack[7] = (unsigned char)(CRC16 >> 8);
- RS485_DIR_HIGH;
- for(i=0;i<8;i++)
- {
- USART_SendData(USART1,Pack[i]);
- while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
- }
- RS485_DIR_LOW;
- }
- /**********************************************************************************************************
- *更新寄存器列表参数
- ************************************************************************************************************/
- void ModbusRefreshValue(void)
- {
- if(g_ucModbusRefreshEN == 1)
- {
- g_ucModbusRefreshEN = 0;
- g_ucModbusRefreshTimeOut = 0;
- g_ucRegNumCount++;
- if((sutModbusRegPack.RegNum - 1) < g_ucRegNumCount) g_ucRegNumCount = 0;
- ModbusCmdReadOneValue(sutModbusRegPack.RegList,g_ucRegNumCount);
- }
- else
- {
- if(g_ucModbusRefreshTimeOut > 5)//返回超时,重置g_ucModbusRecv=1
- {
- g_ucModbusRefreshEN = 1;
- g_ucModbusRefreshTimeOut = 0;
- }
- g_ucModbusRefreshTimeOut++;
- }
- }
- /**********************************************************************************************************
- *向MODBUS设备发送配置参数命令
- 数据格式 :slave(u8)|function(u8)|AddrH(u8)|AddrL(u8)|valueH(u8)|valueL(u8)|CRC(u16)
- ************************************************************************************************************/
- void ModbusCmdSetValue(SUT_MODBUS_REGLIST *pMsg)
- {
- unsigned short crc,CRC16;
- unsigned char Pack[8],i;
- Pack[0] = pMsg->slave;
- Pack[1] = WRITESINGLEREG;
- Pack[2] = (unsigned char)(pMsg->addr >> 8);
- Pack[3] = (unsigned char)(pMsg->addr & 0xff);
- Pack[4] = (unsigned char)(pMsg->value >> 8);
- Pack[5] = (unsigned char)(pMsg->value & 0xff);
- CRC16=crc16_calc(0xffff,Pack,6);
- Pack[6] = (unsigned char)(CRC16 & 0xff);
- Pack[7] = (unsigned char)(CRC16 >> 8);
- RS485_DIR_HIGH;
- for(i=0;i<8;i++)
- {
- USART_SendData(USART1,Pack[i]);
- while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
- }
- RS485_DIR_LOW;
- }
|