首页 > 代码库 > EasyARM i.mx28学习笔记——通过modbus tcp控制GPIO
EasyARM i.mx28学习笔记——通过modbus tcp控制GPIO
0 前言
本文使用freemodbus协议栈,在EasyARM i.mx287上实现了modbus tcp从机。在该从机中定义了线圈寄存器,其中线圈寄存器地址较低的4位和EasyARM的P2.4至P2.5关联,通过modbus指令可控制GPIO的输出。本文修改自freemodbus 示例LINUXTCP,经过简单的修改也可用于其他Linux开发板。
【相关博文】
【EasyARM i.mx28学习笔记——文件IO方式操作GPIO】
【EasyARM i.mx28学习笔记——安装和使用tftp】
【树莓派学习笔记——实现modbus RTU从机 】
【MODBUS协议整理——汇总】
【freemodbus modbus TCP 学习笔记】
【MODBUS学习笔记——modbus tk modbus TCP主机实现】
【Linux学习笔记——例说makefile 索引博文】
【代码仓库】
代码仓库位于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 = http://www.mamicode.com/demo.c gpio-sysfs.c port/portother.c port/portevent.c port/modbus/modbus/tcp/modbus/functions/modbus/functions/modbus/functions/modbus/functions/modbus/functions/modbus/functions/modbus/functions/mbutils.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需要不少的基础知识。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。