- 打卡等级:以坛为家I
- 打卡总天数:375
- 最近打卡:2025-04-26 15:51:33
已绑定手机
高级会员
- 积分
- 822
|
发表于 2023-11-23 17:10:22
|
显示全部楼层
可以参考下**********
/**************************************************************************/
/******** 读寄存器操作 **************************************************/
/**************************************************************************/
void Read_Reg()
{
uchar i,x;
uint CRC_DATA;
Modbus.Reg_addr = (UART1.RX_data[2] << 8) + UART1.RX_data[3]; //寄存器地址
Modbus.Reg_number = (UART1.RX_data[4] << 8) + UART1.RX_data[5]; //寄存器个数
if( Modbus.Reg_number >= 0x007D)
{
return ; //返回错误码
}
if(( Modbus.Reg_addr < 0x0060) || (Modbus.Reg_addr > 0x00FF)) //寄存器地址范围
{
return ; //返回错误码
}
x = 0;
UART1.TX_data[x++] = 0X01; //地址
UART1.TX_data[x++] = UART1.RX_data[1]; //功能码
UART1.TX_data[x++] = Modbus.Reg_number*2; //数据个数
for(i = (Modbus.Reg_addr-0X0060); i < ((Modbus.Reg_addr-0X0060)+Modbus.Reg_number); i++ )
{
UART1.TX_data[x++] = Modbus.Read_buff_data >> 8;
UART1.TX_data[x++] = Modbus.Read_buff_data ;
}
CRC_DATA = GetCRC16( UART1.TX_data , x);
UART1.TX_data[x++] = CRC_DATA >> 8;
UART1.TX_data[x++] = CRC_DATA ;
while( UART1.TX_Busy ); //串口空闲
UART1.TX_Busy = 1; //串口置1 忙标志
UART1.TX_Len = 0;
UART1.TX_Count = x; //发送数据位数
Enable_485_1_TX();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //空操作 短延时
SBUF = UART1.TX_data[UART1.TX_Len]; //发送数据 中断发送
}
/**************************************************************************/
/******** 写单个或多个寄存器数据 **************************************************/
/**************************************************************************/
void Write_Reg()
{
uchar i,x;
uchar addr; //数组位置
uint CRC_DATA; //CRC数据
dat_ui Change; //数据转换
fucDataBuf databuf0;
fucDataBuf databuf1; //结构体定义
float f;
if(( Modbus.Reg_addr < 0x0060) || (Modbus.Reg_addr > 0x00FF)) //寄存器地址范围
{
return ; //返回错误码
}
else
{
addr = Modbus.Reg_addr - 0x0060; //获取存储地址 = 寄存器地址-偏移量
if( Modbus.Cmd == 0x06 ) //写单个寄存器
{
Change.dat_uchar[0] = UART1.RX_data[4];
Change.dat_uchar[1] = UART1.RX_data[5]; //数据转换
Modbus.Write_buff_data[ addr ] = Change.dat_uint; //将数据写入对应寄存器位置
// Modbus.Read_buff_data[ addr ] = Change.dat_uint;
}
else if( Modbus.Cmd == 0x10 ) //写多个寄存器
{
Modbus.Reg_number = UART1.RX_data[4];
Modbus.Reg_number = Modbus.Reg_number << 8;
Modbus.Reg_number = Modbus.Reg_number + UART1.RX_data[5]; //寄存器个数
Modbus.Data_number = UART1.RX_data[6]; //数据长数
if( Modbus.Reg_number >= 0x007D) //判断寄存器个数
{
return ; //返回错误码
}
else
{
x = 7; //临时变量,数据从第七位开始
for( i = addr; i < ( addr + Modbus.Reg_number ); i++)
{
Change.dat_uchar[0] = UART1.RX_data[x++];
Change.dat_uchar[1] = UART1.RX_data[x++]; //数据转换
Modbus.Write_buff_data = Change.dat_uint; //将数据写入对应寄存器位置
//Modbus.Read_buff_data = Change.dat_uint;
}
}
}
switch( Modbus.Reg_addr ) //根据下发寄存器执行相应的功能
{
case 0x0064: MK.Cmd_flag = 1; MK.Cmd_Mode = 1; break; //修改地址
case 0x0068: MK.Cmd_flag = 1; MK.Cmd_Mode = 2; break; //标定零点
case 0x006E: MK.count += 3 ; break; //标定系数1
case 0x0070: MK.count += 5 ; break; //标定系数2
case 0x0076: MK.Cmd_flag = 1; MK.Cmd_Mode = 10; break; //清密
case 0x007E: EA = 0; //标定协议改变,程序重启
Protocol = Modbus.Write_buff_data[Pro_Name_Reg];
IapEraseSector(EEPROM_Protocol); //扇区擦除
IapProgramByte(EEPROM_Protocol,(Protocol<<8)); IapProgramByte(EEPROM_Protocol+1,Protocol); //存储
IAP_CONTR = 0X60; //重启
P36 = P37 = 0;
while(1); //死循环
break;
/*************************** 以下为多点标定 ******************************************************/
case 0x0080: databuf0.ucDataBuf[0] = Modbus.Write_buff_data[W_Xs1_H_Reg]; // 0x0080 系数1 寄存器
databuf0.ucDataBuf[1] = Modbus.Write_buff_data[W_Xs1_L_Reg]; // 0X0081
f = databuf0.fDataBuf;
databuf0.fDataBuf = f/10000.0; //系数缩小10000倍
Modbus.Write_buff_data[W_Xs1_H_Reg] = databuf0.ucDataBuf[0];
Modbus.Write_buff_data[W_Xs1_L_Reg] = databuf0.ucDataBuf[1];
MK.Cmd_flag = 1; MK.Cmd_Mode = 4;
break;
case 0x0082: databuf0.ucDataBuf[0] = Modbus.Write_buff_data[W_Xs2_H_Reg]; // 0x0082 系数2 寄存器
databuf0.ucDataBuf[1] = Modbus.Write_buff_data[W_Xs2_L_Reg]; // 0X0083
f = databuf0.fDataBuf;
databuf0.fDataBuf = f/10000.0; //系数缩小10000倍
Modbus.Write_buff_data[W_Xs2_H_Reg] = databuf0.ucDataBuf[0];
Modbus.Write_buff_data[W_Xs2_L_Reg] = databuf0.ucDataBuf[1];
MK.Cmd_flag = 1; MK.Cmd_Mode = 5;
break;
case 0x0084: databuf0.ucDataBuf[0] = Modbus.Write_buff_data[W_Xs3_H_Reg]; // 0x0084 系数3 寄存器
databuf0.ucDataBuf[1] = Modbus.Write_buff_data[W_Xs3_L_Reg]; // 0X0085
f = databuf0.fDataBuf;
databuf0.fDataBuf = f/10000.0; //系数缩小10000倍
Modbus.Write_buff_data[W_Xs3_H_Reg] = databuf0.ucDataBuf[0];
Modbus.Write_buff_data[W_Xs3_L_Reg] = databuf0.ucDataBuf[1];
MK.Cmd_flag = 1; MK.Cmd_Mode = 6;
break;
case 0x0086: databuf0.ucDataBuf[0] = Modbus.Write_buff_data[W_Xs4_H_Reg]; // 0x0086 系数4 寄存器
databuf0.ucDataBuf[1] = Modbus.Write_buff_data[W_Xs4_L_Reg]; // 0X0087
f = databuf0.fDataBuf;
databuf0.fDataBuf = f/10000.0; //系数缩小10000倍
Modbus.Write_buff_data[W_Xs4_H_Reg] = databuf0.ucDataBuf[0];
Modbus.Write_buff_data[W_Xs4_L_Reg] = databuf0.ucDataBuf[1];
MK.Cmd_flag = 1; MK.Cmd_Mode = 7;
break;
case 0x0088: databuf0.ucDataBuf[0] = Modbus.Write_buff_data[W_Xs5_H_Reg]; // 0x0088 系数5 寄存器
databuf0.ucDataBuf[1] = Modbus.Write_buff_data[W_Xs5_L_Reg]; // 0X0089
f = databuf0.fDataBuf;
databuf0.fDataBuf = f/10000.0; //系数缩小10000倍
Modbus.Write_buff_data[W_Xs5_H_Reg] = databuf0.ucDataBuf[0];
Modbus.Write_buff_data[W_Xs5_L_Reg] = databuf0.ucDataBuf[1];
MK.Cmd_flag = 1; MK.Cmd_Mode = 8;
break;
case 0x008A: databuf0.ucDataBuf[0] = Modbus.Write_buff_data[W_Xs6_H_Reg]; // 0x008A 系数6 寄存器
databuf0.ucDataBuf[1] = Modbus.Write_buff_data[W_Xs6_L_Reg]; // 0X008B
f = databuf0.fDataBuf;
databuf0.fDataBuf = f/10000.0; //系数缩小10000倍
Modbus.Write_buff_data[W_Xs6_H_Reg] = databuf0.ucDataBuf[0];
Modbus.Write_buff_data[W_Xs6_L_Reg] = databuf0.ucDataBuf[1];
MK.Cmd_flag = 1; MK.Cmd_Mode = 9;
break;
default: break;
}
if(MK.count==8)
{
MK.Cmd_flag = 1;
MK.Cmd_Mode = 3;
MK.count =0;
//系数1
databuf0.ucDataBuf[0] = Modbus.Write_buff_data[W_Bdxs1_H_Reg]; // 0x006E 系数1 寄存器
databuf0.ucDataBuf[1] = Modbus.Write_buff_data[W_Bdxs1_L_Reg]; // 0X006F
Modbus.xishu_1 = databuf0.fDataBuf;
//系数2
databuf1.ucDataBuf[0] = Modbus.Write_buff_data[W_Bdxs2_H_Reg]; //0X0070 系数2 寄存器
databuf1.ucDataBuf[1] = Modbus.Write_buff_data[W_Bdxs2_L_Reg]; //0X0071
Modbus.xishu_2 = databuf1.fDataBuf;
//缩小2次10000倍
databuf0.fDataBuf = Modbus.xishu_1/100000000.0;
databuf1.fDataBuf = Modbus.xishu_2/100000000.0;
//系数1
Modbus.Write_buff_data[W_Bdxs1_H_Reg] = databuf0.ucDataBuf[0];
Modbus.Write_buff_data[W_Bdxs1_L_Reg] = databuf0.ucDataBuf[1];
//系数2
Modbus.Write_buff_data[W_Bdxs2_H_Reg] = databuf1.ucDataBuf[0];
Modbus.Write_buff_data[W_Bdxs2_L_Reg] = databuf1.ucDataBuf[1];
}
}
for( i = 0; i < 6; i++) //Modbus 返回值
{
UART1.TX_data = UART1.RX_data;
}
CRC_DATA = GetCRC16( UART1.TX_data , i ); //CRC计算
UART1.TX_data[i++] = CRC_DATA >> 8;
UART1.TX_data[i++] = CRC_DATA ;
while( UART1.TX_Busy ); //串口1空闲
UART1.TX_Busy = 1; //串口置1 忙标志
UART1.TX_Len = 0;
UART1.TX_Count = i;
Enable_485_1_TX();
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SBUF = UART1.TX_data[UART1.TX_Len]; //发送数据 中断发送 //标志赋0
}
/****************** CRC 计算 ******************************************************/
unsigned int GetCRC16(unsigned char *ptr, unsigned char len)
{
unsigned int index;
unsigned char crch = 0xFF; //高CRC字节
unsigned char crcl = 0xFF; //低CRC字节
unsigned char code TabH[] = { //CRC高位字节值表
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
} ;
unsigned char code TabL[] = { //CRC低位字节值表
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
} ;
while (len--) //计算指定长度的CRC
{
index = crch ^ *ptr++;
crch = crcl ^ TabH[index];
crcl = TabL[index];
}
return ((crch<<8) | crcl);
} |
|