玩轉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一個寄存器占兩個字節。大小端有區分。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM