[其他ST产品] STM32-modbus rtu 之从机程序

[复制链接]
738|16
 楼主| 结合国际经验 发表于 2022-11-30 15:58 | 显示全部楼层 |阅读模式
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

 楼主| 结合国际经验 发表于 2022-11-30 16:14 | 显示全部楼层
对 F=0X03的反馈
  1. /*
  2. 回应 读保持寄存器,命令0X03
  3. */
  4. void  mb_sentfor_readHoldingReg(const _mbdata_st mbd)
  5. {
  6.     u16 temp;
  7.     u8 len = mbd.len*2+5;
  8.     serialTXbuf_st.buf[0] = local_addr;
  9.     serialTXbuf_st.buf[1] = 0x03;
  10.     serialTXbuf_st.buf[2] = mbd.len*2;
  11.     /*用户数据*/
  12.     for(temp=0;temp< (len-5)/2;temp++)
  13.     {
  14.         serialTXbuf_st.buf[3+temp*2] = mbd.buf[mbd.start+temp] >>8;
  15.         serialTXbuf_st.buf[4+temp*2] = mbd.buf[mbd.start+temp] ;
  16.     }
  17.     temp=usMBCRC16(  serialTXbuf_st.buf,  len-2 );
  18.     serialTXbuf_st.buf[len-2] = temp;    //低
  19.     serialTXbuf_st.buf[len-1] = temp>>8;
  20.     myUSART_Sendarr(  USART1,   serialTXbuf_st.buf , len) ;  
  21.     while( (USART1->SR&0X40)==0 ); //等待发送完成
  22. }
 楼主| 结合国际经验 发表于 2022-11-30 16:16 | 显示全部楼层
对F=0X10的反馈
  1. /*
  2. 回应 写保持寄存器,命令0X10
  3. */
  4. void  mb_sentfor_writeHoldingReg( _mbdata_st *pmb)
  5. {
  6.     u16 temp;
  7.     u8 i;
  8.     temp=usMBCRC16(  serialRXbuf_st.buf,  6 );
  9.     serialTXbuf_st.buf[0]=temp;
  10.     serialTXbuf_st.buf[1]=temp>>8;
  11.     //发送8字节反馈
  12.     myUSART_Sendarr(  USART1,   serialRXbuf_st.buf ,  6) ; //前6字节
  13.     myUSART_Sendarr(  USART1,   serialTXbuf_st.buf ,  2) ; //CRC
  14.     //修改保持寄存器
  15.     for(i=0;i< pmb->len ;i++)
  16.     {
  17.        pmb->buf [ pmb->start +i] = (u16)(serialRXbuf_st.buf[i*2+7]<<8 ) + serialRXbuf_st.buf[i*2+8];
  18.     }
  19.     while( (USART1->SR&0X40)==0 ){}; //等待发送完成
  20. }
 楼主| 结合国际经验 发表于 2022-11-30 16:17 | 显示全部楼层
接收处理
  1. /*帧检测*/
  2. u8 frm_cheak(_serialbuf_st *rx, _mbfrm_st *pfrm)
  3. {
  4.     u16 t,len;
  5.     if( rx->len < 4   ) return res_ERR1;
  6.     len=rx->len;
  7.     rx->len = 0 ;
  8.    
  9.     pfrm->addr=rx->buf[0];
  10.     if( pfrm->addr != local_addr ) return res_ERR2;
  11.     pfrm->crc= (u16)(rx->buf[ len-1]<<8) + (rx->buf[ len-2]) ;
  12.     t= usMBCRC16( rx->buf,  len-2 );
  13.     if( pfrm->crc !=  t ) return  res_ERR3;
  14.     pfrm->cmd=rx->buf[1];
  15.     pfrm->start=( u16)(rx->buf[2] <<8 ) + rx->buf[3] ;
  16.     pfrm->rlen= ( u16)(rx->buf[4] <<8 ) + rx->buf[5] ;
  17.     if( pfrm->start > 0x7d) return res_ERR4;//超出地址
  18.     if( pfrm->rlen + pfrm->start > 0x7d) return res_ERR5;//超出长度
  19.     return res_OK;
  20. }


  21. //接收
  22. u8 smb_recvHoldingReg( _mbdata_st *pmb  )
  23. {
  24.     u8 rel;
  25.     u16 temp ;
  26.     _mbfrm_st frm;
  27.    
  28.     rel=frm_cheak( &serialRXbuf_st , &frm);
  29.     if( rel == res_OK)
  30.     {
  31.         mb_setMODRXorTX(0);//转为发送模式
  32.         //延时,给主机准备时间
  33.         delay_ms(10);
  34.         pmb->len =  frm.rlen;
  35.         pmb->start =  frm.start;
  36.         switch( frm.cmd)
  37.         {
  38.         case 0x03://读寄存器
  39.             mb_sentfor_readHoldingReg( *pmb );
  40.         break ;
  41.         case 0x10://写寄存器
  42.             mb_sentfor_writeHoldingReg( pmb);
  43.         break ;
  44.         }
  45.         mb_setMODRXorTX(0);//转为接收模式
  46.     }
  47.     else
  48.     if(rel == res_ERR3)
  49.     {
  50.        mb_sentACK(  frm.cmd ,  rel) ;
  51.     }
  52.     return rel;
  53. }


  54. /*主循环调用*/
  55. void mb_poll()
  56. {
  57.    smb_recvHoldingReg( &HoldingReg_st  ) ;
  58. }
 楼主| 结合国际经验 发表于 2022-11-30 16:17 | 显示全部楼层
在主循环里调用mb_poll()函数即可。
 楼主| 结合国际经验 发表于 2022-11-30 16:18 | 显示全部楼层
验证
将STM32的串口与电脑连接,打开PC端软件MODBUS POLL ,设置好参数,OK,如下图

F=0X03
36294638711c2c55a6.png
 楼主| 结合国际经验 发表于 2022-11-30 16:19 | 显示全部楼层
R2D2 发表于 2022-11-30 20:51 | 显示全部楼层
MODBUS从机其实挺麻烦的,建议直接移植freemodbus。
Wordsworth 发表于 2024-11-8 07:21 | 显示全部楼层

逐渐变细的孔(也称为邮票孔)变得越来越普遍
Clyde011 发表于 2024-11-8 08:24 | 显示全部楼层

可能还需要进行一些额外的测试
公羊子丹 发表于 2024-11-8 09:17 | 显示全部楼层

正激:脉冲变压器的原/副边相位关系
Uriah 发表于 2024-11-8 11:23 | 显示全部楼层

并在必要时进行去毛刺。
帛灿灿 发表于 2024-11-8 13:19 | 显示全部楼层

改变测试负载的值,再次测试输出的电流和电压
Bblythe 发表于 2024-11-8 14:22 | 显示全部楼层

表征负载能力的指标是负载能力和负载能力上升时间
周半梅 发表于 2024-11-8 16:18 | 显示全部楼层

直至电感器饱和,使开关器件烧毁。好的元器件就到唯样商城。图中的D3与N3构成的磁通复位电路,提供了泄放多余磁能的渠道
Pulitzer 发表于 2024-11-8 17:21 | 显示全部楼层

一些静态测试参数还包括波浪、纹波、起伏和静态输出电压精度。
童雨竹 发表于 2024-11-8 19:17 | 显示全部楼层

测试参数包括电源的输出电压、输出电流、负载能力、压降、效率和输出波形
您需要登录后才可以回帖 登录 | 注册

本版积分规则

66

主题

775

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部