parent
af6d6fd969
commit
f92b4a15f7
|
@ -116,7 +116,7 @@ typedef struct
|
||||||
uint8_t bluetooth_enable; //蓝牙透传使能
|
uint8_t bluetooth_enable; //蓝牙透传使能
|
||||||
uint8_t modbus_enable; //MODBUS使能
|
uint8_t modbus_enable; //MODBUS使能
|
||||||
SIG_MODBUS_TYPE modbus_type; //SIG在modbus中作为主或从
|
SIG_MODBUS_TYPE modbus_type; //SIG在modbus中作为主或从
|
||||||
uint16_t modbus_timeout_period; //SIG作为主设备时,等待从设备响应的超时时间上限(ms)
|
uint8_t modbus_master_send_flag; //发送标志
|
||||||
|
|
||||||
//ITEMS_3
|
//ITEMS_3
|
||||||
uint8_t item3_page0_lightflag; //照明状态标志,0熄灭,1开启
|
uint8_t item3_page0_lightflag; //照明状态标志,0熄灭,1开启
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "SIG24130.h"
|
#include "SIG24130.h"
|
||||||
#include "modbus_485.h"
|
#include "modbus_485.h"
|
||||||
#include "modbus_rtu.h"
|
#include "modbus_rtu.h"
|
||||||
|
#include "modbus_rtu_master.h"
|
||||||
|
|
||||||
extern osThreadId task_lcdHandle;
|
extern osThreadId task_lcdHandle;
|
||||||
extern osThreadId task_menuHandle;
|
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)
|
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(); //不做延时,尽快响应
|
sig_sv_update(); //不做延时,尽快响应
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ void tab_data_init(void)
|
||||||
tabdata.bluetooth_enable = 0; //HART默认使能状态
|
tabdata.bluetooth_enable = 0; //HART默认使能状态
|
||||||
tabdata.modbus_enable = 0; //HART默认使能状态
|
tabdata.modbus_enable = 0; //HART默认使能状态
|
||||||
tabdata.modbus_type = SIG_SLAVE; //SIG默认作为从设备
|
tabdata.modbus_type = SIG_SLAVE; //SIG默认作为从设备
|
||||||
tabdata.modbus_timeout_period = 1000; //默认超时时间为1000ms
|
tabdata.modbus_master_send_flag = 0; //触发发送后置1,发送完成后置0
|
||||||
|
|
||||||
//ITEMS_3(部分内容位于EERPOM读取)
|
//ITEMS_3(部分内容位于EERPOM读取)
|
||||||
tabdata.item3_page0_lightflag = 0; //照明状态标志,0熄灭,1开启
|
tabdata.item3_page0_lightflag = 0; //照明状态标志,0熄灭,1开启
|
||||||
|
@ -592,6 +592,14 @@ void scr_setting_run(void) //详细设置界面
|
||||||
|
|
||||||
//处理复位事件
|
//处理复位事件
|
||||||
deal_data_reset();
|
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
|
// lv_demo_benchmark(); //lv_conf.h, line:761
|
||||||
setup_ui(&guider_ui); // 初始化UI,设置与加载初始界面
|
setup_ui(&guider_ui); // 初始化UI,设置与加载初始界面
|
||||||
events_init(&guider_ui); // 初始化事件
|
events_init(&guider_ui); // 初始化事件
|
||||||
|
|
||||||
|
//MODBUS主站初始化
|
||||||
|
modbus_rtu_master_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -65,11 +65,19 @@ void duty_tim6(void)
|
||||||
input_500ms_flag = 1;
|
input_500ms_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sig2slave_step == 1)
|
//发送完成 或者 已经接收到一部分数据之后开始计时
|
||||||
|
if( (sig2slave_step == 1)||(mod_master.tx_flag == TX_OK) )
|
||||||
{
|
{
|
||||||
sig2slave_current_tick++;
|
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_DMAStop(&huart2);
|
||||||
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
|
__HAL_UART_CLEAR_IDLEFLAG(&huart2);
|
||||||
|
|
||||||
|
|
|
@ -14,18 +14,13 @@ typedef enum
|
||||||
extern uint32_t tick_start;
|
extern uint32_t tick_start;
|
||||||
extern uint32_t tick_middle;
|
extern uint32_t tick_middle;
|
||||||
extern uint32_t tick_end;
|
extern uint32_t tick_end;
|
||||||
extern uint32_t trans_log_rx;
|
//extern uint32_t trans_log_rx;
|
||||||
extern uint32_t trans_log_tx;
|
extern uint32_t trans_log_tx;
|
||||||
extern uint8_t sig2slave_step;
|
extern uint8_t sig2slave_step;
|
||||||
extern TRANS_PROCESS st_flag;
|
extern TRANS_PROCESS st_flag;
|
||||||
|
|
||||||
void parse_scom_485(st_scom *scom);
|
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发送,与发送回调组合使用
|
//透传,DMA发送,与发送回调组合使用
|
||||||
void transparent_tim(void);
|
void transparent_tim(void);
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,10 @@
|
||||||
#define ReadDisInputState 0x02 //读取输入状态
|
#define ReadDisInputState 0x02 //读取输入状态
|
||||||
#define ReadHoldReg 0x03 //读取保持寄存器
|
#define ReadHoldReg 0x03 //读取保持寄存器
|
||||||
#define ReadInputReg 0x04 //读取输入寄存器
|
#define ReadInputReg 0x04 //读取输入寄存器
|
||||||
#define WriteSingleCoil 0x05 //强制写单线圈输出状态
|
#define WriteSingleCoil 0x05 //写单个线圈寄存器
|
||||||
#define WriteSingleReg 0x06 //预设(写)单寄存器
|
#define WriteSingleReg 0x06 //写单个保持寄存器
|
||||||
#define WriteMultiCoil 0x0F //强制写多线圈输出状态
|
#define WriteMultiCoil 0x0F //写多个线圈寄存器
|
||||||
#define WriteMultiReg 0x10 //预设(写)多寄存器
|
#define WriteMultiReg 0x10 //写多个保持寄存器
|
||||||
|
|
||||||
#define COIL_ADD_MIN 0x00
|
#define COIL_ADD_MIN 0x00
|
||||||
#define COIL_ADD_MAX 0x64
|
#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 InputReg[MAX_INPUT_REG_NUM];
|
||||||
extern uint16_t HoldReg[MAX_HOLD_REG_NUM];
|
extern uint16_t HoldReg[MAX_HOLD_REG_NUM];
|
||||||
extern Var_Reg SamVarReg;
|
extern Var_Reg SamVarReg;
|
||||||
|
extern eMBException ex_message;
|
||||||
|
|
||||||
//MODBUS_RTU
|
//MODBUS_RTU
|
||||||
void modbus_analysis_rtu(uint8_t * upRxdbuf, uint16_t wRxdLen);
|
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_start = 0;
|
||||||
uint32_t tick_middle = 0;
|
uint32_t tick_middle = 0;
|
||||||
uint32_t tick_end = 0;
|
uint32_t tick_end = 0;
|
||||||
uint32_t trans_log_rx = 0;
|
//uint32_t trans_log_rx = 0;
|
||||||
uint32_t trans_log_tx = 0;
|
uint32_t trans_log_tx = 0;
|
||||||
TRANS_PROCESS st_flag = TRANSPARENT_WAIT;
|
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)
|
void parse_scom_485(st_scom *scom)
|
||||||
{
|
{
|
||||||
|
@ -24,89 +15,13 @@ void parse_scom_485(st_scom *scom)
|
||||||
scom->rx_flag = FALSE;
|
scom->rx_flag = FALSE;
|
||||||
if ((scom->rx_buff[0] == 0xff) && (scom->rx_buff[1] == 0xff) && (scom->rx_buff[scom->rx_len - 1] == 0xaa))
|
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);
|
vTaskDelay(10);
|
||||||
HAL_UART_Transmit(&huart2, scom->rx_buff, scom->rx_len, 0xFFFF);
|
HAL_UART_Transmit(&huart2, scom->rx_buff, scom->rx_len, 0xFFFF);
|
||||||
//RS485_RW(RS485_RD);
|
|
||||||
}
|
}
|
||||||
scom->rx_len = 0;
|
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)
|
void transparent_tim(void)
|
||||||
{
|
{
|
||||||
switch (sig_trans)
|
switch (sig_trans)
|
||||||
|
@ -306,7 +221,9 @@ void trans_modbus_sig2slave(void)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
//进入此处说明已经接收完成一部分数据,开始超时计时
|
//进入此处说明已经接收完成一部分数据,重新开始超时计时,发送标志复位
|
||||||
|
mod_master.tx_flag = TX_NONE;
|
||||||
|
sig2slave_current_tick = 0;
|
||||||
|
|
||||||
//记录第一次接收到的数据长度
|
//记录第一次接收到的数据长度
|
||||||
sig2slave_data_length_total = scom2_rs485.rx_len;
|
sig2slave_data_length_total = scom2_rs485.rx_len;
|
||||||
|
@ -342,9 +259,18 @@ void trans_modbus_sig2slave(void)
|
||||||
|
|
||||||
case 2:
|
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;
|
sig2slave_step = 0;
|
||||||
sig_trans = TRANS_NONE;
|
sig_trans = TRANS_NONE;
|
||||||
memset(scom2_rs485.rx_buff, 0, scom2_rs485.rx_len);
|
memset(scom2_rs485.rx_buff, 0, scom2_rs485.rx_len);
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
uint8_t CoilState[(MAX_COIL_NUM + 7) / 8] = {0x00,0x00,0x00,0x00,0x00}; //线圈寄存器
|
uint8_t CoilState[(MAX_COIL_NUM + 7) / 8] = {0x00,0x00,0x00,0x00,0x00}; //线圈寄存器
|
||||||
uint8_t DisState[(MAX_DIS_NUM + 7) / 8] = {0x00,0x00,0x00,0x00,0x00,0x00}; //离散量寄存器
|
uint8_t DisState[(MAX_DIS_NUM + 7) / 8] = {0x00,0x00,0x00,0x00,0x00,0x00}; //离散量寄存器
|
||||||
uint16_t InputReg[MAX_INPUT_REG_NUM] = {0x0000,0x0000,0x0000,0x0000}; //输入寄存器
|
uint16_t InputReg[MAX_INPUT_REG_NUM] = {0x0000,0x0000,0x0000,0x0000}; //输入寄存器
|
||||||
uint16_t HoldReg[MAX_HOLD_REG_NUM] = {0, 0,0,0x00C8}; //保持寄存器
|
uint16_t HoldReg[MAX_HOLD_REG_NUM] = {0, 0,0,0x00C8}; //保持寄存器
|
||||||
|
|
||||||
Var_Reg SamVarReg;
|
Var_Reg SamVarReg;
|
||||||
|
eMBException ex_message = MB_EX_NONE; //从设备返回的异常信息
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
函数名称 : Modbus_Analysis
|
函数名称 : 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 RX_DMA_ENABLE 1
|
||||||
|
|
||||||
#define BUFFER_SIZE 255
|
#define BUFFER_SIZE 128
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
|
@ -465,9 +465,37 @@ void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||||
scom2_rs485.tx_len = 0;
|
scom2_rs485.tx_len = 0;
|
||||||
|
|
||||||
//开启对应的DMA
|
//开启对应的DMA
|
||||||
if(sig_trans == TRANS_HART_TO_PC) HAL_UART_Receive_DMA(&huart1, scom1_hart.rx_buff, BUFFER_SIZE);
|
switch (sig_trans)
|
||||||
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);
|
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)
|
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>
|
<FileType>1</FileType>
|
||||||
<FilePath>..\App\MODBUS\Src\modbus_rtu.c</FilePath>
|
<FilePath>..\App\MODBUS\Src\modbus_rtu.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>modbus_rtu_master.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\App\MODBUS\Src\modbus_rtu_master.c</FilePath>
|
||||||
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue