|
|
|
|
/*
|
|
|
|
|
#include <packages/qmodbus/inc/modbus.h>
|
|
|
|
|
#include <packages/qmodbus/inc/modbus.h>
|
|
|
|
|
* Copyright (c) 2006-2021, RT-Thread Development Team
|
|
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
|
*
|
|
|
|
|
* Change Logs:
|
|
|
|
|
* Date Author Notes
|
|
|
|
|
* 2025-10-20 Administrator the first version
|
|
|
|
|
* 2025-11-12 Modified Switch to IDLE interrupt mode (no DMA, no ringbuffer)
|
|
|
|
|
* 2025-11-21 Fixed Enable RX_IDLE mode correctly for RT-Thread 5.1
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "rtthread.h"
|
|
|
|
|
#include "modbus.h"
|
|
|
|
|
#include "SC828_DATA_table.h"
|
|
|
|
|
|
|
|
|
|
#define DBG_TAG "plc.rtu"
|
|
|
|
|
#define DBG_LVL DBG_LOG
|
|
|
|
|
#include <rtdbg.h>
|
|
|
|
|
|
|
|
|
|
static const mb_backend_param_t mb_bkd_prm = {
|
|
|
|
|
.rtu.dev = "uart2", //设备名
|
|
|
|
|
.rtu.baudrate = 57600, //波特率
|
|
|
|
|
.rtu.parity = 0, //校验位, 0-无, 1-奇, 2-偶
|
|
|
|
|
.rtu.pin = -1, //控制引脚, <0 表示不使用
|
|
|
|
|
.rtu.lvl = 0 //控制发送电平
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
extern unsigned char sys_time[6];
|
|
|
|
|
|
|
|
|
|
static void mb_plc_read_regs(mb_inst_t *hinst)
|
|
|
|
|
{
|
|
|
|
|
if (mb_connect(hinst) < 0)//连接失败, 延时返回
|
|
|
|
|
{
|
|
|
|
|
LOG_E("modbus connect fail.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//输入m0000->rtu2000
|
|
|
|
|
uint8_t r_buffer[(DI_TABLE_SIZE + 7) / 8];
|
|
|
|
|
//读取 Modbus bits
|
|
|
|
|
int mrx = mb_read_bits(hinst, 2000, DI_TABLE_SIZE, r_buffer);
|
|
|
|
|
if (mrx > 0)
|
|
|
|
|
{ //解包到数据表
|
|
|
|
|
for (int i = 0; i < DI_TABLE_SIZE; i++) {
|
|
|
|
|
di_table[i].current_state = (r_buffer[i / 8] >> (i % 8)) & 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 输出 m0256 -> RTU 2256
|
|
|
|
|
uint8_t w_buffer[(DO_TABLE_SIZE + 7) / 8]; // 关键:初始化为0
|
|
|
|
|
// 打包 do_table 到 bit_buffer
|
|
|
|
|
for (int i = 0; i < DO_TABLE_SIZE; i++) {
|
|
|
|
|
const int byte_idx = i / 8;
|
|
|
|
|
const int bit_idx = i % 8;
|
|
|
|
|
const uint8_t bit_mask = (1U << bit_idx);
|
|
|
|
|
if (do_table[i].current_state) {
|
|
|
|
|
w_buffer[byte_idx] |= bit_mask;
|
|
|
|
|
} else {
|
|
|
|
|
w_buffer[byte_idx] &= ~bit_mask;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 写入 Modbus
|
|
|
|
|
mb_write_bits(hinst, 2256, DO_TABLE_SIZE, w_buffer);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* u16 regs[64];
|
|
|
|
|
int addr = 7000;
|
|
|
|
|
int nb = 10;
|
|
|
|
|
int total = mb_write_regs(hinst, addr, nb, regs);
|
|
|
|
|
if (total <= 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
u8 regsM[64];
|
|
|
|
|
int addrM = 3000;
|
|
|
|
|
int nbM = 10;
|
|
|
|
|
int totalM = mb_read_bits(hinst, addrM, nbM, regsM);
|
|
|
|
|
if (totalM <= 0)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mb_plc_thread(void *args)//线程服务函数
|
|
|
|
|
{
|
|
|
|
|
mb_inst_t *hinst = mb_create(MB_BACKEND_TYPE_RTU, &mb_bkd_prm);
|
|
|
|
|
RT_ASSERT(hinst != NULL);
|
|
|
|
|
|
|
|
|
|
mb_set_slave(hinst, 1);//修改从机地址, 默认地址为1, 可根据实际情况修改
|
|
|
|
|
mb_set_prot(hinst, MB_PROT_RTU);//修改通信协议类型, RTU后端默认使用MODBUS-RTU通信协议
|
|
|
|
|
mb_set_tmo(hinst, 500, 15);//修改超时时间, 应答超时500ms(默认300ms), 字节超时15ms(默认32ms)
|
|
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
|
{
|
|
|
|
|
mb_plc_read_regs(hinst);
|
|
|
|
|
rt_thread_mdelay(50);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
extern struct rt_memheap sram_DTCMRAM;
|
|
|
|
|
static struct rt_thread dat_plc_thread;
|
|
|
|
|
static void *dat_plc_stack __attribute__((aligned(4)))= RT_NULL ;
|
|
|
|
|
static int mb_rtu_master_startup(void)
|
|
|
|
|
{
|
|
|
|
|
rt_err_t db_err;
|
|
|
|
|
dat_plc_stack = rt_memheap_alloc(&sram_DTCMRAM, 1024*2);
|
|
|
|
|
db_err = rt_thread_init(&dat_plc_thread, "plc_rtu", mb_plc_thread, RT_NULL,dat_plc_stack, 1024*2, 10, 10);
|
|
|
|
|
if(db_err != RT_EOK)
|
|
|
|
|
{
|
|
|
|
|
LOG_D("Failed to create SCCM_uart thread!");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
rt_thread_startup(&dat_plc_thread);
|
|
|
|
|
LOG_I("Create SCCM_uart thread");
|
|
|
|
|
/*rt_thread_t tid = rt_thread_create("plc_rtu", mb_plc_thread, NULL, 2048, 5, 20);
|
|
|
|
|
RT_ASSERT(tid != NULL);
|
|
|
|
|
rt_thread_startup(tid);*/
|
|
|
|
|
return(0);
|
|
|
|
|
}
|
|
|
|
|
INIT_APP_EXPORT(mb_rtu_master_startup);
|