2. 各類Modbus功能接口函數(shù)
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_read_bits(modbus t * ctx,int addr,int nb,uint8_t * dest):
此函數(shù)對(duì)應(yīng)于功能碼01(0x01)讀取線圈/離散量輸出狀態(tài)(Read CoilStatus/DOs),其中,所讀取的值存放于參數(shù)uint8_t * dest指向的數(shù)組空間因此dest指向的空間必須足夠大,其大小至少為nb * sizeof(uint8_t)個(gè)字節(jié)。
用法舉例:
左右滑動(dòng)查看完整內(nèi)容
#define SERVER ID 1 #define ADDRESS START 0 #define ADDRESS END 99 modbus_t * ctx; uint8_t * tab_rp_bits; int rc; int nb; ctx=modbus_new_tcp("127.0.0.1",502); modbus_set_debug(ctx,TRUE); if (modbus_connect(ctx)==-1) { fprintf(stderr,"Connection failed:%s ", modbus_strerror(errno)); modbus free(ctx); return -1; } //申請(qǐng)存儲(chǔ)空間并初始化 int nb = ADDRESS_END - ADDRESS_START; tab_rp_bits = (uint8_t * ) malloc (nb * sizeof(uint8_t)); memset(tab_rp_bits, 0, nb * sizeof(uint8_t)); //讀取一個(gè)線圈 int addr =1; rc =modbus_read_bits(ctx,addr,1,tab_rp_bits); if (rc !=1) { printf("ERROR modbus_read_bits_single (%d) ", rc); printf("address =%d ", addr); } //讀取多個(gè)線圈 rc =modbus_read_bits(ctx,addr,nb,tab_rp_bits); if (rc !=nb) { printf("ERROR modbus_read_bits "); printf("Address =%d,nb =%d ", addr, nb); } //釋放空間關(guān)閉連接 free(tab_rp_bits); modbus_close(ctx); modbus_free(ctx);
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_read_input_bits (modbus_t * ctx, intaddr, int nb,uint8_t * dest):
此函數(shù)對(duì)應(yīng)于功能碼02(0x02)讀取離散量輸入值(Read InputStatus/DIs),各參數(shù)的意義與用法,類似于函數(shù)modbus_read_bits()。
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_read_registers (modbus_t * ctx, intaddr, int nb,uint16_t * dest):
此函數(shù)對(duì)應(yīng)于功能碼03(0x03)讀取保持寄存器(Read HoldingRegister),其中,所讀取的值存放于參數(shù)uint16_t * dest指向的數(shù)組空間,因此dest指向的空間必須足夠大,其大小至少為nb * sizeof(uint16_t)個(gè)字節(jié)。
當(dāng)讀取成功后,返回值為讀取的寄存器個(gè)數(shù);若讀取失敗,則返回-1。此函數(shù)調(diào)用依賴關(guān)系如下圖6-5所示。
用法舉例:
左右滑動(dòng)查看完整內(nèi)容
modbust * ctx; uint16_t tab_reg[64]; int rc; int i; ctx=modbus_new_tcp("127.0.0.1",502); if (modbusconnect(ctx)==-1) { fprintf(stderr,"Connection failed:%s ", modbus_strerror(errno)); modbus_free(ctx); return -1; } //從地址0開始連續(xù)讀取10個(gè) rc =modbus_read_registers(ctx,0,10,tab_reg); if (rc ==-1) { fprintf(stderr,"%s ",modbus_strerror(errno)); return -1; } for (i=0;i
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_read_input_registers (modbus_t * ctx,int addr, int nb, uint16_t * dest ):
此函數(shù)對(duì)應(yīng)于功能碼04(0x04)讀取輸人寄存器(Read Iput Register),各參數(shù)的意義與用法,類似于函數(shù) modbus_read_registers()。
此函數(shù)的調(diào)用依賴關(guān)系如下圖6-6所示。
圖6-6函數(shù)modbus_read input_registers()的調(diào)用依賴關(guān)系:
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_write_bit(modbus_t * ctx,intcoil_addr,int status):
該函數(shù)對(duì)應(yīng)于功能碼05(0x05)寫單個(gè)線圈或單個(gè)離散輸出(ForceSingleCoil)。其中參數(shù)coil_addr代表線圈地址;參數(shù)status代表寫值取值只能是TRUE(1)或 FALSE(0)。
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_write_register(modbus_t * ctx,intreg_addr,int value):
該函數(shù)對(duì)應(yīng)于功能碼06(0x06)寫單個(gè)保持寄存器(Preset SingleRegister)。
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_write_bits(modbus_t * ctx, int addr,int nb,const uint8_t * data):
該函數(shù)對(duì)應(yīng)于功能碼15(0x0F)寫多個(gè)線圈(Force Multiple Coils)
參數(shù)addr代表寄存器起始地址,參數(shù)nb表示線圈個(gè)數(shù),而參數(shù)constuint8_t * data表示待寫入的數(shù)據(jù)塊。一般情況下,可以使用數(shù)組存儲(chǔ)寫入數(shù)據(jù),數(shù)組的各元素取值范圍只能是TRUE(1)或FALSE(0)。
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_write_registers(modbus_t * ctx, intaddr,int nb,const uint16_t * data):
該函數(shù)對(duì)應(yīng)于功能碼16(0x10)寫多個(gè)保持存器 (PresetMultipleRegisters)
參數(shù)addr代表寄存器起始地址,參數(shù)nb表示存器的個(gè)數(shù)而參數(shù)constuint16_t * data表示待寫人的數(shù)據(jù)塊。一般情況下,可以使用數(shù)組存儲(chǔ)寫入數(shù)據(jù)數(shù)組的各元素取值范圍是0~0xFFFF即數(shù)據(jù)類型uint16_t的取值范圍。
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_mask_registers(modbus_t * ctx, intaddr, uint16_t and_mask,uint16_t or_mask ):
modbus_mask_write_register()函數(shù)應(yīng)使用以下算法修改遠(yuǎn)程設(shè)備地址“addr”處的保持寄存器的值:
新值=(current value AND ‘a(chǎn)nd’)OR(‘or’ AND(NOT ‘a(chǎn)nd’))。
該功能使用Modbus功能代碼0x16(掩碼單個(gè)寄存器)。
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_write_and_read_registers (mobus_t *ctx , int writer_addr, int writer_nb, const uint16_t * src, int read_addr, int read_nb, uint16_t * dest);
modbus_write_and_read_registers()函數(shù)應(yīng)將write_nb保持寄存器的內(nèi)容從數(shù)組“src”寫入遠(yuǎn)程設(shè)備的地址 write_addr,然后將read_nb保持寄存器的內(nèi)容讀取到遠(yuǎn)程設(shè)備的地址read_addr。讀取結(jié)果作為字值(16位)存儲(chǔ)在dest數(shù)組中。
必須注意分配足夠的內(nèi)存來存儲(chǔ)結(jié)果dest(至少nb *sizeof(uint16_t))。該功能使用Modbus功能代碼0x17(寫/讀寄存器)。
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API int modbus_report_slave_id(modbus_t * ctx, intmax_dest, uint8_t * dest):
該函數(shù)對(duì)應(yīng)于功能碼17(0x11)報(bào)告從站ID。參數(shù)max_dest代表最大的存儲(chǔ)空間,參數(shù)dest用于存儲(chǔ)返回?cái)?shù)據(jù)。返回?cái)?shù)據(jù)可以包括如下內(nèi)容:從站ID狀態(tài)值(0x00=OFF狀態(tài),0xFF=ON狀態(tài))以及其他附加信息,具體的各參數(shù)意義由開發(fā)者指定。
用法舉例:
左右滑動(dòng)查看完整內(nèi)容
uint8_t tab_bytes[MODBUS_MAX_PDU_LENGTH]; ... rc =modbus_report_slave_id(ctx, MODBUS_MAX_PDU_LENGTH, tab_bytes); if (rc>1) { printf("Run Status Indicator: %s ",tab_bytes[1] ?"ON":"OFF"); }
3.數(shù)據(jù)處理的相關(guān)函數(shù)或宏定義
在libmodbus開發(fā)庫中,為了方便數(shù)據(jù)處理在modbus.h 文件中定義了一系列數(shù)據(jù)處理宏。
例如獲取數(shù)據(jù)的高低字節(jié)序宏定義:
左右滑動(dòng)查看完整內(nèi)容
#define MODBUS_GET_HIGH_BYTE (data) (((data) >>8)&0xFF)
左右滑動(dòng)查看完整內(nèi)容
#define MODBUS_GET_LOW_BYTE (data) ((data)&0xFF)
對(duì)于浮點(diǎn)數(shù)等多字節(jié)數(shù)據(jù)而言,由于存在字節(jié)序與大小端處理等的問題,所以輔助定義了一些特殊函數(shù):
左右滑動(dòng)查看完整內(nèi)容
MODBUS_API float modbus_get_float (const uint16_t * src); MODBUS_API float modbus_get_float_abcd (const uint16_t * src); MODBUS_API float modbus_get_float_dcba (const uint16_t * src); MODBUS_API float modbus_get_float_badc (const uint16_t * src); MODBUS_API float modbus_get_float_cdab (const uint16_t * src); MODBUS_API void modbus_set_float (float f,uint16_t * dest); MODBUS_API void modbus_set_float_abcd (float f,uint16_t * dest); MODBUS_API void modbus_set_float_dcba (float f,uint16_t * dest); MODBUS_API void modbus_set_float_badc (float f,uint16_t * dest); MODBUS_API void modbus_set_float_cdab (float f,uint16_t * dest);
當(dāng)然,可以參照float類型的處理方法,繼續(xù)定義其他多字節(jié)類型的數(shù)據(jù)例如int32_t、uint32_t、int64_t、uint64_t以及double類型的讀寫函數(shù)。
-
接口
+關(guān)注
關(guān)注
33文章
8575瀏覽量
151014 -
MODBUS
+關(guān)注
關(guān)注
28文章
1799瀏覽量
76947 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62569
原文標(biāo)題:Modbus接口與數(shù)據(jù)處理 - RZ MPU工業(yè)控制教程連載(41)
文章出處:【微信號(hào):瑞薩MCU小百科,微信公眾號(hào):瑞薩MCU小百科】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論