mirror of
https://github.com/armfly/H7-TOOL_STM32H7_App.git
synced 2024-08-09 10:05:34 +08:00
999 lines
33 KiB
C
Executable File
999 lines
33 KiB
C
Executable File
/*
|
||
*********************************************************************************************************
|
||
*
|
||
* 模块名称 : MODSBUS通信程序 (主机)
|
||
* 文件名称 : modbus_host.c
|
||
* 版 本 : V1.0
|
||
* 说 明 : 无线通信程序。通信协议基于MODBUS
|
||
* 修改记录 :
|
||
* 版本号 日期 作者 说明
|
||
* V1.0 2015-04-18 修改协议
|
||
*
|
||
* Copyright (C), 2015-2016, 安富莱电子 www.armfly.com
|
||
*
|
||
*********************************************************************************************************
|
||
*/
|
||
#include "bsp.h"
|
||
#include "param.h"
|
||
#include "main.h"
|
||
#include "main_run.h"
|
||
#include "tcp_modbus_host.h"
|
||
#include "tcp_echoclient.h"
|
||
|
||
/* 保存每个从机的计数器值 */
|
||
|
||
MODH_T g_tModH;
|
||
uint8_t g_modh_timeout = 0;
|
||
|
||
//static void MODH_RxTimeOut(void);
|
||
static void MODH_AnalyzeApp(void);
|
||
|
||
static void MODH_Read_01H(void);
|
||
static void MODH_Read_02H(void);
|
||
static void MODH_Read_03H(void);
|
||
static void MODH_Read_04H(void);
|
||
static void MODH_Read_05H(void);
|
||
static void MODH_Read_06H(void);
|
||
static void MODH_Read_10H(void);
|
||
//static void MODH_Read_30H(void);
|
||
|
||
#if 0
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_SendPacket
|
||
* 功能说明: 发送数据包 COM1口
|
||
* 形 参: _buf : 数据缓冲区
|
||
* _len : 数据长度
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_SendPacket(uint8_t *_buf, uint16_t _len)
|
||
{
|
||
RS485_SendBuf1(_buf, _len);
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_SendAckWithCRC
|
||
* 功能说明: 发送应答,自动加CRC.
|
||
* 形 参: 无。发送数据在 g_tModH.TxBuf[], [g_tModH.TxCount
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
static void MODH_SendAckWithCRC(void)
|
||
{
|
||
uint16_t crc;
|
||
|
||
crc = CRC16_Modbus(g_tModH.TxBuf, g_tModH.TxCount);
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = crc >> 8;
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = crc;
|
||
|
||
memcpy(g_tClient.TxData, g_tModH.TxBuf, g_tModH.TxCount); /* 要发送的数据放入TCP客户端发送缓冲区 */
|
||
g_tClient.TxCount = g_tModH.TxCount; /* TCP将要发送的数据长度 */
|
||
|
||
//MODH_SendPacket(g_tModH.TxBuf, g_tModH.TxCount);
|
||
tcp_client_usersent(echoclient_pcb); /* 用户发送g_tClient.TxData中的数据 */
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_AnalyzeApp
|
||
* 功能说明: 分析应用层协议。处理应答。
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
static void MODH_AnalyzeApp(void)
|
||
{
|
||
switch (g_tModH.RxBuf[1]) /* 第2个字节 功能码 */
|
||
{
|
||
case 0x01: /* 读取线圈状态(对应远程开关D01/D02/D03) */
|
||
MODH_Read_01H();
|
||
break;
|
||
|
||
case 0x02: /* 读取输入状态(对应X0~X7) */
|
||
MODH_Read_02H();
|
||
break;
|
||
|
||
case 0x03: /* 读取保持寄存器 在一个或多个保持寄存器中取得当前的二进制值 */
|
||
MODH_Read_03H();
|
||
break;
|
||
|
||
case 0x04: /* 读取输入寄存器(对应A01/A02) ) */
|
||
MODH_Read_04H();
|
||
break;
|
||
|
||
case 0x05: /* 强制单线圈(对应Y1/Y2) */
|
||
MODH_Read_05H();
|
||
break;
|
||
|
||
case 0x06: /* 写单个寄存器 */
|
||
MODH_Read_06H();
|
||
break;
|
||
|
||
case 0x10: /* 写多个寄存器 */
|
||
MODH_Read_10H();
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Send10H
|
||
* 功能说明: 发送10H指令,连续写多个保持寄存器. 最多一次支持23个寄存器。
|
||
* 形 参: _addr : 从站地址
|
||
* _reg : 寄存器编号
|
||
* _num : 寄存器个数n (每个寄存器2个字节) 值域
|
||
* _buf : n个寄存器的数据。长度 = 2 * n
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Send10H(uint8_t _addr, uint16_t _reg, uint8_t _num, uint8_t *_buf)
|
||
{
|
||
uint16_t i;
|
||
|
||
g_tModH.TxCount = 0;
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _addr; /* 从站地址 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = 0x10; /* 从站地址 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8; /* 寄存器编号 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg; /* 寄存器编号 低字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _num >> 8; /* 寄存器个数 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _num; /* 寄存器个数 低字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = 2 * _num; /* 数据字节数 */
|
||
|
||
for (i = 0; i < 2 * _num; i++)
|
||
{
|
||
if (g_tModH.TxCount > H_RX_BUF_SIZE - 3)
|
||
{
|
||
return; /* 数据超过缓冲区超度,直接丢弃不发送 */
|
||
}
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _buf[i]; /* 后面的数据长度 */
|
||
}
|
||
|
||
MODH_SendAckWithCRC(); /* 发送数据,自动加CRC */
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Send05H
|
||
* 功能说明: 发送05H指令,写强置单线圈
|
||
* 形 参: _addr : 从站地址
|
||
* _reg : 寄存器编号
|
||
* _value : 寄存器值,2字节
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Send05H(uint8_t _addr, uint16_t _reg, uint16_t _value)
|
||
{
|
||
g_tModH.TxCount = 0;
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _addr; /* 从站地址 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = 0x05; /* 功能码 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8; /* 寄存器编号 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg; /* 寄存器编号 低字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _value >> 8; /* 寄存器值 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _value; /* 寄存器值 低字节 */
|
||
|
||
MODH_SendAckWithCRC(); /* 发送数据,自动加CRC */
|
||
|
||
g_tModH.fAck05H = 0; /* 如果收到从机的应答,则这个标志会设为1 */
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Send06H
|
||
* 功能说明: 发送06H指令,写1个保持寄存器
|
||
* 形 参: _addr : 从站地址
|
||
* _reg : 寄存器编号
|
||
* _value : 寄存器值,2字节
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Send06H(uint8_t _addr, uint16_t _reg, uint16_t _value)
|
||
{
|
||
g_tModH.TxCount = 0;
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _addr; /* 从站地址 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = 0x06; /* 功能码 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8; /* 寄存器编号 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg; /* 寄存器编号 低字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _value >> 8; /* 寄存器值 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _value; /* 寄存器值 低字节 */
|
||
|
||
MODH_SendAckWithCRC(); /* 发送数据,自动加CRC */
|
||
|
||
g_tModH.fAck06H = 0; /* 如果收到从机的应答,则这个标志会设为1 */
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Send03H
|
||
* 功能说明: 发送03H指令,查询1个或多个保持寄存器
|
||
* 形 参: _addr : 从站地址
|
||
* _reg : 寄存器编号
|
||
* _num : 寄存器个数
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Send03H(uint8_t _addr, uint16_t _reg, uint16_t _num)
|
||
{
|
||
g_tModH.TxCount = 0;
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _addr; /* 从站地址 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = 0x03; /* 功能码 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg >> 8; /* 寄存器编号 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _reg; /* 寄存器编号 低字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _num >> 8; /* 寄存器个数 高字节 */
|
||
g_tModH.TxBuf[g_tModH.TxCount++] = _num; /* 寄存器个数 低字节 */
|
||
|
||
MODH_SendAckWithCRC(); /* 发送数据,自动加CRC */
|
||
g_tModH.fAck03H = 0; /* 清接收标志 */
|
||
g_tModH.RegNum = _num; /* 寄存器个数 */
|
||
g_tModH.Reg03H = _reg; /* 保存03H指令中的寄存器地址,方便对应答数据进行分类 */
|
||
}
|
||
|
||
#if 0
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_ReciveNew
|
||
* 功能说明: 串口接收中断服务程序会调用本函数。当收到一个字节时,执行一次本函数。
|
||
* 形 参:
|
||
* 返 回 值: 1 表示有数据
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_ReciveNew(uint8_t _data)
|
||
{
|
||
/*
|
||
3.5个字符的时间间隔,只是用在RTU模式下面,因为RTU模式没有开始符和结束符,
|
||
两个数据包之间只能靠时间间隔来区分,Modbus定义在不同的波特率下,间隔时间是不一样的,
|
||
所以就是3.5个字符的时间,波特率高,这个时间间隔就小,波特率低,这个时间间隔相应就大
|
||
|
||
4800 = 7.297ms
|
||
9600 = 3.646ms
|
||
19200 = 1.771ms
|
||
38400 = 0.885ms
|
||
*/
|
||
uint32_t timeout;
|
||
|
||
g_modh_timeout = 0;
|
||
|
||
|
||
timeout = 48000000 / g_tParam.HBaud485; /* 计算超时时间,单位us 35000000*/
|
||
|
||
//timeout = 35000000 / g_tParam.Baud485; /* 计算超时时间,单位us 35000000*/
|
||
|
||
/* 硬件定时中断,定时精度us 硬件定时器2用于MODBUS从机, 定时器3用于MODBUS从机主机*/
|
||
bsp_StartHardTimer(3, timeout, (void *)MODH_RxTimeOut);
|
||
|
||
if (g_tModH.RxCount < H_RX_BUF_SIZE)
|
||
{
|
||
g_tModH.RxBuf[g_tModH.RxCount++] = _data;
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_RxTimeOut
|
||
* 功能说明: 超过3.5个字符时间后执行本函数。 设置全局变量 g_rtu_timeout = 1; 通知主程序开始解码。
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
static void MODH_RxTimeOut(void)
|
||
{
|
||
g_modh_timeout = 1;
|
||
}
|
||
#endif
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Poll
|
||
* 功能说明: 接收控制器指令. 1ms 响应时间。
|
||
* 形 参: 无
|
||
* 返 回 值: 0 表示无数据 1表示收到正确命令
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Poll(void)
|
||
{
|
||
uint16_t crc1;
|
||
|
||
if (g_modh_timeout == 0)
|
||
{
|
||
/* 没有超时,继续接收。不要清零 g_tModH.RxCount */
|
||
return;
|
||
}
|
||
|
||
/* 收到命令
|
||
05 06 00 88 04 57 3B70 (8 字节)
|
||
05 : 数码管屏的号站,
|
||
06 : 指令
|
||
00 88 : 数码管屏的显示寄存器
|
||
04 57 : 数据,,,转换成 10 进制是 1111.高位在前,
|
||
3B70 : 二个字节 CRC 码 从05到 57的校验
|
||
*/
|
||
g_modh_timeout = 0;
|
||
|
||
if (g_tModH.RxCount < 4)
|
||
{
|
||
goto err_ret;
|
||
}
|
||
|
||
/* 计算CRC校验和 */
|
||
crc1 = CRC16_Modbus(g_tModH.RxBuf, g_tModH.RxCount);
|
||
if (crc1 != 0)
|
||
{
|
||
goto err_ret;
|
||
}
|
||
|
||
/* 分析应用层协议 */
|
||
MODH_AnalyzeApp();
|
||
|
||
err_ret:
|
||
g_tModH.RxCount = 0; /* 必须清零计数器,方便下次帧同步 */
|
||
}
|
||
|
||
static void MODH_Read_01H(void)
|
||
{
|
||
;
|
||
}
|
||
|
||
static void MODH_Read_02H(void)
|
||
{
|
||
;
|
||
}
|
||
|
||
static void MODH_Read_04H(void)
|
||
{
|
||
;
|
||
}
|
||
|
||
static void MODH_Read_05H(void)
|
||
{
|
||
if (g_tModH.RxCount > 0)
|
||
{
|
||
if (g_tModH.RxBuf[0] == SlaveAddr) //g_tParam.HAddr485
|
||
{
|
||
g_tModH.fAck05H = 1; /* 接收到应答 */
|
||
}
|
||
};
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Read_06H
|
||
* 功能说明: 分析06H指令的应答数据
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
static void MODH_Read_06H(void)
|
||
{
|
||
if (g_tModH.RxCount > 0)
|
||
{
|
||
if (g_tModH.RxBuf[0] == SlaveAddr) //g_tParam.HAddr485
|
||
{
|
||
g_tModH.fAck06H = 1; /* 接收到应答 */
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Read_03H
|
||
* 功能说明: 分析03H指令的应答数据
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Read_03H(void)
|
||
{
|
||
#if 0
|
||
uint8_t bytes;
|
||
uint8_t *p;
|
||
|
||
if (g_tModH.RxCount > 0)
|
||
{
|
||
//BEEP_KeyTone();
|
||
|
||
bytes = g_tModH.RxBuf[2]; /* 数据长度 字节数 */
|
||
switch (g_tModH.Reg03H)
|
||
{
|
||
case REG_P01:
|
||
if (bytes == 32)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
|
||
g_tVar.P01 = BEBufToUint16(p); p += 2; /* 寄存器 */
|
||
g_tVar.P02 = BEBufToUint16(p); p += 2; /* 寄存器 */
|
||
g_tVar.P03 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P04 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P05 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P06 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P07 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P08 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P09 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tVar.P10 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P11 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P12 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P13 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P14 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P15 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P16 = BEBufToUint16(p); p += 2;
|
||
// bsp_PutMsg(MSG_READ_FINISH, 0); /* 开机时读取一次数据,发送消息表示读取完毕 */
|
||
g_tModH.fAck03H = 1;
|
||
}
|
||
break;
|
||
|
||
case REG_P01 + 16:
|
||
if (bytes == 32)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
|
||
g_tVar.P17 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P18 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P19 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tVar.P20 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P21 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P22 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P23 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P24 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P25 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P26 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P27 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P28 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P29 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tVar.P30 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P31 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P32 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tModH.fAck03H = 2;
|
||
}
|
||
break;
|
||
|
||
case REG_P01 + 32:
|
||
if (bytes == 32)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
|
||
g_tVar.P33 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P34 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P35 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P36 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P37 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P38 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P39 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tVar.P40 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P41 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P42 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P43 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P44 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P45 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P46 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P47 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P48 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tModH.fAck03H = 3;
|
||
}
|
||
break;
|
||
|
||
case REG_P01 + 48:
|
||
if (bytes == 32)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
|
||
g_tVar.P49 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tVar.P50 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P51 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P52 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P53 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P54 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P55 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P56 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P57 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P58 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P59 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tVar.P60 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P61 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P62 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P63 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P64 = BEBufToUint16(p); p += 2;
|
||
|
||
g_tModH.fAck03H = 4;
|
||
}
|
||
break;
|
||
|
||
case REG_H40: /* 总运行次数 */
|
||
if (bytes == 28) /* 扫描读 */
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
|
||
g_tVar.H40 = BEBufToUint32(p); p += 4;
|
||
g_tVar.H42 = BEBufToUint32(p); p += 4;
|
||
g_tVar.H44 = BEBufToUint16(p); p += 2;
|
||
g_tVar.H45 = BEBufToUint16(p); p += 2;
|
||
g_tVar.H46 = BEBufToUint16(p); p += 2;
|
||
g_tVar.H47 = BEBufToUint16(p); p += 2;
|
||
g_tVar.H48 = BEBufToUint16(p); p += 2;
|
||
g_tVar.H49 = BEBufToUint16(p); p += 2;
|
||
g_tVar.H4A = BEBufToUint16(p); p += 2;
|
||
g_tVar.H4B = BEBufToUint16(p); p += 2;
|
||
|
||
g_tVar.H4C = BEBufToUint16(p); p += 2;
|
||
g_tVar.H4D = BEBufToUint16(p); p += 2;
|
||
|
||
g_tModH.fAck03H = 5;
|
||
}
|
||
|
||
#if 0
|
||
if (bytes == 4)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
g_tVar.H40 = BEBufToUint32(p);
|
||
g_tModH.fAck03H = 1;
|
||
}
|
||
#endif
|
||
break;
|
||
|
||
case REG_H44: /* 故障内容,查询到主板上报的故障时,自动测试界面返回主菜单 */
|
||
if (bytes == 2)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
g_tVar.H44 = BEBufToUint16(p);
|
||
|
||
g_tModH.fAck03H = 1;
|
||
}
|
||
break;
|
||
|
||
#if 0
|
||
case REG_H4A: /* 输入状态查询 */
|
||
if (bytes == 2)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
g_tVar.H4A = BEBufToUint16(p);
|
||
g_tModH.fAck03H = 1;
|
||
}
|
||
break;
|
||
|
||
case REG_H42: /* 维护后运行的次数 */
|
||
if (bytes == 4)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
g_tVar.H42 = BEBufToUint32(p);
|
||
}
|
||
break;
|
||
|
||
case REG_H47: /* 系统查询1 */
|
||
break;
|
||
|
||
case REG_H49: /* 系统查询2 */
|
||
break;
|
||
|
||
case REG_H48: /* 系统查询3 */
|
||
break;
|
||
|
||
case REG_H4D: /* 系统查询4 */
|
||
break;
|
||
|
||
case REG_H4C: /* 系统查询5 */
|
||
break;
|
||
|
||
case REG_P16: /* 系统查询6 */
|
||
break;
|
||
|
||
case REG_P18: /* 系统查询7 */
|
||
break;
|
||
|
||
case REG_H4B: /* 系统查询8 */
|
||
break;
|
||
|
||
case REG_P63: /* 系统版本 */
|
||
if (bytes == 4)
|
||
{
|
||
p = &g_tModH.RxBuf[3];
|
||
g_tVar.P63 = BEBufToUint16(p); p += 2;
|
||
g_tVar.P64 = BEBufToUint16(p);
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Read_10H
|
||
* 功能说明: 分析10H指令的应答数据
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Read_10H(void)
|
||
{
|
||
/*
|
||
10H指令的应答:
|
||
从机地址 11
|
||
功能码 10
|
||
寄存器起始地址高字节 00
|
||
寄存器起始地址低字节 01
|
||
寄存器数量高字节 00
|
||
寄存器数量低字节 02
|
||
CRC校验高字节 12
|
||
CRC校验低字节 98
|
||
*/
|
||
//uint8_t addr;
|
||
//uint8_t bytes;
|
||
//uint8_t reg;
|
||
|
||
if (g_tModH.RxCount > 0)
|
||
{
|
||
// BEEP_KeyTone();
|
||
|
||
/* 发送消息. 消息体是寄存器地址和数量 */
|
||
#if 0
|
||
{
|
||
uint8_t buf[4];
|
||
|
||
buf[0] = g_tModH.RxBuf[0]; /* 从机地址 */
|
||
buf[1] = g_tModH.RxBuf[5]; /* 寄存器长度 */
|
||
buf[2] = g_tModH.RxBuf[2]; /* 寄存器地址高16位 */
|
||
buf[3] = g_tModH.RxBuf[3]; /* 寄存器地址低16位 */
|
||
bsp_PutMsg(MSG_RX_10H, (uint32_t)buf);
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_WriteParam
|
||
* 功能说明: 单个参数. 通过发送06H指令实现,发送之后,等待从机应答。循环10次写命令
|
||
* 形 参: 无
|
||
* 返 回 值: 1 表示成功。0 表示失败(通信超时或被拒绝)
|
||
*********************************************************************************************************
|
||
*/
|
||
extern uint8_t g_fTcpState;
|
||
uint8_t MODH_WriteParam(uint16_t _reg, uint16_t _value)
|
||
{
|
||
int32_t time1;
|
||
uint8_t i;
|
||
|
||
for (i = 0; i < 3; i++)
|
||
{
|
||
MODH_Send06H(SLAVE_ADDR, _reg, _value);
|
||
/* 将TCP状态标志设置为非接收到数据状态 */
|
||
g_tClient.TcpState = g_fTcpState; /* 2016-10-17 add by xd */
|
||
time1 = bsp_GetRunTime(); /* 记录命令发送的时刻 */
|
||
|
||
while (1)
|
||
{
|
||
bsp_Idle();
|
||
|
||
/* 超时大于 150ms ,则认为异常, 100ms有时会超时,数据没有接收到,PC软件应答时间间隔几十到一百多浮动 */
|
||
if (bsp_CheckRunTime(time1) > 200) //100
|
||
{
|
||
break;
|
||
}
|
||
|
||
if (g_tClient.TcpState == 2)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tClient.TcpState == 2)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tClient.TcpState == 2) /* 接收到数据 */
|
||
{
|
||
return 1;
|
||
}
|
||
else
|
||
{
|
||
return 0; /* 通信超时了 */
|
||
}
|
||
}
|
||
|
||
#if 0
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_Read_30H
|
||
* 功能说明: 分析30H指令的应答数据
|
||
* 形 参: 无
|
||
* 返 回 值: 无
|
||
*********************************************************************************************************
|
||
*/
|
||
void MODH_Read_30H(void)
|
||
{
|
||
uint8_t addr;
|
||
uint8_t bytes;
|
||
|
||
if (g_tModH.RxCount > 0)
|
||
{
|
||
//BEEP_KeyTone();
|
||
|
||
addr = g_tModH.RxBuf[0];
|
||
bytes = g_tModH.RxBuf[2];
|
||
#if 0
|
||
if (g_tModH.Reg30H == SREG_STATUS) /* 主机查询状态字 - 实时产量 - 当班员工工号 */
|
||
{
|
||
if ((addr < DEV_NUM_MAX) && (addr > 0) && (addr != ADDR_FF) && (bytes >= 10))
|
||
{
|
||
addr--;
|
||
|
||
g_tVar.Dev[addr].CommErr = 0; /* 通信错误清零 */
|
||
|
||
g_tVar.Dev[addr].Status = BEBufToUint16(&g_tModH.RxBuf[3]);
|
||
|
||
if (bytes >= 4)
|
||
{
|
||
g_tVar.Dev[addr].CountNow = BEBufToUint16(&g_tModH.RxBuf[5]);
|
||
}
|
||
if (bytes >= 6)
|
||
{
|
||
g_tVar.Dev[addr].GH[0] = BEBufToUint16(&g_tModH.RxBuf[7]);
|
||
}
|
||
if (bytes >= 8)
|
||
{
|
||
g_tVar.Dev[addr].GH[1] = BEBufToUint16(&g_tModH.RxBuf[9]);
|
||
}
|
||
if (bytes >= 10)
|
||
{
|
||
g_tVar.Dev[addr].GH[2] = BEBufToUint16(&g_tModH.RxBuf[11]);
|
||
}
|
||
|
||
bsp_PutMsg(MSG_433M_OK, addr + 1); /* 433M 通信OK, 通知监控界面刷新图标 */
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_WriteParam_05H
|
||
* 功能说明: 单个参数. 通过发送05H指令实现,发送之后,等待从机应答。
|
||
* 形 参: 无
|
||
* 返 回 值: 1 表示成功。0 表示失败(通信超时或被拒绝)
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t MODH_WriteParam_05H(uint16_t _reg, uint16_t _value)
|
||
{
|
||
int32_t time1;
|
||
uint8_t i;
|
||
|
||
for (i = 0; i < 10; i++)
|
||
{
|
||
MODH_Send05H (SlaveAddr, _reg, _value);
|
||
time1 = bsp_GetRunTime(); /* 记录命令发送的时刻 */
|
||
|
||
g_LastTime = bsp_GetRunTime(); /* 300ms */
|
||
while (1)
|
||
{
|
||
bsp_Idle();
|
||
|
||
/* 超时大于 150ms ,则认为异常 */
|
||
if (bsp_CheckRunTime(time1) > 150) //100
|
||
{
|
||
g_LastTime = bsp_GetRunTime();
|
||
break; /* 通信超时了 */
|
||
}
|
||
|
||
if (g_tModH.fAck05H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck05H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck05H == 0)
|
||
{
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
/* 读一个寄存器 */
|
||
uint8_t MODH_ReadParam_03H(uint16_t _reg, uint16_t _num)
|
||
{
|
||
int32_t time1;
|
||
uint8_t i;
|
||
|
||
for (i = 0; i < 10; i++)
|
||
{
|
||
MODH_Send03H (SlaveAddr, _reg, _num);
|
||
time1 = bsp_GetRunTime(); /* 记录命令发送的时刻 */
|
||
|
||
g_LastTime = bsp_GetRunTime(); /* 300ms */
|
||
while (1)
|
||
{
|
||
bsp_Idle();
|
||
|
||
/* 超时大于 150ms ,则认为异常 */
|
||
if (bsp_CheckRunTime(time1) > 150) //100
|
||
{
|
||
g_LastTime = bsp_GetRunTime();
|
||
break; /* 通信超时了 */
|
||
}
|
||
|
||
if (g_tModH.fAck03H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck03H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck03H == 0)
|
||
{
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
return 1; /* 写入03H参数成功 */
|
||
}
|
||
}
|
||
|
||
/* 读64个寄存器的参数,读10次 */
|
||
uint8_t MODH_ReadParam_03H_16(uint16_t _reg, uint16_t _num)
|
||
{
|
||
int32_t time1;
|
||
uint8_t i;
|
||
uint8_t State = 0;
|
||
|
||
while (1)
|
||
{
|
||
for (i = 0; i < 10; i++)
|
||
{
|
||
/* 主板的地址就定0x55,最多连续读16个参数(32字节)*/
|
||
MODH_Send03H (SlaveAddr, _reg + State * _num, _num); /* 发送查询命令 */
|
||
|
||
time1 = bsp_GetRunTime(); /* 记录命令发送的时刻 */
|
||
|
||
g_LastTime = bsp_GetRunTime(); /* 300ms */
|
||
while (1)
|
||
{
|
||
bsp_Idle();
|
||
|
||
/* 超时大于 200ms ,则认为异常 */
|
||
if (bsp_CheckRunTime(time1) > 200) //200
|
||
{
|
||
g_LastTime = bsp_GetRunTime();
|
||
break; /* 通信超时了 */
|
||
}
|
||
|
||
if (g_tModH.fAck03H > 0)
|
||
{
|
||
State++;
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck03H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck03H == 0)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
if (State == 4)
|
||
{
|
||
return 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
/* 轮询读14个参数 */
|
||
uint8_t MODH_CycleRead_03H(uint16_t _reg)
|
||
{
|
||
int32_t time1;
|
||
|
||
/* 主板的地址就定0x55,最多连续读16个参数(32字节)*/
|
||
MODH_Send03H (SlaveAddr, _reg, 14); /* 发送查询命令 */
|
||
|
||
time1 = bsp_GetRunTime(); /* 记录命令发送的时刻 */
|
||
|
||
g_LastTime = bsp_GetRunTime(); /* 300ms */
|
||
while (1)
|
||
{
|
||
bsp_Idle();
|
||
|
||
/* 超时大于 200ms ,则认为异常 */
|
||
if (bsp_CheckRunTime(time1) > 200)
|
||
{
|
||
g_LastTime = bsp_GetRunTime();
|
||
return 0; /* 通信超时了 */
|
||
}
|
||
|
||
if (g_tModH.fAck03H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
return 1;
|
||
}
|
||
|
||
|
||
/*
|
||
*********************************************************************************************************
|
||
* 函 数 名: MODH_AllowRun_05H
|
||
* 功能说明: 允许禁止运行专用05指令,不调用bsp_Idle(); 调用解析命令函数
|
||
* 形 参: 无
|
||
* 返 回 值: 1 表示成功。0 表示失败(通信超时或被拒绝)
|
||
*********************************************************************************************************
|
||
*/
|
||
uint8_t MODH_AllowRun_05H(uint16_t _reg, uint16_t _value)
|
||
{
|
||
int32_t time1;
|
||
uint8_t i;
|
||
|
||
for (i = 0; i < 10; i++)
|
||
{
|
||
MODH_Send05H (SlaveAddr, _reg, _value);
|
||
time1 = bsp_GetRunTime(); /* 记录命令发送的时刻 */
|
||
|
||
g_LastTime = bsp_GetRunTime();
|
||
while (1)
|
||
{
|
||
//bsp_Idle();
|
||
MODH_Poll();
|
||
MODS_Poll();
|
||
|
||
/* 超时大于 150ms ,则认为异常 */
|
||
if (bsp_CheckRunTime(time1) > 150) //100
|
||
{
|
||
g_LastTime = bsp_GetRunTime();
|
||
break; /* 通信超时了 */
|
||
}
|
||
|
||
if (g_tModH.fAck05H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck05H > 0)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (g_tModH.fAck05H == 0)
|
||
{
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
return 1;
|
||
}
|
||
}
|
||
#endif
|
||
|
||
/***************************** 安富莱电子 www.armfly.com (END OF FILE) *********************************/
|