| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 |
- #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<SlaveNum;i++){
- sut_device_read[i].Addr=j++;
-
- }
- }
- /**********************************************************************************************************
- *更新寄存器列表参数
- ************************************************************************************************************/
- void ModbusRefreshValue(void)
- {
- static char chekcnt=0;
- unsigned char i;
- unsigned short cnt;
- /************************************自检********************************************/
- if(SelfChek==0){
- //存在一个问题第一次无法扫到第一个从机。不过后续都能扫描到第一个从机。
- if(g_ucModbusRefreshEN == 1)
- {
- g_ucModbusRefreshEN = 0;
- g_ucModbusRefreshTimeOut = 0;
- g_ucRegNumCount++; //
-
- if((MODBUS_REG_NUM_MAX - 1) < g_ucRegNumCount){
- //置位可上传FLAG
- //sut_sys_status.OnceFlag=1;
- g_ucRegNumCount = 0;
- //完成一次读取 需要一个标志位表示一次读取完成
- chekcnt++;
- if(chekcnt==4)SelfChek=1;
- }
- 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++;
- }
- }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<MODBUS_REG_NUM_MAX;i++)
- {
- if(device_vailable[i]!=1) continue; //不在线直接跳过
- os_dly_wait(1);
- ModbusCmdSetValue(&Device_Down.sut_device_write[i]);
- }
- return 0;
- }
- //初步定为定时上传
- int ProcessTcpSend()
- {
- return 0;
- }
|