parent
af6d6fd969
commit
f92b4a15f7
|
@ -116,7 +116,7 @@ typedef struct
|
|||
uint8_t bluetooth_enable; //蓝牙透传使能
|
||||
uint8_t modbus_enable; //MODBUS使能
|
||||
SIG_MODBUS_TYPE modbus_type; //SIG在modbus中作为主或从
|
||||
uint16_t modbus_timeout_period; //SIG作为主设备时,等待从设备响应的超时时间上限(ms)
|
||||
uint8_t modbus_master_send_flag; //发送标志
|
||||
|
||||
//ITEMS_3
|
||||
uint8_t item3_page0_lightflag; //照明状态标志,0熄灭,1开启
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "SIG24130.h"
|
||||
#include "modbus_485.h"
|
||||
#include "modbus_rtu.h"
|
||||
#include "modbus_rtu_master.h"
|
||||
|
||||
extern osThreadId task_lcdHandle;
|
||||
extern osThreadId task_menuHandle;
|
||||
|
|
|
@ -286,6 +286,18 @@ uint8_t init_set_bar(uint8_t start, uint8_t end, uint16_t interval)
|
|||
|
||||
void scr_main_run(void)
|
||||
{
|
||||
//modbus主站功能测试
|
||||
if(tabdata.modbus_master_send_flag == 1)
|
||||
{
|
||||
tabdata.modbus_enable = 1;
|
||||
tabdata.modbus_type = SIG_MASTER;
|
||||
|
||||
tabdata.modbus_master_send_flag = 0;
|
||||
|
||||
modbus_rtu_master_load();
|
||||
modbus_rtu_master_send();
|
||||
}
|
||||
|
||||
//实时更新设定值
|
||||
sig_sv_update(); //不做延时,尽快响应
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ void tab_data_init(void)
|
|||
tabdata.bluetooth_enable = 0; //HART默认使能状态
|
||||
tabdata.modbus_enable = 0; //HART默认使能状态
|
||||
tabdata.modbus_type = SIG_SLAVE; //SIG默认作为从设备
|
||||
tabdata.modbus_timeout_period = 1000; //默认超时时间为1000ms
|
||||
tabdata.modbus_master_send_flag = 0; //触发发送后置1,发送完成后置0
|
||||
|
||||
//ITEMS_3(部分内容位于EERPOM读取)
|
||||
tabdata.item3_page0_lightflag = 0; //照明状态标志,0熄灭,1开启
|
||||
|
@ -592,6 +592,14 @@ void scr_setting_run(void) //详细设置界面
|
|||
|
||||
//处理复位事件
|
||||
deal_data_reset();
|
||||
|
||||
if(tabdata.modbus_master_send_flag == 1)
|
||||
{
|
||||
tabdata.modbus_master_send_flag = 0;
|
||||
|
||||
modbus_rtu_master_load();
|
||||
modbus_rtu_master_send();
|
||||
}
|
||||
}
|
||||
|
||||
//执行保存功能
|
||||
|
|
|
@ -847,6 +847,9 @@ void my_inits_gather(void)
|
|||
// lv_demo_benchmark(); //lv_conf.h, line:761
|
||||
setup_ui(&guider_ui); // 初始化UI,设置与加载初始界面
|
||||
events_init(&guider_ui); // 初始化事件
|
||||
|
||||
//MODBUS主站初始化
|
||||
modbus_rtu_master_init();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -65,11 +65,19 @@ void duty_tim6(void)
|
|||
input_500ms_flag = 1;
|
||||
}
|
||||
|
||||
if(sig2slave_step == 1)
|
||||
//发送完成 或者 已经接收到一部分数据之后开始计时
|
||||
if( (sig2slave_step == 1)||(mod_master.tx_flag == TX_OK) )
|
||||
{
|
||||
sig2slave_current_tick++;
|
||||
if(sig2slave_current_tick > tabdata.modbus_timeout_period)
|
||||
if(sig2slave_current_tick > mod_master.timeout)
|
||||
{
|
||||
if(sig2slave_step == 0)
|
||||
{
|
||||
//进入此处说明发送成功后未收到任何数据
|
||||
mod_master.rx_error_message = RX_ERROR_TIMEOUT;
|
||||
mod_master.tx_flag = TX_NONE;
|
||||
}
|
||||
|
||||
HAL_UART_DMAStop(&huart2);
|
||||
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
|
||||
|
||||
|
|
|
@ -14,18 +14,13 @@ typedef enum
|
|||
extern uint32_t tick_start;
|
||||
extern uint32_t tick_middle;
|
||||
extern uint32_t tick_end;
|
||||
extern uint32_t trans_log_rx;
|
||||
//extern uint32_t trans_log_rx;
|
||||
extern uint32_t trans_log_tx;
|
||||
extern uint8_t sig2slave_step;
|
||||
extern TRANS_PROCESS st_flag;
|
||||
|
||||
void parse_scom_485(st_scom *scom);
|
||||
|
||||
//PC <---SIG---> HART/BLUETOOTH/MODBUS
|
||||
//BLE:将接收完成的BLE数据发送至上位机,将来自上位机的BLE数据装载至comhart_tx
|
||||
//HART:将接收完成的HART的数据发送至上位机,将来自上位机的HART数据装载至comhart_tx
|
||||
void transparent_485(st_scom *scom);
|
||||
|
||||
//透传,DMA发送,与发送回调组合使用
|
||||
void transparent_tim(void);
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
#define ReadDisInputState 0x02 //读取输入状态
|
||||
#define ReadHoldReg 0x03 //读取保持寄存器
|
||||
#define ReadInputReg 0x04 //读取输入寄存器
|
||||
#define WriteSingleCoil 0x05 //强制写单线圈输出状态
|
||||
#define WriteSingleReg 0x06 //预设(写)单寄存器
|
||||
#define WriteMultiCoil 0x0F //强制写多线圈输出状态
|
||||
#define WriteMultiReg 0x10 //预设(写)多寄存器
|
||||
#define WriteSingleCoil 0x05 //写单个线圈寄存器
|
||||
#define WriteSingleReg 0x06 //写单个保持寄存器
|
||||
#define WriteMultiCoil 0x0F //写多个线圈寄存器
|
||||
#define WriteMultiReg 0x10 //写多个保持寄存器
|
||||
|
||||
#define COIL_ADD_MIN 0x00
|
||||
#define COIL_ADD_MAX 0x64
|
||||
|
@ -63,6 +63,7 @@ extern uint8_t DisState [(MAX_DIS_NUM + 7) / 8];
|
|||
extern uint16_t InputReg[MAX_INPUT_REG_NUM];
|
||||
extern uint16_t HoldReg[MAX_HOLD_REG_NUM];
|
||||
extern Var_Reg SamVarReg;
|
||||
extern eMBException ex_message;
|
||||
|
||||
//MODBUS_RTU
|
||||
void modbus_analysis_rtu(uint8_t * upRxdbuf, uint16_t wRxdLen);
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
#ifndef __MODBUS_RTU_MASTER_H
|
||||
#define __MODBUS_RTU_MASTER_H
|
||||
|
||||
#include "apps_gather.h"
|
||||
#include "modbus_rtu.h"
|
||||
|
||||
#define TX_BUFF_MAX 128
|
||||
#define TX_DATA_MAX 100
|
||||
#define RX_BUFF_MAX 128
|
||||
|
||||
#define TX_NONE 0x00 //没有需要发送的数据
|
||||
#define TX_WAITING 0x01 //数据准备完成,等待发送
|
||||
#define TX_OK 0x02 //发送完成
|
||||
#define RX_NONE 0x00 //没有接收到数据
|
||||
#define RX_WAITING 0x01 //等待接收
|
||||
#define RX_OK 0x02 //接收完成
|
||||
|
||||
typedef enum
|
||||
{
|
||||
RX_ERROR_NONE = 0, //数据接收未出现错误
|
||||
RX_ERROR_TIMEOUT, //接收数据超时
|
||||
RX_ERROR_OVERFLOW, //接收到的数据超出缓存区
|
||||
RX_ERROR_WRONG_ID //接收到的设备ID与目标ID不符
|
||||
}ERROR_NESSAGE_RX;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TX_ERROR_NONE = 0, //数据发送未出现错误
|
||||
TX_ERROR_WRONG_CMD, //命令字错误
|
||||
TX_ERROR_COIL_NUM, //写多个线圈时,线圈数量或字节数错误
|
||||
TX_ERROR_HOLDREG_NUM //写保持寄存器时,寄存器数量或字节数错误
|
||||
}ERROR_NESSAGE_TX;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t target_id; //目标ID,从设备识别号、地址
|
||||
uint8_t command_code; //命令字
|
||||
uint16_t start_address; //起始地址
|
||||
uint16_t register_num; //线圈、寄存器数量
|
||||
uint16_t crc16; //MODBUS_CRC16校验码
|
||||
uint8_t byte_num; //需要写入的线圈、保持寄存器字节数
|
||||
uint8_t data_tx_value8[TX_DATA_MAX]; //需要写入的数值,8位
|
||||
uint16_t data_tx_value16[TX_DATA_MAX]; //需要写入的数值,16位
|
||||
uint8_t data_tx[TX_BUFF_MAX]; //存放完整的发送数据报
|
||||
uint8_t data_rx[RX_BUFF_MAX]; //存放完整的接收数据报
|
||||
uint8_t data_tx_len; //发送的数据报长度
|
||||
uint8_t data_rx_len; //接收到的数据报长度
|
||||
ERROR_NESSAGE_RX rx_error_message; //接收过程中的错误信息
|
||||
ERROR_NESSAGE_TX tx_error_message; //发送过程中的错误信息
|
||||
uint16_t timeout; //超时、等待时间
|
||||
uint8_t rx_flag; //接收标志位
|
||||
uint8_t tx_flag; //发送标志位
|
||||
|
||||
}MODBUS_MASTER;
|
||||
|
||||
extern MODBUS_MASTER mod_master;
|
||||
|
||||
void modbus_rtu_master_init(void);
|
||||
|
||||
void modbus_rtu_master_load(void);
|
||||
|
||||
void modbus_rtu_master_send(void);
|
||||
|
||||
void modbus_rtu_master_analysis(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -3,19 +3,10 @@
|
|||
uint32_t tick_start = 0;
|
||||
uint32_t tick_middle = 0;
|
||||
uint32_t tick_end = 0;
|
||||
uint32_t trans_log_rx = 0;
|
||||
//uint32_t trans_log_rx = 0;
|
||||
uint32_t trans_log_tx = 0;
|
||||
TRANS_PROCESS st_flag = TRANSPARENT_WAIT;
|
||||
|
||||
//static void scom_485_send(UART_HandleTypeDef *huart, char *str)
|
||||
//{
|
||||
// RS485_RW(RS485_WR);
|
||||
// vTaskDelay(10);
|
||||
// printf("\r\n");
|
||||
// usart_printf(huart, "rs485 receive:[%s]\r\n", str);
|
||||
// printf("printf test_data:[%s]\r\n", str);
|
||||
// RS485_RW(RS485_RD);
|
||||
//}
|
||||
|
||||
void parse_scom_485(st_scom *scom)
|
||||
{
|
||||
|
@ -24,89 +15,13 @@ void parse_scom_485(st_scom *scom)
|
|||
scom->rx_flag = FALSE;
|
||||
if ((scom->rx_buff[0] == 0xff) && (scom->rx_buff[1] == 0xff) && (scom->rx_buff[scom->rx_len - 1] == 0xaa))
|
||||
{
|
||||
// scom_485_send(&huart2, scom->rx_buff);
|
||||
//RS485_RW(RS485_WR);
|
||||
vTaskDelay(10);
|
||||
HAL_UART_Transmit(&huart2, scom->rx_buff, scom->rx_len, 0xFFFF);
|
||||
//RS485_RW(RS485_RD);
|
||||
}
|
||||
scom->rx_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void transparent_485(st_scom *scom)
|
||||
{
|
||||
if(scom != &scom2_rs485) return;
|
||||
|
||||
//来自上位机的数据是否接收完成
|
||||
if(scom->rx_flag == TRUE)
|
||||
{
|
||||
scom->rx_flag = FALSE;
|
||||
|
||||
// switch (sig_trans)
|
||||
// {
|
||||
// case TRANS_HART:
|
||||
// {
|
||||
// if ((scom->rx_buff[0] == 0xff) && (scom->rx_buff[1] == 0xff) && (scom->rx_buff[scom->rx_len - 1] == 0xaa))
|
||||
// {
|
||||
// //接收到的数据是否符合HART数据报,符合则写入HART的tx,准备发送至HART设备
|
||||
// memcpy(scom1_hart.tx_buff, scom->rx_buff, sizeof(scom->rx_buff));
|
||||
// scom1_hart.tx_flag = TRUE;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case TRANS_BLUETOOTH:
|
||||
// {
|
||||
// //将接收到的数据存入BLE的tx,准备发送至蓝牙设备
|
||||
// memcpy(scom6_ble.tx_buff, scom->rx_buff, sizeof(scom->rx_buff));
|
||||
// scom6_ble.tx_flag = TRUE;
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case TRANS_MODBUS:
|
||||
// {
|
||||
// modbus_process_rtu();
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case TRANS_NONE:
|
||||
// {}
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
//清空缓存区,等待新的数据
|
||||
memset(scom->rx_buff, 0, sizeof(scom->rx_buff));
|
||||
scom->rx_len = 0;
|
||||
|
||||
}
|
||||
|
||||
//数据是否准备完成
|
||||
if( (scom->tx_flag == TRUE) && (sig_trans != TRANS_NONE) )
|
||||
{
|
||||
scom->tx_flag = FALSE;
|
||||
|
||||
//vTaskDelay(10);
|
||||
wu_delay_us(1000);
|
||||
|
||||
//将数据发送至上位机
|
||||
HAL_UART_Transmit(&huart2, scom->tx_buff, scom->tx_len, 0xFFFF);
|
||||
|
||||
//清空缓存区,等待新的数据
|
||||
memset(scom->tx_buff, 0, sizeof(scom->tx_buff));
|
||||
scom->tx_len = 0;
|
||||
//HAL_UART_Transmit_IT(&huart2, scom->tx_buff, scom->tx_len);
|
||||
|
||||
xTaskResumeFromISR(task_lcdHandle);
|
||||
xTaskResumeFromISR(task_menuHandle);
|
||||
screen_suspend_flag = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void transparent_tim(void)
|
||||
{
|
||||
switch (sig_trans)
|
||||
|
@ -306,7 +221,9 @@ void trans_modbus_sig2slave(void)
|
|||
{
|
||||
case 0:
|
||||
{
|
||||
//进入此处说明已经接收完成一部分数据,开始超时计时
|
||||
//进入此处说明已经接收完成一部分数据,重新开始超时计时,发送标志复位
|
||||
mod_master.tx_flag = TX_NONE;
|
||||
sig2slave_current_tick = 0;
|
||||
|
||||
//记录第一次接收到的数据长度
|
||||
sig2slave_data_length_total = scom2_rs485.rx_len;
|
||||
|
@ -342,9 +259,18 @@ void trans_modbus_sig2slave(void)
|
|||
|
||||
case 2:
|
||||
{
|
||||
//进入此处说明超时计时结束,对接收到的数据进行处理
|
||||
if(mod_master.rx_error_message != RX_ERROR_TIMEOUT)
|
||||
{
|
||||
//进入此处说明收到了数据,并且超时计时期间内未收到新的数据
|
||||
modbus_rtu_master_analysis();
|
||||
|
||||
//如果接收到的数据没有错误,则清空相关数据,否则保留
|
||||
if(mod_master.rx_error_message == RX_ERROR_NONE)
|
||||
{
|
||||
modbus_rtu_master_init();
|
||||
}
|
||||
}
|
||||
|
||||
//数据处理完成
|
||||
sig2slave_step = 0;
|
||||
sig_trans = TRANS_NONE;
|
||||
memset(scom2_rs485.rx_buff, 0, scom2_rs485.rx_len);
|
||||
|
|
|
@ -6,6 +6,7 @@ uint16_t InputReg[MAX_INPUT_REG_NUM] = {0x0000,0x0000,0x0000,0x0000}; //输入
|
|||
uint16_t HoldReg[MAX_HOLD_REG_NUM] = {0, 0,0,0x00C8}; //保持寄存器
|
||||
|
||||
Var_Reg SamVarReg;
|
||||
eMBException ex_message = MB_EX_NONE; //从设备返回的异常信息
|
||||
|
||||
/*******************************************************************************
|
||||
函数名称 : Modbus_Analysis
|
||||
|
|
|
@ -0,0 +1,221 @@
|
|||
#include "modbus_rtu_master.h"
|
||||
|
||||
MODBUS_MASTER mod_master;
|
||||
|
||||
void modbus_rtu_master_init(void)
|
||||
{
|
||||
mod_master.target_id = 0x00;
|
||||
mod_master.command_code = 0x00;
|
||||
mod_master.start_address = 0x0000;
|
||||
mod_master.register_num = 0x0000;
|
||||
mod_master.crc16 = 0x0000;
|
||||
mod_master.byte_num = 0;
|
||||
memset(mod_master.data_tx_value8, 0, TX_DATA_MAX);
|
||||
memset(mod_master.data_tx_value16, 0, TX_DATA_MAX);
|
||||
memset(mod_master.data_tx, 0, TX_BUFF_MAX);
|
||||
memset(mod_master.data_rx, 0, RX_BUFF_MAX);
|
||||
mod_master.data_tx_len = 0;
|
||||
mod_master.data_rx_len = 0;
|
||||
mod_master.rx_error_message = RX_ERROR_NONE;
|
||||
mod_master.tx_error_message = TX_ERROR_NONE;
|
||||
mod_master.timeout = 1000;
|
||||
mod_master.rx_flag = RX_NONE;
|
||||
mod_master.tx_flag = TX_NONE;
|
||||
}
|
||||
|
||||
void modbus_rtu_master_load(void)
|
||||
{
|
||||
mod_master.data_tx[0] = mod_master.target_id;
|
||||
mod_master.data_tx[1] = mod_master.command_code;
|
||||
memset(mod_master.data_rx, 0, sizeof(mod_master.data_rx));
|
||||
|
||||
switch (mod_master.data_tx[1])
|
||||
{
|
||||
//读四种寄存器的格式一致
|
||||
case ReadCoilState:
|
||||
{
|
||||
//注释break,直接向下穿透
|
||||
}
|
||||
//break;
|
||||
|
||||
case ReadDisInputState:
|
||||
{
|
||||
//注释break,直接向下穿透
|
||||
}
|
||||
//break;
|
||||
|
||||
case ReadHoldReg:
|
||||
{
|
||||
//注释break,直接向下穿透
|
||||
}
|
||||
//break;
|
||||
|
||||
case ReadInputReg:
|
||||
{
|
||||
mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8);
|
||||
mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF);
|
||||
mod_master.data_tx[4] = (uint8_t)(mod_master.register_num >> 8);
|
||||
mod_master.data_tx[5] = (uint8_t)(mod_master.register_num & 0x00FF);
|
||||
mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 6);
|
||||
mod_master.data_tx[6] = (uint8_t)(mod_master.crc16 & 0x00FF);
|
||||
mod_master.data_tx[7] = (uint8_t)(mod_master.crc16 >> 8);
|
||||
|
||||
mod_master.data_tx_len = 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case WriteSingleCoil:
|
||||
{
|
||||
mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8);
|
||||
mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF);
|
||||
mod_master.data_tx[4] = (uint8_t)(mod_master.data_tx_value8[0] >> 8);
|
||||
mod_master.data_tx[5] = (uint8_t)(mod_master.data_tx_value8[0] & 0x00FF);
|
||||
mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 6);
|
||||
mod_master.data_tx[6] = (uint8_t)(mod_master.crc16 & 0x00FF);
|
||||
mod_master.data_tx[7] = (uint8_t)(mod_master.crc16 >> 8);
|
||||
|
||||
mod_master.data_tx_len = 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case WriteSingleReg:
|
||||
{
|
||||
mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8);
|
||||
mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF);
|
||||
mod_master.data_tx[4] = (uint8_t)(mod_master.data_tx_value16[0] >> 8);
|
||||
mod_master.data_tx[5] = (uint8_t)(mod_master.data_tx_value16[0] & 0x00FF);
|
||||
mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 6);
|
||||
mod_master.data_tx[6] = (uint8_t)(mod_master.crc16 & 0x00FF);
|
||||
mod_master.data_tx[7] = (uint8_t)(mod_master.crc16 >> 8);
|
||||
|
||||
mod_master.data_tx_len = 8;
|
||||
}
|
||||
break;
|
||||
|
||||
case WriteMultiCoil:
|
||||
{
|
||||
if( mod_master.register_num % 8 )
|
||||
{
|
||||
//线圈数量不为8的倍数时,字节数 == (线圈数量/8 + 1)
|
||||
if( (mod_master.register_num/8 + 1) != mod_master.byte_num )
|
||||
{
|
||||
mod_master.tx_error_message = TX_ERROR_COIL_NUM;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//线圈数量为8的倍数时,字节数 == 线圈数量/8
|
||||
if( (mod_master.register_num/8) != mod_master.byte_num )
|
||||
{
|
||||
mod_master.tx_error_message = TX_ERROR_COIL_NUM;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8);
|
||||
mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF);
|
||||
mod_master.data_tx[4] = (uint8_t)(mod_master.register_num >> 8);
|
||||
mod_master.data_tx[5] = (uint8_t)(mod_master.register_num & 0x00FF);
|
||||
mod_master.data_tx[6] = mod_master.byte_num;
|
||||
for(uint8_t i = 1; i <= mod_master.byte_num; i++ )
|
||||
{
|
||||
mod_master.data_tx[6 + i] = mod_master.data_tx_value8[i - 1];
|
||||
}
|
||||
mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 7 + mod_master.byte_num);
|
||||
mod_master.data_tx[7 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 & 0x00FF);
|
||||
mod_master.data_tx[8 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 >> 8);
|
||||
|
||||
mod_master.data_tx_len = 8 + mod_master.byte_num + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case WriteMultiReg:
|
||||
{
|
||||
if( (mod_master.register_num * 2) != mod_master.byte_num )
|
||||
{
|
||||
//字节数 == (寄存器数量*2)
|
||||
mod_master.tx_error_message = TX_ERROR_HOLDREG_NUM;
|
||||
return;
|
||||
}
|
||||
|
||||
mod_master.data_tx[2] = (uint8_t)(mod_master.start_address >> 8);
|
||||
mod_master.data_tx[3] = (uint8_t)(mod_master.start_address & 0x00FF);
|
||||
mod_master.data_tx[4] = (uint8_t)(mod_master.register_num >> 8);
|
||||
mod_master.data_tx[5] = (uint8_t)(mod_master.register_num & 0x00FF);
|
||||
mod_master.data_tx[6] = mod_master.byte_num;
|
||||
for(uint8_t i = 1; i <= mod_master.byte_num; i++ )
|
||||
{
|
||||
mod_master.data_tx[6 + i] = mod_master.data_tx_value16[ (i - 1)/2 ] >> ( 8*(i%2) );
|
||||
}
|
||||
mod_master.crc16 = ModbusCRC16(mod_master.data_tx, 7 + mod_master.byte_num);
|
||||
mod_master.data_tx[7 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 & 0x00FF);
|
||||
mod_master.data_tx[8 + mod_master.byte_num] = (uint8_t)(mod_master.crc16 >> 8);
|
||||
|
||||
mod_master.data_tx_len = 8 + mod_master.byte_num + 1;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
mod_master.tx_error_message = TX_ERROR_WRONG_CMD;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void modbus_rtu_master_send(void)
|
||||
{
|
||||
if(mod_master.tx_error_message == TX_ERROR_NONE)
|
||||
{
|
||||
mod_master.rx_flag = TX_WAITING;
|
||||
|
||||
//将准备好的数据发送至从设备
|
||||
memcpy(scom2_rs485.tx_buff, mod_master.data_tx, mod_master.data_tx_len);
|
||||
scom2_rs485.tx_len = mod_master.data_tx_len;
|
||||
scom2_rs485.tx_flag = TRUE;
|
||||
|
||||
if(scom2_rs485.tx_flag == TRUE)
|
||||
{
|
||||
scom2_rs485.tx_flag = FALSE;
|
||||
|
||||
//将数据发送至上位机
|
||||
HAL_UART_Transmit_DMA(&huart2, scom2_rs485.tx_buff, scom2_rs485.tx_len);
|
||||
}
|
||||
|
||||
//在发送回调中判断发送是否完成
|
||||
sig_trans = TRANS_MODBUS_SIG_TO_SLAVE;
|
||||
}
|
||||
}
|
||||
|
||||
void modbus_rtu_master_analysis(void)
|
||||
{
|
||||
if(scom2_rs485.rx_len > RX_BUFF_MAX)
|
||||
{
|
||||
mod_master.rx_error_message = RX_ERROR_OVERFLOW;
|
||||
return;
|
||||
}
|
||||
|
||||
mod_master.data_rx_len = scom2_rs485.rx_len;
|
||||
memcpy(mod_master.data_rx, scom2_rs485.rx_buff, mod_master.data_rx_len);
|
||||
|
||||
if(mod_master.data_rx[0] != mod_master.target_id)
|
||||
{
|
||||
mod_master.rx_error_message = RX_ERROR_WRONG_ID;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mod_master.data_rx[1] <= 0x80)
|
||||
{
|
||||
//收到的是正常响应
|
||||
}
|
||||
else
|
||||
{
|
||||
//收到的是异常响应
|
||||
ex_message = (eMBException)mod_master.data_rx[2];
|
||||
}
|
||||
|
||||
|
||||
mod_master.rx_flag = RX_OK;
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ extern UART_HandleTypeDef huart6;
|
|||
|
||||
#define RX_DMA_ENABLE 1
|
||||
|
||||
#define BUFFER_SIZE 255
|
||||
#define BUFFER_SIZE 128
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
|
|
@ -465,9 +465,37 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
|||
scom2_rs485.tx_len = 0;
|
||||
|
||||
//开启对应的DMA
|
||||
if(sig_trans == TRANS_HART_TO_PC) HAL_UART_Receive_DMA(&huart1, scom1_hart.rx_buff, BUFFER_SIZE);
|
||||
if(sig_trans == TRANS_BLE_TO_PC) HAL_UART_Receive_DMA(&huart6, scom6_ble.rx_buff, BUFFER_SIZE);
|
||||
if(sig_trans == TRANS_MODBUS_PC_TO_SIG) HAL_UART_Receive_DMA(&huart2, scom2_rs485.rx_buff, BUFFER_SIZE);
|
||||
switch (sig_trans)
|
||||
{
|
||||
case TRANS_HART_TO_PC:
|
||||
{
|
||||
HAL_UART_Receive_DMA(&huart1, scom1_hart.rx_buff, BUFFER_SIZE);
|
||||
}
|
||||
break;
|
||||
|
||||
case TRANS_BLE_TO_PC:
|
||||
{
|
||||
HAL_UART_Receive_DMA(&huart6, scom6_ble.rx_buff, BUFFER_SIZE);
|
||||
}
|
||||
break;
|
||||
|
||||
case TRANS_MODBUS_PC_TO_SIG:
|
||||
{
|
||||
HAL_UART_Receive_DMA(&huart2, scom2_rs485.rx_buff, BUFFER_SIZE);
|
||||
}
|
||||
break;
|
||||
|
||||
case TRANS_MODBUS_SIG_TO_SLAVE:
|
||||
{
|
||||
mod_master.tx_flag = TX_OK;
|
||||
HAL_UART_Receive_DMA(&huart2, scom2_rs485.rx_buff, BUFFER_SIZE);
|
||||
sig2slave_current_tick = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(huart == &huart6)
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -760,6 +760,11 @@
|
|||
<FileType>1</FileType>
|
||||
<FilePath>..\App\MODBUS\Src\modbus_rtu.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>modbus_rtu_master.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\App\MODBUS\Src\modbus_rtu_master.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue