G-CAMS-DATU/applications/Modbus/modbus_rtu.c

371 lines
9.2 KiB
C
Raw Normal View History

2024-05-13 08:08:47 +00:00
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-04-23 lijian the first version
*/
#include "modbus_rtu.h"
#include <board.h>
Modbus_RTU_t Modbus_RTU;
/**
* modbus从机地址
* @param modbus_addr
*/
void set_Modbus_Addr(rt_uint16_t modbus_addr)
{
Modbus_RTU.modbus_addr = modbus_addr;
}
/**
* @brief Modbus从机地址
* @return rt_uint16
*/
rt_uint16_t get_Modbus_Addr()
{
return Modbus_RTU.modbus_addr;
}
/**
* modbus寄存器地址
* @param modbus_reg_addr
*/
void set_Modbus_Reg_Addr(rt_uint16_t modbus_reg_addr)
{
Modbus_RTU.modbus_reg_addr = modbus_reg_addr;
}
/**
* @brief Modbus读取寄存器起始地址
* @return rt_uint16
*/
rt_uint16_t get_Modbus_Reg_Addr()
{
return Modbus_RTU.modbus_reg_addr;
}
/**
* @brief Modbus读寄存器数量
* @return rt_uint16
*/
void set_Modbus_Reg_Num(rt_uint16_t modbus_reg_num)
{
Modbus_RTU.modbus_reg_num = modbus_reg_num;
}
/**
* @brief Modbus读寄存器数量
* @return rt_uint16
*/
rt_uint16_t get_Modbus_Reg_Num()
{
return Modbus_RTU.modbus_reg_num;
}
//功能码010x01: 读线圈状态Read Coils
//功能码020x02: 读离散输入状态Read Discrete Inputs
//功能码030x03: 读保持寄存器Read Holding Registers
//功能码040x04: 读输入寄存器Read Input Registers
//功能码050x05: 写单个线圈Write Single Coil
//功能码060x06: 写单个保持寄存器Write Single Holding Register
//功能码150x0F: 写多个线圈Write Multiple Coils
//功能码160x10: 写多个保持寄存器Write Multiple Holding Registers
/**
* modbus初始化
*/
void Modbus_init()
{
// Modbus_RTU.modbus_addr = (rt_uint16_t)0x01;
// Modbus_RTU.modbus_reg_addr = (rt_uint16_t)0x00;
// Modbus_RTU.modbus_reg_num = (rt_uint16_t)0x02;
rs485_inst_t *hinst = rs485_create(RS485_SAMPLE_MASTER_SERIAL, RS485_SAMPLE_MASTER_BAUDRATE,
RS485_SAMPLE_MASTER_PARITY, RS485_SAMPLE_MASTER_PIN, RS485_SAMPLE_MASTER_LVL);
if (hinst == RT_NULL)
{
rt_kprintf("create rs485 instance fail.\n");
return;
}
rs485_set_recv_tmo(hinst, 1000);
if (rs485_connect(hinst) != RT_EOK)
{
rs485_destory(hinst);
rt_kprintf("rs485 connect fail.\n");
return;
}
rt_uint8_t ctx_send_buf[AGILE_MODBUS_MAX_ADU_LENGTH];
rt_uint8_t ctx_read_buf[AGILE_MODBUS_MAX_ADU_LENGTH];
agile_modbus_rtu_t ctx_rtu;
agile_modbus_t *ctx = &ctx_rtu._ctx;
agile_modbus_rtu_init(&ctx_rtu, ctx_send_buf, sizeof(ctx_send_buf), ctx_read_buf, sizeof(ctx_read_buf));
agile_modbus_set_slave(ctx, Modbus_RTU.modbus_addr); //地址
rt_kprintf("Modbus Running.\n");
rt_int8_t send_len;
rt_int8_t read_len;
rt_uint8_t i;
rt_int8_t rc;
//
while (1)
{
rt_thread_mdelay(1000);
//if(Modbus_RTU.modbus_func == 3){
send_len = agile_modbus_serialize_read_registers(ctx, Modbus_RTU.modbus_reg_addr, Modbus_RTU.modbus_reg_num);
//
// } else if(Modbus_RTU.modbus_func == 1){
// send_len = agile_modbus_serialize_read_bits(ctx, Modbus_RTU.modbus_reg_addr, Modbus_RTU.modbus_reg_num);
//
// }
// rt_kprintf("rs485 send %d datas : ", send_len);
// for (i = 0; i < send_len; i++) {
// rt_kprintf("%02X ", ctx->send_buf[i]);
// }
// rt_kprintf("\n");
read_len = rs485_send_then_recv(hinst, (void *) ctx->send_buf, send_len, ctx->read_buf, ctx->read_bufsz);
if (read_len < 0)
{
// rt_kprintf("rs485 send datas error.\n");
break;
}
if (read_len == 0)
{
// rt_kprintf("rs485 recv timeout.\n");
continue;
}
ctx->read_buf[read_len] = 0;
// Bsp_Rs485_Tx(ctx->send_buf, send_len); //
// int read_len = Bsp_Rs485_Rx(ctx->read_buf, ctx->read_bufsz); //
if (read_len == 0)
{
// rt_kprintf("Receive timeout.\n");
continue;
}
rc = agile_modbus_deserialize_read_registers(ctx, read_len, Modbus_RTU.hold_register);
if (rc < 0)
{
Modbus_RTU.modbus_rec = 0;
rt_kprintf("Receive failed.\n");
if (rc != -1)
rt_kprintf("Error code:%d\n", -128 - rc);
continue;
}
Modbus_RTU.modbus_rec = 1;
if (Modbus_RTU.log) {
rt_kprintf("Hold Registers:");
for (i = 0; i < 10; i++)
rt_kprintf("Register [%d]: 0x%04X\n", i, Modbus_RTU.hold_register[i]);
}
if (Modbus_RTU.modbus_rec) {
//get_modbus_rec();
// MQTT_Send_Modbus(get_modbus_rec());
}
rt_kprintf("\r\n\r\n\r\n");
}
}
void set_modbus_log(rt_uint8_t log){
Modbus_RTU.log = log;
}
/**
* modbus读取数据的转换后返回值
* @return
*/
rt_uint16_t get_modbus_rec(){
if (Modbus_RTU.modbus_rec) {
rt_uint8_t high_d=0;
rt_uint8_t low_d=0;
if (Modbus_RTU.modbus_reg_num == 2) {
high_d = Modbus_RTU.hold_register[0];
low_d = Modbus_RTU.hold_register[1];
rt_uint16_t rec = (high_d << 8) | low_d;
return rec;
}
Modbus_RTU.modbus_rec =0;
}
return 0;
}
//void Bsp_Rs485_Tx(){
//
//}
//
//void Bsp_Rs485_Rx(){
//
//}
//
//static void rs485_sample_master(void *args)
//{
// const char read_cmd[] = "read datas test\r\n";
// static rt_uint8_t buf[256];
// rs485_inst_t *hinst = rs485_create(RS485_SAMPLE_MASTER_SERIAL, RS485_SAMPLE_MASTER_BAUDRATE,
// RS485_SAMPLE_MASTER_PARITY, RS485_SAMPLE_MASTER_PIN, RS485_SAMPLE_MASTER_LVL);
//
// if (hinst == RT_NULL)
// {
// LOG_E("create rs485 instance fail.");
// return;
// }
//
// rs485_set_recv_tmo(hinst, 1000);
// if (rs485_connect(hinst) != RT_EOK)
// {
// rs485_destory(hinst);
// LOG_E("rs485 connect fail.");
// return;
// }
//
// while (1)
// {
// int len = strlen(read_cmd);
// len = rs485_send_then_recv(hinst, (void *) read_cmd, len, buf, sizeof(buf));
// if (len < 0)
// {
// LOG_E("rs485 send datas error.");
// break;
// }
//
// if (len == 0)
// {
// LOG_D("rs485 recv timeout.");
// continue;
// }
//
// buf[len] = 0;
// LOG_D("rs485 recv %d datas : %s", len, buf);
// }
//
//}
//
//#define PORT_NUM MB_MASTER_USING_PORT_NUM
//#define PORT_BAUDRATE MB_MASTER_USING_PORT_BAUDRATE
//
//#define PORT_PARITY MB_PAR_EVEN
//
//#define MB_POLL_CYCLE_MS 500
//
//#define func_Coil 1
//#define func_Holding 3
//
//#define MODBUS_REG_NUM 30
//rt_uint16_t buffer[MODBUS_REG_NUM];
//
///*
// *
// *
// */
//
//void Copy_Holding(rt_uint16_t * Holding, rt_uint16_t reg_num){
// rt_uint16_t * a = get_modbus_03();
// for (rt_uint8_t var = 0; var < reg_num; var++) {
// Holding[var] = a[var];
// }
//}
//
//void Copy_Coil(rt_uint16_t * Coil, rt_uint16_t reg_num){
// unsigned char * a = get_modbus_01();
// for (rt_uint8_t var = 0; var < reg_num; var++) {
// Coil[var] = a[var];
// }
//}
//
//
//
//void Modbus_Read_Holding_Registers(rt_uint16_t addr, rt_uint16_t reg_addr, rt_uint16_t reg_num, rt_uint16_t * Holding){
//
// while(1){
// eMBMasterPoll();
//
// /*
// * ucSndAddr 请求的从机地址0代表广播。
// usRegAddr 读寄存器的地址
// usRegData 读寄存器的数量
// lTimeOut 请求超时时间。支持永久等待,使用操作系统的永久等待参数即可。
// */
// eMBMasterReqReadHoldingRegister(addr, reg_addr, reg_num, 1000);
//
// rt_thread_mdelay(MB_POLL_CYCLE_MS);
//
// if (get_Holding_flag()) {
// Copy_Holding(Holding, reg_num);
// Modbus_RTU.modbus_rec =1;
// get_modbus_rec();
// }
//
// }
//}
//
//void Modbus_Read_Coils(rt_uint16_t addr, rt_uint16_t reg_addr, rt_uint16_t reg_num, rt_uint16_t * Coil){
//
// while(1){
// eMBMasterPoll();
//
// /*
// * ucSndAddr 请求的从机地址0代表广播。
// usCoilAddr 读线圈的地址
// usNCoils 读线圈的数量
// lTimeOut 请求超时时间。支持永久等待,使用操作系统的永久等待参数即可
// */
// eMBMasterReqReadCoils(addr, reg_addr, reg_num, 1000);
//
// rt_thread_mdelay(MB_POLL_CYCLE_MS);
// if (get_Coil_flag()) {
// Copy_Coil(Coil , reg_num);
// Modbus_RTU.modbus_rec =1;
// }
// }
//}
//
//
//void Modbus_config(void){
//
// eMBMasterInit(MB_RTU, PORT_NUM, PORT_BAUDRATE, PORT_PARITY);
// eMBMasterEnable();
//
//// if(Modbus_RTU.modbus_func == func_Holding){
// Modbus_Read_Holding_Registers(Modbus_RTU.modbus_addr, Modbus_RTU.modbus_reg_addr, Modbus_RTU.modbus_reg_num ,buffer);
//// } else if(Modbus_RTU.modbus_func == func_Coil){
//// Modbus_Read_Coils(Modbus_RTU.modbus_addr, Modbus_RTU.modbus_reg_addr, Modbus_RTU.modbus_reg_num , buffer);
//// }
//
//}
//