玩转Libmodbus(二) 写代码体验

libmodbus在线文档

 https://www.jianshu.com/p/d93c17485c0a

原创篇

参考上一篇转载的博客,我的ubuntu上的最终生成的动态库的路径,下图所示

我的linux板子上( 权限最好 777):

我的ubuntu主机上的C语言源代码的路径,四个头文件modbus.h、modbus-rtu.h、modbus-tcp.h、modbus-version.h也都放在了这里

 我的C源代码:

/*************************
**
** modbus-rtu-test.c 
** 移植libmodbus库到ARM开发板,并测试成功
**
**************************/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include "modbus.h"  //modbus动态库文件
 
unsigned char log[6] = {0x11,0x12,0x13,0x14,0x15,0x16}; 
#define Path_dat "/root/Test_Data_Dir/record.dat"
 
#define Path_log1 "/root/Test_Data_Dir/log1.dat"
#define Path_log2 "/root/Test_Data_Dir/log2.dat"
#define Path_log3 "/root/Test_Data_Dir/log3.dat"
#define Path_log4 "/root/Test_Data_Dir/log4.dat"

/*
int read_data_hex(unsigned char *buf, int length, char *string)
{
    FILE *fp;
    fp = fopen(string, "rb");
    if (NULL == fp)
    {
        // printf("read: file open Fail!\n");
        return -1;
    }
    fread(buf, sizeof(unsigned char), length, fp);

    fclose(fp);
    fp = NULL;
    return 0;
} 
*/
 
int write_data_hex(unsigned char *my_array, int length, char *string)
{
    int i = 0;
    FILE *fp;
    fp = fopen(string, "wb+"); // b 二进制操作
    if (NULL == fp)
    {
        // printf("write: file open Fail!\n");
        return -1;
    }
    while (i < length)
    {
        fwrite(&my_array[i], sizeof(unsigned char), 1, fp);
        i++;
    }

    fclose(fp);
    fp = NULL;
    return 0;
} 
 
 
//如果手边只有一根USB转串口线,那么只能连接板子的modbus串口和PC机,就不能
//连接PC机和板子的串口调试口了。如何调试?使用write_data_hex()写log观察过程。

int main(int argc, char *argv[])
{
    struct timeval t;
    uint16_t tab_reg[64] = {0}; //定义存放数据的数组
    modbus_t *ctx = NULL;
 
    int rc;
    int i;
                //以串口的方式创建libmodbus实例,并设置参数
                //ttySAC0         /dev/ttyS1            
    ctx = modbus_new_rtu("/dev/ttySAC0", 115200, 'N', 8, 1);                    
    if (ctx == NULL)               
    {
        fprintf(stderr, "Unable to allocate libmodbus contex\n");
        return -1;
    }
    
    printf("MY_Debug: usleep begin! \n");
    
    //这里我给了40秒延时,在这个时间内:你把串口线从板子的串口调试口转为
    //连接到板子的modbus串口,打开一个事先设置好串口参数的PC机上的模拟modbus从机的软件
    //(我使用的是和modsim32)
    //注意:如果前后接的是同一个电脑com口,注意还要把之前的串口调试口对应的上位机软件
    //      关闭一下,以便modsim32能够顺利打开该com口。
    usleep(40000000); 
    
    modbus_set_debug(ctx, 0);      //设置1可看到调试信息
    modbus_set_slave(ctx, 1);      //设置slave ID
    
    t.tv_sec = 0;
    t.tv_usec = 50000;
    // 50ms超时时间,下位机回复帧的限制时间:主机发完后,下位机需要在50ms内回应
    //   *** 必须设置从站的响应超时 小于 主站的响应超时 *** 
    //   总之,在确保速度满足你所需应用的情况下,把主站的响应超时适当设置大一点,是保险措施
    modbus_set_response_timeout(ctx,&t); 
    

    if (modbus_connect(ctx) == -1) //连接设备
     {
        write_data_hex(&log[0], 1, Path_log1);
        printf("MY_Debug: modbus_connect Fail! \n");
        fprintf(stderr, "Connection failed:%s\n", modbus_strerror(errno));
        
        modbus_close(ctx);  //关闭modbus连接
        modbus_free(ctx);   //释放modbus资源,libmodbus需要释放掉
     }
    else{
        printf("MY_Debug: modbus_connect Success! \n");
    }
    
    
    while (1)
    {
        printf("\n 这里的代码只执行一次 return -1,或者 break \n");
        
        rc = modbus_read_registers(ctx, 0, 10, tab_reg);
        if (rc == -1)    //读取保持寄存器的值,可读取多个连续输入保持寄存器
        {
            write_data_hex(&log[1], 1, Path_log2);
            fprintf(stderr,"%s\n", modbus_strerror(errno));
            printf("MY_Debug: modbus_read_registers Fail! \n");
            return -1;
        }
        
        // 这里保存为文件,如果你只有一根串口线,方便你观察结果。
        write_data_hex(&log[2], 1, Path_log3);
        
        write_data_hex(tab_reg, 10, Path_dat);
        
        for (i=0; i<10; i++)
        {
            printf("reg[%d] = %d(0x%x)\n", i, tab_reg[i], tab_reg[i]);
        }
        
        break;
    }
    
    write_data_hex(&log[3], 1, Path_log4);    //标记代码已顺利结束
    modbus_close(ctx);  //关闭modbus连接
    modbus_free(ctx);   //释放modbus资源,使用完libmodbus需要释放掉
 
    return 0;
}

我的makefile:

CC = arm-none-linux-gnueabi-gcc

#CFLAGS    += -I../include -std=gnu99 -lm -lpthread -O3 -lstdc++

LIBS    += -L /home/aston/LibModbus_Study/installHere/lib -lmodbus

TARGET=main.out

SRCS =     Lib_Modbus_test.c 

OBJS = $(SRCS:.c=.o)

$(TARGET):$(OBJS)
    $(CC) $(LDFLAGS) $^ -o $@ $(LIBS)    

clean:
    rm -rf $(TARGET) $(OBJS)


    
    

我使用到的工具软件: ModSim32 

D:\Study_2019\LibModbus\使用到的工具软件\ModSim32 v1.A00-04

软件使用介绍:

先点击New, 就可以出现‘’2’的界面,并配置好参数,以便后面使用

待linux板子上的程序跑起来以后,用USB转串口线连接好板子的MODBUS串口和PC机的USB口,再点击下图所示的‘3’的Connect

代码中读取到的寄存器的值展示:

实验成功。注意,modbus一个寄存器占两个字节。大小端有区分。

猜你喜欢

转载自www.cnblogs.com/happybirthdaytoyou/p/11301863.html
今日推荐