1. 程式人生 > >EasyARM i.mx287學習筆記——通過modbus tcp控制GPIO

EasyARM i.mx287學習筆記——通過modbus tcp控制GPIO

0 前言    本文使用freemodbus協議棧,在EasyARM i.mx287上實現了modbus tcp從機。在該從機中定義了線圈暫存器,其中線圈暫存器地址較低的4位和EasyARM的P2.4至P2.5關聯,通過modbus指令可控制GPIO的輸出。本文修改自freemodbus 示例LINUXTCP,經過簡單的修改也可用於其他Linux開發板。    【相關博文】    【程式碼倉庫】    程式碼倉庫位於bitbucket——easyarm-modbus-tcp,請使用Hg克隆或者直接下載zip包。請不要使用任何版本的IE瀏覽器訪問連結,除非你已經知道所使用的IE瀏覽器符合HTML5標準。推薦使用谷歌或者火狐瀏覽器訪問,若使用國產雙核瀏覽器請切換到極速模式。 1 部分程式碼
    【gpio-sysfs】    在gpio-sysfs中增加使能GPIO、禁止GPIO和GPIO定期處理函式。其中gpio_poll傳入的引數為modbus線圈暫存器
int gpio_enable(void)
{
    gpio_export(P24);gpio_direction(P24,OUT);gpio_write(P24,0);
    gpio_export(P25);gpio_direction(P25,OUT);gpio_write(P25,0);
    gpio_export(P26);gpio_direction(P26,OUT);gpio_write(P26,0);
    gpio_export(P27);gpio_direction(P27,OUT);gpio_write(P27,0);
    return 0;
}

int gpio_disable(void)
{
    gpio_write(P24,0);gpio_unexport(P24);
    gpio_write(P25,0);gpio_unexport(P25);
    gpio_write(P26,0);gpio_unexport(P26);
    gpio_write(P27,0);gpio_unexport(P27);
    return 0;
}
int gpio_poll(unsigned char status)
{
    status & 0x01 ? gpio_write(P24,1) : gpio_write(P24,0);
    status & 0x02 ? gpio_write(P25,1) : gpio_write(P25,0);
    status & 0x04 ? gpio_write(P26,1) : gpio_write(P26,0);
    status & 0x08 ? gpio_write(P27,1) : gpio_write(P27,0);
    return 0;
}
    【modbus poll】    pvPollingThread執行緒中獲得線圈暫存器結果——ucRegCoilsBuf[0],並傳遞至gpio_poll函式中。
void* pvPollingThread( void *pvParameter )
{
    eSetPollingThreadState( RUNNING );
    if( eMBEnable( ) == MB_ENOERR )
    {
        do
        {
            gpio_poll(ucRegCoilsBuf[0]); // 改變IO口狀態
            if( eMBPoll( ) != MB_ENOERR )
                break;
        }
        while( eGetPollingThreadState( ) != SHUTDOWN );
    }
    ( void )eMBDisable( );
    eSetPollingThreadState( STOPPED );
    return 0;
}
    【線圈暫存器讀寫函式】
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
    eMBErrorCode eStatus = MB_ENOERR;
    int iNCoils = ( int )usNCoils;
    int usBitOffset;
   
    if( ( usAddress >= REG_COILS_START ) &&
       ( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) )
    {

        usBitOffset = ( int )( usAddress - REG_COILS_START );
        switch ( eMode )
        {
        case MB_REG_READ:
            while( iNCoils > 0 )
            {
                *pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset,
                                                 ( UCHAR )( iNCoils > 8 ? 8 : iNCoils ) );
                iNCoils -= 8;
                usBitOffset += 8;
            }
            break;
           
        case MB_REG_WRITE:
            while( iNCoils > 0 )
            {
                xMBUtilSetBits( ucRegCoilsBuf, usBitOffset,
                               ( UCHAR )( iNCoils > 8 ? 8 : iNCoils ),
                               *pucRegBuffer++ );
                iNCoils -= 8;
                usBitOffset += 8;
            }
            break;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
    return eStatus;
}
    【makefile】
# 指定編譯器
CROSS = arm-fsl-linux-gnueabi-
CC = $(CROSS)gcc
STRIP = $(CROSS)strip

# CFLAG包括標頭檔案目錄
CFLAGS = -g -Wall

# 標頭檔案查詢路徑
INC = -I. -Iport -I../../modbus/rtu \
        -I../../modbus/ascii -I../../modbus/include -I../../modbus/tcp

#
LIBS = -lpthread
# 目標
TARGET = modbustcp
# 原始檔
SRC = demo.c gpio-sysfs.c port/portother.c \
    port/portevent.c port/porttcp.c \
    ../../modbus/mb.c ../../modbus/tcp/mbtcp.c \
    ../../modbus/functions/mbfunccoils.c \
    ../../modbus/functions/mbfuncdiag.c \
    ../../modbus/functions/mbfuncholding.c \
    ../../modbus/functions/mbfuncinput.c \
    ../../modbus/functions/mbfuncother.c \
    ../../modbus/functions/mbfuncdisc.c \
    ../../modbus/functions/mbutils.c

# 原始檔編譯為目標檔案
OBJS = $(SRC:.c=.o)

.PHONY: clean

# 連結為可執行檔案
$(TARGET): $(OBJS)
    $(CC) $^ -o [email protected] $(LIBS)
    $(STRIP) [email protected]

# 可執行檔案和目標檔案
clean:
    rm -f $(OBJS)
    rm -f $(TARGET)

# 連續動作,先清除再編譯連結,複製到tftpboot中
install:clean $(TARGET)
    @echo 複製到tftpboot目錄
    cp $(TARGET) ~/tftpboot
    @echo 複製結束

# 編譯規則 加入標頭檔案 [email protected]代表目標檔案 $< 代表第一個依賴檔案
%.o:%.c
    $(CC) $(CFLAGS) $(INC) -o [email protected] -c $<
2 實驗    【1】在虛擬機器中make獲得可執行檔案——modbustcp    【2】配置EasyARM IP地址,例如EasyARM的IP地址為192.168.1.211    ifconfig eht0 192.168.1.211    【2】通過tftp傳輸可執行檔案至開發板(假設此時虛擬機器的IP地址為192.168.1.106)    tftp -g -r modbustcp 192.168.1.106    【3】修改可執行許可權。並執行    chmod a+x modbustcp    ./modbustcp    【4】modbus tcp中有一個簡單的控制檯,輸入h可獲得指令幫助。其中e為使能協議棧,q為退出程式。    輸入e使能modbus從機協議棧。
圖1 執行modbus tcp    【5】在windows中開啟modbus除錯軟體,連線EasyARM,IP地址為192.168.1.211,埠號為預設埠號205。
圖2 通過modbus tcp控制GPIO
圖3 實驗效果4 總結【1】操作步驟較多,實現modbus tcp需要不少的基礎知識。

相關推薦

EasyARM i.mx287學習筆記——通過modbus tcp控制GPIO

0 前言    本文使用freemodbus協議棧,在EasyARM i.mx287上實現了modbus tcp從機。在該從機中定義了線圈暫存器,其中線圈暫存器地址較低的4位和EasyARM的P2.4至P2.5關聯,通過modbus指令可控制GPIO的輸出。本文修改自free

EasyARM i.mx287學習筆記——開箱試用總結

0 前言    本月初(2014年8月)購買了周立功的EasyARM開發板,主控為EasyARM i.mx287。出於以下幾個理由購買了該開發板。    【1】主要原因,有人約我一起學習一起使用該開發板。    【2】該開發板價效比較高,到手300元以內(2015年初降低到2

nBodyCS<I>學習筆記之計算著色器

uuid 代碼 接下來 gin resource pos 示例 dynamic 通訊 nBodyCS<I>學習筆記之計算著色器 Nvidia-SDK(1) 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 DirectX一直是Windows

6.swoole學習筆記--異步tcp服務器

img tar com image iptables 分享 關閉 host style <?php //創建tcp服務器 $host=‘0.0.0.0‘; $port=9501; $serv=new swoole_server($host,$port); //設置異

netty學習筆記一:TCP粘包拆包

min -s 原因 兩個 image 分享 技術 ima 選項 什麽是TCP拆包粘包 假設客戶端發送了2條消息M1,M2。可能會出現以下幾種情況。 1、服務端正常接收到M1,M2這兩條消息。 2、服務端一次接收到了2個數據包,M1和M2粘合在一起,這時候就被稱為TCP粘包

apollo學習筆記---通過lincoln找出如何將控制訊號和CAN通訊相連線

任務目標:        現在人工智慧成為當下熱門研究物件,自動駕駛技術作為人工智慧重要的一個研究領域集結了大量的科技人才,然而高成本和高技術門檻成為研究自動駕駛技術的一個重要瓶頸。apollo的釋出為我們的開發提供了一個選擇,無奈,apollo推薦的lincoln實在太貴了

Hibernate學習筆記---通過load和get方法來查詢物件(只能根據主鍵來查詢)

下面的例子是說明如何來查詢一個物件。 get方法(get方法一經呼叫,會立即發出get方法) package com.ahuzl.hibernate; import java.util.Date;import org.hibernate.Session;import org

[NUST-Wangpeis]基於i.MX287學習Linux[1]---基本環境搭建及裝置資訊

如有錯誤,歡迎批評指正!!! 一、本教程基於周立功EasyARM-i.MX287開發套件 詳詢周立功網站,www.zlgmcu.com 二、系統恢復及相關設定 根據周立功產品使用說明恢復系統,設定系統IP地址為192.168.0.160,掛載到192.168.0.190

Android學習筆記---通過網頁喚醒自己的APP並且傳參

前言 相信大家在生活中會發現很多網頁都有這樣的功能,前一秒還在網頁呢 後一秒莫名其妙的就進入了他們的APP,那麼這種效果到底是如何做的呢? 經過本屌絲認真學習後發現是使用安卓中android:scheme屬性來完成功能的,這裡說一下我個人看法,我覺得andr

樹莓派學習筆記——實現modbus RTU從機

0.前言    本文使用樹莓派實現MODBUS RTU從機,藉助python庫——modbus-tk實現RTU從機。MODBUS是一種靈活可靠的工業通訊協議,常用的MODBUS協議包括MODBUS RTU和MODBUS TCP。藉助python強大的庫函式,可以在樹莓派平臺上

Tensorflow學習筆記-通過slim讀取TFRecord檔案

  TFRecord檔案格式的介紹:http://blog.csdn.net/lovelyaiq/article/details/78711944   由於slim是tensorflow的高階API,使用起來比較方便,例如在卷積或全連線層的書寫時,可以大大減少

[學習筆記]通過各語言特征碼尋找按鈕事件

說明 什麽 繼續 -- ++ color 註意 bubuko 檢測 今天的課件都無殼。 一 Delphi和BC++ DIE檢測一下,是Delphi OD載入 反匯編窗口右鍵---查找---二進制字符串 查看一下特征碼 復制Delphi的

Shell 腳本學習筆記八:流程控制

等於 break 語句 until循環 ase 所有 span 數字 if 語句 一、 if else /// 如果else分支沒有語句執行,就不要寫這個else 1、if 語句 if condition then

ELK 學習筆記之 elasticsearch 版本控制

如果 curl version last ges 外部 upd put image 版本控制: elasticsearch 版本控制: 內部版本控制 外部版本控制 內部版本控制: 內部版本會檢查你提供的版本值和文檔的版本值是否一致,如果不一致就報錯,一致則可以更

Perl 學習筆記-高級控制結構.unless控制結構

over 優先 span perl 運算符 spa size i++ php 1.unless控制結構  類似於獨立的else語句; 要麽條件為真, 要麽執行語句塊內的代碼; unless(<condition>){code...;} 等價於 if(<

ASA防火墻學習筆記2-ACL訪問控制策略

ASA ACL ACL 訪問控制列表 ASA防火墻學習筆記2-ACL訪問控制策略

第六週學習筆記,vc各類控制元件的輸入輸出

6w學習筆記  vc控制元件的輸入輸出 單選按鈕 當單擊 RadioButton 控制元件時,其 Checked 屬性設定為 true,並且呼叫 Click 事件處理程式。當 Checked 屬性的值更改時,將引發 CheckedChanged 事件。如果 AutoCheck 屬性設定為 tr

IOS開發學習筆記十四 UITableView控制元件實現ListView的效果

效果圖:專案地址 ViewController對應的程式碼: #import "ViewController.h" #import "CZHero.h" @interface ViewController () <UITableViewDataSource, UIT

View的學習筆記(二) 實現複合控制元件模板

實現複合控制元件模板 定義屬性 獲取屬性 通過TypedArray來獲取屬性值 組合控制元件 測量子View 放置子View 重寫滑動事件 通過介面來增加控制元件的互動 增加模板的拓展性 引用UI模板

Qt學習筆記4——視窗和控制元件

1.1 視窗定義 視窗:當一個部件沒有嵌入到其他部件中,則把這個部件叫作視窗或者頂層視窗,頂層視窗是沒有父視窗的,一般的,這些視窗都會被列在工作列中。通常,一個視窗會包含有標題欄,視窗邊框等。如果一個視窗具有父類,則這個視窗被稱為是次級視窗,例如設定了父類的QDialog就