📄 modbus.c
字号:
/*************************************************************************************/
#ifdef MODBUS_COMM
//MODBUS 命令定义
#define REGISTERREAD 0x03 //读出存储寄存器的内容
#define REGISTERWRITEONBYTE 0x06 //改写一个特定的寄存器的数据
#define REGISTERWRITE 0x10 //连续写入多个存储寄存器
#define COMMTEST 0x08 //通讯测试
//MODBUS 寄存器地址定义
//1.系统参数及通讯参数
#define Device_Code 0x00 //设备识别号
#define Device_Comm_Sel 0x01 //设备通讯模式寄存器
#define Device_Comm_Pr 0x02 //设备通讯参数(通讯地址,通讯速率)
#define Device_Tcp_Iph 0x03 //TCP 通讯IP地址高字节寄存器
#define Device_Tcp_Ipl 0X04 //TCP 通讯IP地址低字节寄存器
#define Device_Tcp_Maskh 0X05 //TCP 通讯子网掩码地址高字节寄存器
#define Device_Tcp_Maskl 0X06 //TCP 通讯子网掩码地址低字节寄存器
#define Device_Tcp_Gateh 0X07 //TCP 通讯网关地址高字节寄存器
#define Device_Tcp_Gatel 0X08 //TCP 通讯网关地址低字节寄存器
//2.系统时间
#define Minute_Second 0x09 //分,秒
#define Day_Hour 0x0a //日,小时
#define Year_Month 0x0b //年,月
#define Bak 0X0c //预留备用寄存器 oc-oh
//其他寄存器
#define Anomalous_Staus 0x10 //异常状态寄存器
//3.机器实时运行参数
#define Ux_Volt 0x20 //系统电压
#define Uc_Volt 0x21 //机端电压
#define Ut_Volt 0x22 //调差电压
#define Ilc_Value 0x23 //励磁电流
#define Cos_Value 0x24 //功率因数
#define Q_Value 0x25 //无功功率
#define Fre_Jd 0x26 //机端频率
#define Alf_Value 0x27 //触发相位角
#define Ug_Volt 0x28 //给定电压
#define Ilg_Value 0x29 //给定电流
#define Cosg_Value 0x2a //给定功率因数
#define Qg_Value 0x2b //给定无功
#define Alfg_Value 0x2c //给定ALF角度
#define Bak 0x2d //预留备用寄存器 2d-2f
//4.机器开入开出状态寄存器
#define Switch_In 0x30 //开入输入变量
#define Switch_Out 0x31 //开入输入变量
//5.机器实时运行状态寄存器
#define Run_Staus 0x32 //机器实时运行状态寄存器
#define Run_Bak 0x33 //状态备用寄存器 33-3f
//6.励磁设置参数寄存器
#define P_Set 0x40 //PID参数P寄存器
#define I_Set 0x41 //PID参数I寄存器
#define D_Set 0x42 //PID参数D寄存器
#define Kq_Set 0x43 //无功功率比例参数寄存器
#define Ile_Set 0x44 //励磁电流比例参数寄存器
#define Ct_Set 0x45 //CT 变比参数寄存器
#define Pt_Set 0x46 //PT 变比参数寄存器
#define Tc_Set 0x47 //调差系数寄存器
#define LcIncDec_Set 0x48 //增减励寄存器
#define AutoStartStop_Set 0x49 //自动开机停机寄存器
#define RunMode_Set 0x4a //运行模式寄存器
#define UxTron_Set 0x4b //网跟控制寄存器
#define Excitation_Set 0x4c //高低起励寄存器
#define MkActive_Set 0x4d //灭磁开关寄存器
#define Excitation_Suppression_Set 0x4e //起励灭磁寄存器
#define Bak_Set 0x4f //预留备用寄存器
// #define
//全局变量定义:
//UART2 缓冲单元
unsigned char xdata UART2_ReceiveBuffer[UART_DATAPACK_SIZE]; //接收缓冲单元
unsigned char UART2_ReceiveCount = 0; //接收的字节数
unsigned char UART_SendNum = 0; //发送的字节数
unsigned char xdata UART_SendOk = 0; //已经发送的字节数
unsigned char xdata UART2_ReceiveBuffer[UART_SENDPACK_SIZE]; //发送缓冲单元
//扩展缓冲单元
unsigned char xdata SPI_ReceiveBuffer[SPI_DATAPACK_SIZE]; //接收缓冲单元
unsigned char SPI_ReceiveCount = 0; //接收的字节数
unsigned char SPI_SendNum = 0; //发送的字节数
unsigned char xdata SPI_SendOk = 0; //已经发送的字节数
unsigned char xdata SPI_SendBuffer[SPI_SENDPACK_SIZE]; //发送缓冲单元
//本身地址
unsigned int My_Addr
//液晶缓冲单元
unsigned char xdata Yj_ReceiveBuffer[]; //接收缓冲单元
unsigned char xdata Yj_SendBuffer[]; //发送缓冲单元
//液晶接收处理标志位
unsigned int Yj_ReceiveFlag; //液晶接收缓冲单元中是否有数据要求液晶进行处理标志位
unsigned int Yj_SendFlag; //液晶发送缓冲单元中是否有数据要求液晶进行处理标志位
//----------------------------SPI发送程序--------------------------------//
unsigned char SPISendComm(unsigned char *buf,unsigned char len)
{
unsigned int timeout=0;
if (len > SPI_SENDPACK_SIZE) //长度大于UART长度,出错
return -1;
if (SPI_SendOk != 0) //已经发送的字节数不为0
{
while (SPI_SendOk != 0)
{
timeout++;
if (timeout >= 3000)
{
SPI_SendOk = 0; //已经发送的字节数清0
SPI_SendNum = 0; //发送的字节数清0
return 1;
}
}
return 1;
}
memcpy(SPI_SendBuffer,buf,len);
SPI_SendNum = len;
void WriteData(SPI_SendBuffer,channelA, buf,len);
ES = 1;
SPI_SendOk=1;
return 0; //modify
}
//-----------------------------串口发送程序-------------------------------//
unsigned char UARTSendComm(unsigned char *buf,unsigned char len)
{
unsigned int timeout=0;
if (len > UART_SENDPACK_SIZE)
return -1;
if (UART_SendOk != 0)
{
while (UART_SendOk != 0)
{
timeout++;
if (timeout >= 3000)
{
UART_SendOk = 0;
UART_SendNum = 0;
return 1;
}
}
return 1;
}
memcpy(UART_SendBuffer,buf,len);
UART_SendNum = len;
S2BUF=UART_SendBuffer[0];
ES = 1;
UART_SendOk=1;
return 0; //modify
}
/**************************************************************************************
* 名称:GetCommData
* 说明:判断液晶接收数据的正确性
* 功能:7eH 外部与MCU通讯;feH液晶与MCU通讯;My_AddrH外部通讯(0X20之前,外部与液晶通讯;之后,外部与MCU通讯)
* 调用:
* 输入: UART2_ReceiveBuffer,SPI_ReceiveBuffer
* 返回值:7eH返回值为2;feH返回值1;My_Addr返回值0
* ************************************************************************************/
unsigned char GetCommData(unsigned char *len)
{
unsigned char comm;
unsigned char length[2];
unsigned char tempaddr;
unsigned char ret;
unsigned char receivecount; //接收的字节数
unsigned char receivebuffer[]; //接收到的数据
ret = -1;
*len = 0;
if (receivecount >= 8) //接收的字节数
{
tempaddr = receivebuffer[0];
if ( (tempaddr != My_Addr) && (tempaddr != 0x7e) && (tempaddr != 0xfe) )
return ret;
comm = receivebuffer[1];
switch (comm)
{
case REGISTERWRITE:
*(unsigned int*)(length+0) = 9 + (*(unsigned int*)( receivebuffer+4) *2);//接收到数据字节数
if (*(unsigned int*)(length+0) < MAXREADLENGTH )//接收到的字节数小于最大字节长度
if (CrcCmp16( receivebuffer,length[1]) ==0)//CRC校验
{
if (tempaddr == 0x7e)
ret = 2;
if (tempaddr == 0xfe)
ret = 1;
if (tempaddr == My_Addr)
ret = 0;
*len = length[1];
return ret;
}
break;
case REGISTERREAD:
case COMMTEST:
case REGISTERWRITEONBYTE:
if (CrcCmp16( receivebuffer,8) ==0) //接受到字节数是8个,CRC校验
{
if (tempaddr == 0x7e)
ret = 2;
if (tempaddr == 0xfe)
ret = 1;
if (tempaddr == My_Addr)
ret = 0;
*len = 0x08;
return ret;
}
break;
}
}
return ret;
}
/*************************************************************************************
*名称:SendDataToMCU
*说明:液晶把接收到的串口2数据发给MCU;
*功能:把调节器地址替换成7e,重新进行CRC校验,发送给MCU
*调用:
*输入:UART2_ReceiveBuffer
*输出
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -