STM32-modbus rtu 之从机程序

2019-12-02来源: eefocus关键字:STM32-modbus  rtu  从机程序

STM32-modbus rtu 之从机程序


以前移植过freemodbus,这次是自己重新写,只实现保持寄存器的读写。


一、串口


这部分跟上一篇文章主机程序一样,DMA接收,直接发送。


二、错误反馈


/*

发送 错误反馈

*/

void  mb_sentACK( u8 cm,u8 err)

{

    u16 temp;

    serialTXbuf_st.buf[0] = local_addr;

    serialTXbuf_st.buf[1] = cm+0x80;

    serialTXbuf_st.buf[2] =  err;

    temp=usMBCRC16(  serialTXbuf_st.buf,  3 );

    serialTXbuf_st.buf[3] = temp;    //低

    serialTXbuf_st.buf[4] = temp>>8;

}

错误码为命令F+0X80


三、对 F=0X03的反馈


/*

回应 读保持寄存器,命令0X03

*/

 void  mb_sentfor_readHoldingReg(const _mbdata_st mbd)

{

    u16 temp;

    u8 len = mbd.len*2+5;

    serialTXbuf_st.buf[0] = local_addr;

    serialTXbuf_st.buf[1] = 0x03;

    serialTXbuf_st.buf[2] = mbd.len*2;

    /*用户数据*/

    for(temp=0;temp< (len-5)/2;temp++)

    {

        serialTXbuf_st.buf[3+temp*2] = mbd.buf[mbd.start+temp] >>8;

        serialTXbuf_st.buf[4+temp*2] = mbd.buf[mbd.start+temp] ;

    }

    temp=usMBCRC16(  serialTXbuf_st.buf,  len-2 );

    serialTXbuf_st.buf[len-2] = temp;    //低

    serialTXbuf_st.buf[len-1] = temp>>8;

    myUSART_Sendarr(  USART1,   serialTXbuf_st.buf , len) ;  

    while( (USART1->SR&0X40)==0 ); //等待发送完成 

}



四、对F=0X10的反馈


/*

回应 写保持寄存器,命令0X10

*/

void  mb_sentfor_writeHoldingReg( _mbdata_st *pmb)

{

    u16 temp;

    u8 i;

    temp=usMBCRC16(  serialRXbuf_st.buf,  6 );

    serialTXbuf_st.buf[0]=temp;

    serialTXbuf_st.buf[1]=temp>>8;

    //发送8字节反馈

    myUSART_Sendarr(  USART1,   serialRXbuf_st.buf ,  6) ; //前6字节 

    myUSART_Sendarr(  USART1,   serialTXbuf_st.buf ,  2) ; //CRC

    //修改保持寄存器

    for(i=0;i< pmb->len ;i++)

    {

       pmb->buf [ pmb->start +i] = (u16)(serialRXbuf_st.buf[i*2+7]<<8 ) + serialRXbuf_st.buf[i*2+8];

    }

    while( (USART1->SR&0X40)==0 ){}; //等待发送完成 

}



五、接收处理


/*帧检测*/

u8 frm_cheak(_serialbuf_st *rx, _mbfrm_st *pfrm)

{

    u16 t,len;

    if( rx->len < 4   ) return res_ERR1;

    len=rx->len;

    rx->len = 0 ;

    

    pfrm->addr=rx->buf[0];

    if( pfrm->addr != local_addr ) return res_ERR2;

    pfrm->crc= (u16)(rx->buf[ len-1]<<8) + (rx->buf[ len-2]) ;

    t= usMBCRC16( rx->buf,  len-2 );

    if( pfrm->crc !=  t ) return  res_ERR3;

    pfrm->cmd=rx->buf[1]; 

    pfrm->start=( u16)(rx->buf[2] <<8 ) + rx->buf[3] ;

    pfrm->rlen= ( u16)(rx->buf[4] <<8 ) + rx->buf[5] ;

    if( pfrm->start > 0x7d) return res_ERR4;//超出地址

    if( pfrm->rlen + pfrm->start > 0x7d) return res_ERR5;//超出长度

    return res_OK;

}

 

 

//接收

 u8 smb_recvHoldingReg( _mbdata_st *pmb  )

{

    u8 rel;

    u16 temp ;

    _mbfrm_st frm;

    

    rel=frm_cheak( &serialRXbuf_st , &frm);

    if( rel == res_OK)

    {

        mb_setMODRXorTX(0);//转为发送模式

        //延时,给主机准备时间

        delay_ms(10);

        pmb->len =  frm.rlen;

        pmb->start =  frm.start;

        switch( frm.cmd)

        {

        case 0x03://读寄存器

            mb_sentfor_readHoldingReg( *pmb );

        break ;

        case 0x10://写寄存器

            mb_sentfor_writeHoldingReg( pmb);

        break ;

        }

        mb_setMODRXorTX(0);//转为接收模式

    }

    else 

    if(rel == res_ERR3)

    {

       mb_sentACK(  frm.cmd ,  rel) ;

    }

    return rel; 

}

 

/*主循环调用*/

void mb_poll()

{

   smb_recvHoldingReg( &HoldingReg_st  ) ;

}


在主循环里调用mb_poll()函数即可。

六、验证


将STM32的串口与电脑连接,打开PC端软件MODBUS POLL ,设置好参数,OK,如下图


F=0X03

F=0X10

关键字:STM32-modbus  rtu  从机程序 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic481703.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:STM32 堆栈的理解
下一篇:STM32的操作过程,寄存器配置与调试过程

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

FreeModbus for stm32(Keil工程)——精简Modbus slave协议
1、测试环境Keil MDK 4.7a  stm32f103c8, PB12为输出线圈,可以通过Modbus Poll来控制线圈的输出状态。2、通过ModbusProt.h配置硬件、数据缓冲区大小和功能码配置3、移植要点为Port.c和Port.h   定时器操作在stm32平台下基本不用改    a、定时器初始化;   xMBPortTimersInit()    b、开定时器及中断; vMBPortTimersEnable()    c、关定时器及中断
发表于 2019-12-10
FreeModbus for stm32(Keil工程)——精简Modbus slave协议
STM32L053 CRC16-Modbus配置
STM32L053 CRC16-Modbus配置一切为了实用,直接上代码const uint8_t auchCRCHi[] ={0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,0x00, 0xC1, 0x81
发表于 2019-07-22
基于Modbus的RS485通讯+STM32+IAR
最近一直在看Modbus相关的内容,也在网上搜罗了许久,发现大部分内容都是基于协议的书面解释,很少有成功的例程供大家参考,在此将自己最近更改调试通过的例子跟大家分享一下,在此要感谢某论坛的xukai871105.介绍下附件工程:采用的MCU为STM32F103RBT6,ST库版本为3.5版,FreeModbus为1.5版,开发环境为IAR6.3版,调试器为Jlink V8,用到的调试工具为Jobs版的USB转RS485转接板。话不多说,上图:代码中大部分都有详细的注释:看看Jobs版的转接板吧:来个上位机虚拟端Modbus Poll 的效果图:工程文件打包上传:基于Modbus的RS485通讯
发表于 2018-10-17
基于Modbus的RS485通讯+STM32+IAR
FreeModbus 移植于STM32 实现Modbus RTU通信
       毕业设计自己要做个基于STM32的PLC能直接跑语句表的,现在看来好像没有什么创新的地方,不过实现的方式绝对够创新的了...呵呵。自己写的开题报告中说了要有高级的通信功能。现在做以太网有点来不及了,CAN又感觉不搭调,硬件上也没准备。串口上跑Modbus感觉不错。本来西门子的S7-200就能跑Modbus,STM32-PLC当然也要支持Modbus 什么 组态软件,触摸屏都可以连上,不过FreeModbus只支持从机有点可惜,当然本来协议也不难而且也必要实现全协议栈。 Modbus中文协议.PDF STM32移植FreeModbus的步骤: 首先去 http
发表于 2016-10-05
FreeModbus 移植于STM32 实现Modbus RTU通信
基于ARM Cortex-M3的MODBUS协议实现及其应用
送数据尾部作为一个整体发送给接收方。接收方将收到的数据同样除以生成多项式,若余数为零刚传输正常,若余数不为零则传输出错。2 电路连接及硬件参数    在无损探伤试验仪中,选用基于ARM Cortex-M3内核的STM32F103ZET6微控制器作为处理核心,而变频器采用了烟台惠丰公司的F2000-G矢量变频酪。STM32F103ZET6通过基于MAX3485的RS485链路与F2000-G相连,按照MODBUS协议与之通信,实现变频调速的控制功能。RS485接口电路如图2所示,STM32F103ZET6的USART3的Uart3Rx、Uart3Tx连接到MAX3485的RO、DI以进行RS232
发表于 2011-08-05
基于ARM Cortex-M3的MODBUS协议实现及其应用
FreeModbus 精简版本(Only RTU) for M128 (Modbus Slave)
/3231855.html9600 8 N 1 与 Modbus Poll连接地址为1 , M128时钟为8M 3、状态: 通信过程中PA7 LED闪烁4、代码信息:只留RTU模式 优化代码ModbusUser.c      用记功能代码 ModbusFun.c       整合FreeModbus的功能c代码文件; ModbusRTU.c       Modbus的RTU模式桢处理,整理FreeModbus去除ASCII模式
发表于 2019-12-10
FreeModbus 精简版本(Only RTU) for M128 (Modbus Slave)
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2019 EEWORLD.com.cn, Inc. All rights reserved