G-CAMS-DATU/applications/Modbus/modbus_rtu.c
2024-05-13 16:08:47 +08:00

371 lines
9.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* 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);
//// }
//
//}
//