初级会员

- 积分
- 63
- 金钱
- 63
- 注册时间
- 2018-11-7
- 在线时间
- 11 小时
|

楼主 |
发表于 2021-6-10 22:09:19
|
显示全部楼层
本帖最后由 gdqxp 于 2021-6-13 12:08 编辑
现在我把程序贴上啊:
- void Modbus_RegMap()
- {
- ModbusHoldReg[0] = (signed short*)&Address; //设备地址
- ModbusHoldReg[1] = (signed short*)&frequency; //频率
- ModbusHoldReg[2] = (signed short*)&duty_3; //占空比
- ModbusHoldReg[3] = (signed short*)&Kp;
- ModbusHoldReg[4] = (signed short*)&Ki;
- ModbusHoldReg[5] = (signed short*)&Kd;
- }
- void Modbus_Backup_RegMap(void)
- {
- //备份寄存器
- Backup_ModbusHoldReg[0] = (signed short*)&Backup_Address;
- Backup_ModbusHoldReg[1] = (signed short*)&Backup_frequency;
- Backup_ModbusHoldReg[2] = (signed short*)&Backup_duty_3;
- Backup_ModbusHoldReg[3] = (signed short*)&Backup_Kp;
- Backup_ModbusHoldReg[4] = (signed short*)&Backup_Ki;
- Backup_ModbusHoldReg[5] = (signed short*)&Backup_Kd;
- }//CRC效验
- unsigned short CRCData(unsigned char xdata *ptr,unsigned char len)
- {
- unsigned char CRCDataH = 0xFF;
- unsigned char CRCDataL = 0xFF;
- unsigned char Index=0;
- unsigned short CRCResult=0;
- while(len--)
- {
- Index = CRCDataH ^ *ptr++;
- CRCDataH = CRCDataL ^ RevCRC16H[Index];
- CRCDataL = RevCRC16L[Index];
- }
- CRCResult = (((unsigned short)CRCDataL)<<8)|CRCDataH;
- return(CRCResult);
- } /* 串口动作函数,根据接收到的命令帧执行响应的动作
- buf-接收到的命令帧指针,len-命令帧长度 */
- void UartAction()
- {
- unsigned short RegCRC;
- unsigned short CalCRC;
- // if(flagFrame == 1)
- // {
- // flagFrame=0;
- if((RecvBuf[0] == Address)||(RecvBuf[0] == 0))
- {
- if((RecvBuf[1] == 03)||(RecvBuf[1] == 06)||(RecvBuf[1] == 16))//功能码
- {
- StartRegAddress = ((((unsigned short)RecvBuf[2])<<8)|RecvBuf[3]);//寄存器起始地址
- if(StartRegAddress < 100)
- {
- CalCRC = CRCData(RecvBuf,(RecvCnt-2)); /???CRCD£?é??
- RegCRC = (((unsigned short)RecvBuf[RecvCnt-1])<<8)|RecvBuf[RecvCnt-2]; /????óê?μ?μ?CRCD£?é??
- RegCRC = CalCRC; //*****2aê?íê±?oó′?ì???á?é?3y*****
- if(CalCRC == RegCRC)
- {
- switch(RecvBuf[1])
- {
- case 03: //读多个寄存器
- ReadManyRegister(RecvBuf,SendBuf);
- break;
- case 06: //写单个寄存器
- WriteOneRegister(RecvBuf,SendBuf);
- break;
- case 16: //写多个寄存器
- WriteManyRegister(RecvBuf,SendBuf);
- break;
- }
- }
- else //CRCD£?é′í?ó
- {
- SendBuf[0] = RecvBuf[0];
- SendBuf[1] = RecvBuf[1]|0x80;
- SendBuf[2] = 0x04; //′í?ó′ú??0x04:CRCD£?é??òì3£
- CalCRC = CRCData(SendBuf,3);
- SendBuf[3] = CalCRC&0xFF;
- SendBuf[4] = (CalCRC>>8)&0xFF;
- SendCnt = 6; //
- }
- }
- else//超出范围
- {
- SendBuf[0] = RecvBuf[0];
- SendBuf[1] = RecvBuf[1]|0x80;
- SendBuf[2] = 0x02; //0x02:寄存器地址超出范围
- CalCRC = CRCData(SendBuf,3);
- SendBuf[3] = CalCRC&0xFF;
- SendBuf[4] = (CalCRC>>8)&0xFF;
- SendCnt = 6;
- }
- }
- else //功能码错误
- {
- SendBuf[0] = RecvBuf[0];
- SendBuf[1] = RecvBuf[1]|0x80;
- SendBuf[2] = 0x01; //0x01:功能码错误
- CalCRC = CRCData(SendBuf,3);
- SendBuf[3] = CalCRC&0xFF;
- SendBuf[4] = (CalCRC>>8)&0xFF;
- SendCnt = 6;
- }
- RecvCnt = 0;
- pSendBuf = SendBuf;
- RS485_DIR = 1;//准备发送
- UartWrite( SendBuf, (SendCnt-1));
- }
- //}
- //读多个寄存器地址
- void ReadManyRegister(unsigned char xdata*RecvBuf,unsigned char xdata*SendBuf)
- {
- unsigned char i=0;
- unsigned short CalCRC;
- RegisterNum = (((unsigned short)RecvBuf[4])<<8)|RecvBuf[5]; //获取寄存器数量
- if((StartRegAddress+RegisterNum)<100)//地址小于100
- {
- SendBuf[0] = RecvBuf[0];
- SendBuf[1] = RecvBuf[1];
- SendBuf[2] = RegisterNum<<1;//字节数为寄存器的两倍
- for(i=0;i<RegisterNum;i++)//把接收到的数据写进去
- {
- SendBuf[3+i*2] = (*ModbusHoldReg[StartRegAddress+i]>>8)&0xFF; //先发送高字节再发送低字节
- SendBuf[4+i*2] = (*ModbusHoldReg[StartRegAddress+i])&0xFF;
- }
- CalCRC = CRCData(SendBuf,((RegisterNum<<1)+3));
- SendBuf[(RegisterNum<<1)+3] = CalCRC&0xFF;
- SendBuf[(RegisterNum<<1)+4] = (CalCRC>>8)&0xFF;
- SendCnt = SendBuf[2]+6;
- }
- else //寄存器地址+数量超出范围
- {
- SendBuf[0] = RecvBuf[0];
- SendBuf[1] = RecvBuf[1]|0x80;
- SendBuf[2] = 0x02; //错误代码
- CalCRC = CRCData(SendBuf,3);
- SendBuf[3] = CalCRC&0xFF;
- SendBuf[4] = (CalCRC>>8)&0xFF;
- SendCnt = 6;//
- }
- RecvCnt = 0;
- pSendBuf = SendBuf;
- RS485_DIR = 1;//准备发送
- UartWrite( SendBuf,(SendCnt-1));
- }
复制代码 |
|