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

https://blog.csdn.net/wangzibigan/article/details/77722981

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32 Modbus-RTU主机程序是一种针对STM32单片机开发的软件程序,用于实现Modbus通信协议中主站(主机)的功能。Modbus-RTU是一种常见的串行通信协议,用于在工业自动化系统中进行数据交换。 STM32 Modbus-RTU主机程序的设计目的是实现STM32单片机作为Modbus通信系统中的主站,具备与从站进行通信的能力。主机程序中通过串口与从站进行通信,接收和发送数据。主机程序需要实现Modbus协议的相关功能,包括函数码解析、地址解析、数据读写操作等。 在设计STM32 Modbus-RTU主机程序时,需要考虑以下几个关键因素。首先,需要确定从站的地址和通信参数,包括波特率、数据位数、停止位等。其次,需要实现Modbus通信协议的各种功能,如读取保持寄存器、读取输入寄存器、写入单个线圈等。此外,还要考虑主机与从站的通信方式和通信频率,以及数据的处理和解析方式。 在编写STM32 Modbus-RTU主机程序时,可以使用STM32的开发环境进行开发,如Keil等。首先建立串口通信功能,然后根据主机与从站的通信协议,实现相应的Modbus函数码解析和数据读写操作。最后进行测试和调试,确保主机程序能够正确地与从站进行通信,并实现所需的数据交换功能。 总之,STM32 Modbus-RTU主机程序是一种通过STM32单片机实现Modbus通信协议的软件程序。它能够使STM32单片机具备作为主站与从站进行通信的能力,并实现相关的数据读写操作。通过该主机程序,能够在工业自动化系统中实现高效可靠的通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值