#include "includes.h" unsigned char g_ucModbusRefreshEN; unsigned char g_ucModbusRefreshSHUTDOWN; unsigned short g_ucRegNumCount; unsigned short g_ucModbusRefreshTimeOut; //char SendData[850]; // SUT_DEVICE--------->SUT_DEVICE_READ unsigned char device_vailable[MODBUS_REG_NUM_MAX]; unsigned char SelfChek; SUT_DOWN Device_Down; //下行设置 SUT_UP Device_Up; //上行汇报 SUT_DEVICE_READ sut_device_read[MODBUS_REG_NUM_MAX]; //32 SUT_DEVICE_WRITE sut_device_write; SUT_SYS_STATUS sut_sys_status; /********************************************************************************************************** *初始化寄存器列表 ************************************************************************************************************/ void Reg_Init() { unsigned char i,j; j=1; memset(sut_device_read,0,sizeof(SUT_DEVICE_READ)*MODBUS_REG_NUM_MAX); // /****************由鉴权工具下发可用从机个数****SlaveNum************/ // SlaveNum=32;//测试 for(i=0;i 3)// { g_ucModbusRefreshEN = 1; g_ucModbusRefreshTimeOut = 0; //printf("time out\r\n"); } g_ucModbusRefreshTimeOut++; } }else{ if(g_ucModbusRefreshEN == 1) { g_ucModbusRefreshEN = 0; g_ucModbusRefreshTimeOut = 0; g_ucRegNumCount++; //实际个数 while(device_vailable[g_ucRegNumCount]!=1){ g_ucRegNumCount++; } if((MODBUS_REG_NUM_MAX - 1) < g_ucRegNumCount) { //置位可上传FLAG sut_sys_status.OnceFlag=1; g_ucRegNumCount = 0; //完成一次读取 需要一个标志位表示一次读取完成 } ModbusCmdReadOneValue(sut_device_read[g_ucRegNumCount].Addr); //从机地址 }else { if(g_ucModbusRefreshTimeOut > 3)// { g_ucModbusRefreshEN = 1; g_ucModbusRefreshTimeOut = 0; //printf("time out\r\n"); } g_ucModbusRefreshTimeOut++; } } } /********************************************************************************************************** ModbusCmdReadOneValue() 发送请求,读取MODBUS设备指定一个寄存器地址的参数 ADDR:代表寄存器列表里第几个元素 查询指令 AA BB CMD LEN ADDR 01 CRC1 CRC2 DD 55 //10 ************************************************************************************************************/ //SUT_DEVICE Devices[count]; void ModbusCmdReadOneValue(unsigned short addr) { unsigned short CRC16; unsigned char Pack[10],i; unsigned char temp[3]; Pack[0]=0xAA; Pack[1]=0xBB; Pack[2]=HOLDINGREG; Pack[3]=0x0A; Pack[4] =addr; Pack[5] =0x01; CRC16=crc16_calc(0xffff,Pack,6); Pack[6] = (unsigned char)(CRC16 & 0xff); Pack[7] = (unsigned char)(CRC16 >> 8); Pack[8]=0xdd; Pack[9]=0x55; // if(addr==1){ // for(i=0;i<10;i++){ // FEED_EXTWATCHDOG(); // sprintf(temp, "%02x",Pack[i]); // SlwTrace(INF,temp); // } //} RS485_DIR_HIGH; for(i=0;i<10;i++) { USART_SendData(USART1,Pack[i]); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); } RS485_DIR_LOW; } /********************************************************************************************************** *向MODBUS设备发送配置参数命令 数据格式 0xcc 0xdd cmd len(1) addr(1) data(4) crc(2) DD 55 //13 ************************************************************************************************************/ //SUT_DOWN.Devices[2]; void ModbusCmdSetValue(SUT_DEVICE_WRITE *pMsg) { unsigned short crc,CRC16; unsigned char Pack[13],i; unsigned char temp=0x00; char buf[3]; Pack[0]=0xCC; Pack[1]=0xDD; Pack[2] = WRITESINGLEREG; Pack[3]=sizeof(Pack); Pack[4] = pMsg->Addr; // 转化为4个字节发送 temp=temp |((pMsg->STU_RGB[0].R)<<5); temp=temp |((pMsg->STU_RGB[0].G)<<6); temp=temp |((pMsg->STU_RGB[0].B)<<7); temp=temp | ((pMsg->STU_RGB[1].R)<<1); temp=temp |((pMsg->STU_RGB[1].G)<<2); temp=temp |((pMsg->STU_RGB[1].B)<<3); Pack[5]=temp; temp=0x00; temp=temp |((pMsg->STU_RGB[2].R)<<5); temp=temp |((pMsg->STU_RGB[2].G)<<6); temp=temp |((pMsg->STU_RGB[2].B)<<7); temp=temp | ((pMsg->STU_RGB[3].R)<<1); temp=temp |((pMsg->STU_RGB[3].G)<<2); temp=temp |((pMsg->STU_RGB[3].B)<<3); Pack[6]=temp; temp=0x00; temp=temp |((pMsg->STU_RGB[4].R)<<5); temp=temp |((pMsg->STU_RGB[4].G)<<6); temp=temp |((pMsg->STU_RGB[4].B)<<7); temp=temp |((pMsg->STU_RGB[5].R)<<1); temp=temp |((pMsg->STU_RGB[5].G)<<2); temp=temp |((pMsg->STU_RGB[5].B)<<3); Pack[7]=temp; temp=0x00; temp=temp |((pMsg->STU_RGB[6].R)<<5); temp=temp |((pMsg->STU_RGB[6].G)<<6); temp=temp |((pMsg->STU_RGB[6].B)<<7); temp=temp |((pMsg->STU_RGB[7].R)<<1); temp=temp |((pMsg->STU_RGB[7].G)<<2); temp=temp |((pMsg->STU_RGB[7].B)<<3); Pack[8]=temp; CRC16=crc16_calc(0xffff,Pack,9); Pack[9] = (unsigned char)(CRC16 & 0xff); Pack[10] = (unsigned char)(CRC16 >> 8); Pack[11]=0xdd; Pack[12]=0x55; if(Pack[4]==1){ SlwTrace(INF,"/***********ADDR====1*************/\r\n"); for(i=0;i<13;i++) { snprintf(buf,sizeof(buf),"%02x",Pack[i]); SlwTrace(INF,buf); } } SlwTrace(INF,"\r\n"); RS485_DIR_HIGH; for(i=0;i<13;i++) { USART_SendData(USART1,Pack[i]); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); } RS485_DIR_LOW; } /**************************************************************************** ModbusRecvProcess pData格式: AA BB CMD LEN ADDR ERRNUM DT(1) CRC(2) DD 55 //len=11 *****************************************************************************/ //ModbusRecvProcess(pData, sut_deviceTemp[g_ucRegNumCount]); //Devices(count); int ModbusRecvProcess(unsigned char *pData) // 临时变量红外状态 { char buf[30]; int i; unsigned short crc,CRC16; int flag=0; int len=pData[3]; //SlwTrace(DEBUG,"Decodec From MB OK!\r\n"); g_ucModbusRefreshEN = 1; //收到一次 //if(len < 5) return 0;//长度小于5的就不处理 CRC16=crc16_calc(0xffff,pData,len-4); crc=((unsigned short)pData[len-3]&0xff)<<8; crc+=(unsigned short)pData[len-4]&0xff; if(crc != CRC16) return 0;//CRC校验不对,不处理 tsk_lock ();//涉及到全局变量在不同任务中共享,就要加任务锁,避免修改全局变量未完成时切换到别的任务去调用全局变量,从而导致数据完整性问题。 if(sut_device_read[g_ucRegNumCount].Addr==pData[4]){ if(SelfChek==0){ device_vailable[g_ucRegNumCount]=1; } sut_device_read[g_ucRegNumCount].Error=pData[5]; for(i=0;i<8;i++){ sut_device_read[g_ucRegNumCount].RID[i]=(pData[6]&0x80)>>7; pData[6]=pData[6]<<1; } } tsk_unlock (); // SlwTrace(INF,"\r\n"); // sprintf(buf,"g_ucRegNumCount=====%d==\r\n",g_ucRegNumCount); // SlwTrace(DEBUG,buf); return 1; } //处理TCP下行数据 int ProcessSetControl() { unsigned char i; unsigned int cnt; //收到下发数据等待查询完成稳定 // for(cnt=0;cnt<500000;cnt++){ // for(i=0;i<73;i++){ // // __NOP(); // // } // } //循环遍历设置 for(i=0;i