[G32R] 【极海G32R430 TinyBoard开发板测评】+ RS485实现Modbus协议

[复制链接]
419|4
袁胜富 发表于 2026-5-9 00:11 | 显示全部楼层 |阅读模式
本帖最后由 袁胜富 于 2026-5-9 09:42 编辑

一、概述

     在工业控制数据采集中,基于RS485实现的Modbus用于传感器采集数据的传输。
        G32R430的USART支持 RS485 的发送使能 I/O 自动控制,这是个很好的功能必须利用起来。
       本次测试例程使用FreeModbus来移植。目标是使用Modbus通信来控制灯的亮灭。
       外设资源:timer*1,usart*1,gpio*2.
       5046869fe04efdd2da.png
      6015669fe050c0bf4c.png
二、代码移植
1.外设共用头文件
  1. /*
  2. * FreeModbus Libary: BARE Port
  3. * Copyright (C) 2006 Christian Walter <wolti@sil.at>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18. *
  19. * File: $Id$
  20. */

  21. #ifndef _PORT_H
  22. #define _PORT_H

  23. #include <assert.h>
  24. #include <inttypes.h>

  25. #define        INLINE                      inline
  26. #define PR_BEGIN_EXTERN_C           extern "C" {
  27. #define        PR_END_EXTERN_C             }
  28. // 关全局中断
  29. #define ENTER_CRITICAL_SECTION()   __asm volatile ("cpsid i" : : : "memory")
  30. // 开全局中断
  31. #define EXIT_CRITICAL_SECTION()    __asm volatile ("cpsie i" : : : "memory")

  32. typedef uint8_t BOOL;

  33. typedef unsigned char UCHAR;
  34. typedef char CHAR;

  35. typedef uint16_t USHORT;
  36. typedef int16_t  SHORT;

  37. typedef uint32_t ULONG;
  38. typedef int32_t  LONG;

  39. #ifndef TRUE
  40. #define TRUE            1
  41. #endif

  42. #ifndef FALSE
  43. #define FALSE           0
  44. #endif

  45. /*------------------------------------USART相关宏定义-------------------------------*/
  46. #define  MODBUS_USART_PORT         USART1
  47. #define  MODBUS_USART_IRQn         USART1_IRQn
  48. #define  MODBUS_USART_IRQHandler   USART1_IRQHandler
  49. #define  MODBUS_USART_PERIPH       DDL_RCM_APB_PERIPHERAL_USART1
  50. #define  MODBUS_USART_CLOCK_API    DDL_RCM_EnableAPBPeripheral

  51. #define  MODBUS_USART_GPIO_PERIPH         DDL_RCM_AHB_PERIPHERAL_GPIO
  52. #define  MODBUS_USART_GPIO_CLOCK_API      DDL_RCM_EnableAHBPeripheral


  53. #define  MODBUS_USART_TX_PORT      GPIOB
  54. #define  MODBUS_USART_TX_PIN       DDL_GPIO_PIN_9
  55. #define  MODBUS_USART_TX_AF        DDL_GPIO_AF_0

  56. #define  MODBUS_USART_RX_PORT      GPIOB
  57. #define  MODBUS_USART_RX_PIN       DDL_GPIO_PIN_6
  58. #define  MODBUS_USART_RX_AF        DDL_GPIO_AF_0

  59. #define  MODBUS_USART_DE_PORT      GPIOB
  60. #define  MODBUS_USART_DE_PIN       DDL_GPIO_PIN_11
  61. #define  MODBUS_USART_DE_AF        DDL_GPIO_AF_1


  62. /*------------------------------------TIMER相关宏定义-------------------------------*/
  63. #define  MODBUS_TIME_PORT          TMR1
  64. #define  MODBUS_TIME_IRQn          TMR1_IRQn
  65. #define  MODBUS_TIME_IRQHandler    TMR1_IRQHandler
  66. #define  MODBUS_TIME_PERIPH        DDL_RCM_APB_PERIPHERAL_TMR1
  67. #define  MODBUS_TIME_CLOCK_API     DDL_RCM_EnableAPBPeripheral


  68. extern void __myaeabi_assert(const char *expr, const char *file, int line);

  69. #define myassert(e) ((e) ? (void)0 : __myaeabi_assert(#e, __FILE__, __LINE__))


  70. #endif


2.串口移植
  1. /*
  2. * FreeModbus Libary: BARE Port
  3. * Copyright (C) 2006 Christian Walter <wolti@sil.at>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18. *
  19. * File: $Id$
  20. */

  21. #include "port.h"
  22. #include "main.h"

  23. /* ----------------------- Modbus includes ----------------------------------*/
  24. #include "mb.h"
  25. #include "mbport.h"

  26. /* ----------------------- static functions ---------------------------------*/
  27. static void prvvUARTTxReadyISR( void );
  28. static void prvvUARTRxISR( void );
  29. static void MODBUS_USART_IRQHandler(void);
  30. /* ----------------------- Start implementation -----------------------------*/
  31. void vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
  32. {
  33.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable
  34.      * transmitter empty interrupts.
  35.      */
  36.     /* If xRXEnable enable serial receive interrupts. If xTxENable enable
  37.      * transmitter empty interrupts.
  38.      */
  39.   
  40.     if (xRxEnable)  
  41.     {
  42.                           DDL_USART_EnableIT_RXNE(MODBUS_USART_PORT);//使能接收中断
  43.                           DDL_USART_ClearFlag_RXNE(MODBUS_USART_PORT);//清除中断标志
  44.     }
  45.     else  
  46.     {
  47.                           DDL_USART_DisableIT_RXNE(MODBUS_USART_PORT);//失能接收中断;
  48.     }
  49.    
  50.     if (xTxEnable)  
  51.     {
  52.                           DDL_USART_EnableIT_TC(MODBUS_USART_PORT);//使能发送中断
  53.                           DDL_USART_ClearFlag_TC(MODBUS_USART_PORT);//清除中断标志
  54.     }
  55.     else  
  56.     {
  57.                           DDL_USART_DisableIT_TC(MODBUS_USART_PORT);//失能发送中断
  58.     }
  59. }

  60. void vMBPortClose( void )
  61. {
  62.     DDL_USART_Disable(MODBUS_USART_PORT);        //关闭usart  
  63. }



  64. BOOL xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
  65. {
  66.     DDL_GPIO_InitTypeDef GPIO_InitStruct = {0U};
  67.     DDL_USART_InitTypeDef USART_InitStruct = {0U};

  68.     /* 配置时钟 */
  69.     DDL_RCM_Unlock();
  70.     MODBUS_USART_CLOCK_API(MODBUS_USART_PERIPH);
  71.     MODBUS_USART_GPIO_CLOCK_API(MODBUS_USART_GPIO_PERIPH);
  72.     DDL_RCM_Lock();

  73.     /* MODBUS_USART_PORT 配置接收发送引脚*/
  74.     GPIO_InitStruct.Pin        = MODBUS_USART_TX_PIN;
  75.     GPIO_InitStruct.Mode       = DDL_GPIO_MODE_ALTERNATE;
  76.     GPIO_InitStruct.Speed      = DDL_GPIO_SPEED_FREQ_HIGH;
  77.     GPIO_InitStruct.OutputType = DDL_GPIO_OUTPUT_PUSHPULL;
  78.     GPIO_InitStruct.Pull       = DDL_GPIO_PULL_NO;
  79.     GPIO_InitStruct.Alternate  = MODBUS_USART_TX_AF;
  80.     DDL_GPIO_Init(MODBUS_USART_TX_PORT, &GPIO_InitStruct);
  81.                
  82.     GPIO_InitStruct.Pin        = MODBUS_USART_RX_PIN;
  83.     GPIO_InitStruct.Mode       = DDL_GPIO_MODE_ALTERNATE;
  84.     GPIO_InitStruct.Speed      = DDL_GPIO_SPEED_FREQ_HIGH;
  85.     GPIO_InitStruct.OutputType = DDL_GPIO_OUTPUT_PUSHPULL;
  86.     GPIO_InitStruct.Pull       = DDL_GPIO_PULL_NO;
  87.     GPIO_InitStruct.Alternate  = MODBUS_USART_RX_AF;
  88.     DDL_GPIO_Init(MODBUS_USART_RX_PORT, &GPIO_InitStruct);
  89.    
  90.     /* MODBUS_USART_PORT DE*/
  91.     GPIO_InitStruct.Pin        = MODBUS_USART_DE_PIN;
  92.     GPIO_InitStruct.Mode       = DDL_GPIO_MODE_ALTERNATE;
  93.     GPIO_InitStruct.Speed      = DDL_GPIO_SPEED_FREQ_HIGH;
  94.     GPIO_InitStruct.OutputType = DDL_GPIO_OUTPUT_PUSHPULL;
  95.     GPIO_InitStruct.Pull       = DDL_GPIO_PULL_UP;
  96.     GPIO_InitStruct.Alternate  = MODBUS_USART_DE_AF;
  97.     DDL_GPIO_Init(MODBUS_USART_DE_PORT, &GPIO_InitStruct);

  98.     /* MODBUS_USART_PORT 配置 */
  99.     USART_InitStruct.BaudRate            = ulBaudRate;
  100.     if (eParity == MB_PAR_NONE)
  101.     {
  102.         USART_InitStruct.Parity              = DDL_USART_PARITY_NONE;             //不进行奇偶位检测
  103.     }
  104.     else if (eParity == MB_PAR_EVEN)
  105.     {
  106.         USART_InitStruct.Parity              = DDL_USART_PARITY_EVEN;           //进行偶位检测
  107.     }
  108.     else
  109.     {
  110.         USART_InitStruct.Parity              = DDL_USART_PARITY_ODD;           //进行奇位检测
  111.     }
  112.    
  113.     if (ucDataBits == 9)
  114.     {
  115.             USART_InitStruct.DataWidth           = DDL_USART_DATAWIDTH_9B;        //发送数据为9位
  116.     }
  117.     else
  118.     {
  119.             USART_InitStruct.DataWidth           = DDL_USART_DATAWIDTH_8B;        //发送数据为8位
  120.     }
  121.                
  122.     USART_InitStruct.StopBits            = DDL_USART_STOPBITS_1;
  123.     USART_InitStruct.TransferDirection   = DDL_USART_DIRECTION_TX_RX;
  124.     USART_InitStruct.HardwareFlowControl = DDL_USART_HWCONTROL_NONE;
  125.     USART_InitStruct.OverSampling        = DDL_USART_OVERSAMPLING_16;
  126.     DDL_USART_Init(MODBUS_USART_PORT, &USART_InitStruct);

  127.     /* RS485 DE Mode Configuration */
  128.     /* Calculation for DE deassertion time (DEDT): */
  129.     /* DEDT time = DEDT value * (bit time / oversampling rate) */
  130.     /* Bit time = 1 / Baud rate */
  131.     /* Oversampling rate = 16 (DDL_USART_OVERSAMPLING_16) */
  132.     /* Assuming Baud rate = 115200: */
  133.     /* Bit time = 1 / 115200 ≈ 8.68 us */
  134.     /* DEDT time = 16 * (8.68 us / 16) = 8.68 us */
  135.     DDL_USART_SetDEDeassertionTime(MODBUS_USART_PORT, 0x10);

  136.     /* Calculation for DE assertion time (DEAT): */
  137.     /* DEAT time = 16 * (8.68 us / 16) = 8.68 us */
  138.     DDL_USART_SetDEAssertionTime(MODBUS_USART_PORT, 0x10);

  139.     /* Enable USART DE Mode */
  140.     DDL_USART_EnableDEMode(MODBUS_USART_PORT);

  141.     /* USART Enable */
  142.     DDL_USART_Enable(MODBUS_USART_PORT);        

  143.     /* Redirect the interrupt service function to the USART_Receive_Isr function. */
  144.     DDL_Interrupt_Register(MODBUS_USART_IRQn, USART1_IRQHandler);
  145.     /* Enable NVIC Interrupt */
  146.     DDL_NVIC_EnableIRQRequest(MODBUS_USART_IRQn,1,0);
  147.                
  148.     return TRUE;   
  149. }

  150. BOOL xMBPortSerialPutByte( CHAR ucByte )
  151. {
  152.     /* Put a byte in the UARTs transmit buffer. This function is called
  153.      * by the protocol stack if pxMBFrameCBTransmitterEmpty( ) has been
  154.      * called. */
  155.     DDL_USART_TransmitData8(MODBUS_USART_PORT,ucByte);//发送一个字节
  156.     return TRUE;
  157. }

  158. BOOL xMBPortSerialGetByte( CHAR * pucByte )
  159. {
  160.     /* Return the byte in the UARTs receive buffer. This function is called
  161.      * by the protocol stack after pxMBFrameCBByteReceived( ) has been called.
  162.      */
  163.    
  164.     *pucByte = DDL_USART_ReceiveData8(MODBUS_USART_PORT);  //接收一个字节
  165.     //DDL_USART_TransmitData8(USART1,*pucByte );
  166.     return TRUE;
  167. }

  168. /* Create an interrupt handler for the transmit buffer empty interrupt
  169. * (or an equivalent) for your target processor. This function should then
  170. * call pxMBFrameCBTransmitterEmpty( ) which tells the protocol stack that
  171. * a new character can be sent. The protocol stack will then call
  172. * xMBPortSerialPutByte( ) to send the character.
  173. */
  174. static void prvvUARTTxReadyISR( void )
  175. {
  176.     pxMBFrameCBTransmitterEmpty(  );
  177. }

  178. /* Create an interrupt handler for the receive interrupt for your target
  179. * processor. This function should then call pxMBFrameCBByteReceived( ). The
  180. * protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
  181. * character.
  182. */
  183. static void prvvUARTRxISR( void )
  184. {
  185.     pxMBFrameCBByteReceived(  );
  186. }

  187. /*****************************************************************************
  188. *   函数名:MODBUS_USART_PORT_IRQHandler
  189. *   功  能:串口中断服务函数
  190. *   输  入:
  191. *          无
  192. *   输  出:
  193. *          无
  194. ****************************************************************************/
  195. void MODBUS_USART_IRQHandler(void)
  196. {
  197. //#if SYSTEM_SUPPORT_OS
  198. //        OSIntEnter();
  199. //#endif
  200.    
  201.     if (DDL_USART_IsActiveFlag_RXNE(MODBUS_USART_PORT) == SET)  //接收中断
  202.     {
  203.         prvvUARTRxISR();
  204.                           DDL_USART_ClearFlag_RXNE(MODBUS_USART_PORT);
  205.     }
  206.    
  207.     if (DDL_USART_IsActiveFlag_TC(MODBUS_USART_PORT) == SET)  //发送中断
  208.     {
  209.         prvvUARTTxReadyISR();
  210.         DDL_USART_ClearFlag_TC(MODBUS_USART_PORT);
  211.     }

  212. //#if SYSTEM_SUPPORT_OS
  213. //        OSIntExit();
  214. //#endif
  215. }


  216. void __myaeabi_assert(const char *expr, const char *file, int line) {
  217.     // 例如通过串口输出断言信息
  218.     //printf("Assertion failed: %s, file %s, line %d\n", expr, file, line);
  219.     //while (1);  // 死循环或触发看门狗
  220. }
  221. /***********************************文件结束***********************************/




3.定时器移植
  1. /*
  2. * FreeModbus Libary: BARE Port
  3. * Copyright (C) 2006 Christian Walter <wolti@sil.at>
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2.1 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  18. *
  19. * File: $Id$
  20. */

  21. /* ----------------------- Platform includes --------------------------------*/
  22. #include "port.h"
  23. #include "main.h"

  24. /* ----------------------- Modbus includes ----------------------------------*/
  25. #include "mb.h"
  26. #include "mbport.h"

  27. /* ----------------------- static functions ---------------------------------*/
  28. static void prvvTIMERExpiredISR( void );
  29. static void MODBUS_TIME_IRQHandler(void);
  30. //当波特率 > 19200bps时,采用定时器时钟固定为1750us ,
  31. //当波特率 < 19200bps时,定时器时钟为3.5个字符传输时间长
  32. /* ----------------------- Start implementation -----------------------------*/
  33. BOOL xMBPortTimersInit( USHORT usTim1Timerout50us )
  34. {        
  35.     DDL_TMR_InitTypeDef TMR_InitStruct = {0U};
  36.     uint16_t PrescalerValue;

  37.     //时基频率 / (1 + Prescaler) = 20KHz
  38.     PrescalerValue = (uint16_t)((SystemCoreClock / 2400) - 1);

  39.     /* Config Clock */
  40.     DDL_RCM_Unlock();
  41.     MODBUS_TIME_CLOCK_API(MODBUS_TIME_PERIPH);
  42.     DDL_RCM_Lock();

  43.     /* Config MODBUS_TIME_PORT */
  44.     /* Calculation details: */
  45.     /* Main clock frequency: 120 MHz */
  46.     /* Timer frequency after prescaler: 120 MHz / (Prescaler + 1) = 1 MHz (1 us per count) */
  47.     /* Auto-reload value: 999 (Timer counts 1000 cycles before an update event) */
  48.     /* Update event period: 1000*1 us = 1 ms */
  49.     /* Therefore, TMR1 generates an update interrupt every 1 millisecond. */
  50.                
  51.     TMR_InitStruct.Prescaler         = PrescalerValue;
  52.     TMR_InitStruct.CounterMode       = DDL_TMR_COUNTERMODE_UP;
  53.     TMR_InitStruct.Autoreload        = (uint16_t)usTim1Timerout50us;
  54.     TMR_InitStruct.ClockDivision     = DDL_TMR_CLOCKDIVISION_DIV1;
  55.     TMR_InitStruct.RepetitionCounter = 0x00000000U;
  56.     DDL_TMR_Init(MODBUS_TIME_PORT, &TMR_InitStruct);

  57.     /* Enable MODBUS_TIME_PORT Interrupt */
  58.           DDL_TMR_EnableIT_UPDATE(MODBUS_TIME_PORT);
  59.     DDL_Interrupt_Register(MODBUS_TIME_IRQn, MODBUS_TIME_IRQHandler);
  60.     DDL_NVIC_EnableIRQRequest(MODBUS_TIME_IRQn, 0, 0);

  61.     /* Enable MODBUS_TIME_PORT*/
  62.     DDL_TMR_EnableCounter(MODBUS_TIME_PORT);

  63.     return TRUE;
  64. }


  65. inline void vMBPortTimersEnable(  )
  66. {
  67.   /* Enable the timer with the timeout passed to xMBPortTimersInit( ) */
  68.         DDL_TMR_ClearFlag_UPDATE(MODBUS_TIME_PORT);
  69.         DDL_TMR_EnableIT_UPDATE(MODBUS_TIME_PORT);
  70.         DDL_TMR_SetCounter(MODBUS_TIME_PORT,0x00000000);
  71.         DDL_TMR_EnableCounter(MODBUS_TIME_PORT);
  72.                
  73. }

  74. inline void vMBPortTimersDisable(  )
  75. {   
  76.         DDL_TMR_ClearFlag_UPDATE(MODBUS_TIME_PORT);
  77.         DDL_TMR_DisableIT_UPDATE(MODBUS_TIME_PORT);
  78.         DDL_TMR_SetCounter(MODBUS_TIME_PORT,0x00000000);
  79.         DDL_TMR_DisableCounter(MODBUS_TIME_PORT);
  80. }

  81. /* Create an ISR which is called whenever the timer has expired. This function
  82. * must then call pxMBPortCBTimerExpired( ) to notify the protocol stack that
  83. * the timer has expired.
  84. */
  85. static void prvvTIMERExpiredISR( void )
  86. {
  87.     ( void )pxMBPortCBTimerExpired(  );
  88. }

  89. /*****************************************************************************
  90. *   函数名:MODBUS_TIME_PORT_IRQHandler
  91. *   功  能:定时器中断服务函数
  92. *   输  入:
  93. *          无
  94. *   输  出:
  95. *          无
  96. ****************************************************************************/

  97. void MODBUS_TIME_IRQHandler(void)
  98. {
  99. #if SYSTEM_SUPPORT_OS                 
  100.         OSIntEnter();   
  101. #endif
  102.    
  103.      if (DDL_TMR_IsActiveFlag_UPDATE(MODBUS_TIME_PORT) == SET)
  104.      {
  105.          DDL_TMR_ClearFlag_UPDATE(MODBUS_TIME_PORT);
  106.          prvvTIMERExpiredISR();
  107.      }
  108.      
  109. #if SYSTEM_SUPPORT_OS         
  110.         OSIntExit();                                                                                          
  111. #endif        
  112. }


  113. /* ----------------------- start implementation -----------------------------*/

  114. void vMBPortTimersDelay(USHORT usTimeOutMS)
  115. {
  116.     (void)usTimeOutMS;      // 避免编译器警告

  117.     // 如果只使用RTU模式,此函数无需任何操作
  118.     return;
  119. }
5.modbus控制GPIO点亮LED
  1. eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,eMBRegisterMode eMode )
  2. {
  3.     eMBErrorCode    eStatus = MB_ENOERR;
  4.     int             iNCoils = ( int )usNCoils;
  5.     unsigned short  usBitOffset;

  6.     /* Check if we have registers mapped at this block. */
  7.     if( ( usAddress >= REG_COILS_START ) && ( usAddress + usNCoils <= REG_COILS_START + REG_COILS_NREGS*8) )
  8.     {
  9.         usBitOffset = ( unsigned short )( usAddress - REG_COILS_START );
  10.         
  11.         switch ( eMode )
  12.         {
  13.                 /* Read current values and pass to protocol stack. */
  14.             case MB_REG_READ:
  15.                 while( iNCoils > 0 )
  16.                 {
  17.                     *pucRegBuffer++ = xMBUtilGetBits(ucRegCoilsBuf,usBitOffset,(unsigned char)( iNCoils >8 ? 8 :iNCoils ));
  18.                     iNCoils -= 8;
  19.                     usBitOffset += 8;
  20.                 }
  21.                
  22.                 break;

  23.                 /* Update current register values. */
  24.             case MB_REG_WRITE:
  25.                 while( iNCoils > 0 )
  26.                 {
  27.                     xMBUtilSetBits(ucRegCoilsBuf, usBitOffset, (unsigned char)(iNCoils > 8 ? 8:iNCoils),*pucRegBuffer++ );
  28.                     iNCoils -= 8;
  29.                     usBitOffset += 8;
  30.                 }
  31.                 uint8_t temp = ucRegCoilsBuf[0];
  32.                 ///////////////////////////////////////////////////
  33.                 //编写自己的逻辑代码
  34.                                                                 if(temp & 0x01)
  35.                                                                 {
  36.                                                                         DDL_GPIO_ResetOutputPin(GPIOA,DDL_GPIO_PIN_1);
  37.                                                                 }
  38.                                                                 else
  39.                                                                 {
  40.                                                                         DDL_GPIO_SetOutputPin(GPIOA,DDL_GPIO_PIN_1);
  41.                                                                 }
  42.                                                                
  43.                                                                 if((temp >> 1) &0x01)
  44.                                                                 {
  45.                                                                         DDL_GPIO_ResetOutputPin(GPIOA,DDL_GPIO_PIN_2);
  46.                                                                 }
  47.                                                                 else
  48.                                                                 {
  49.                                                                         DDL_GPIO_SetOutputPin(GPIOA,DDL_GPIO_PIN_2);
  50.                                                                 }
  51.                 /////////////////////////////////////////////////
  52.                 break;
  53.         }
  54.     }
  55.     else
  56.     {
  57.         eStatus = MB_ENOREG;
  58.     }
  59.    
  60.     return eStatus;
  61. }


三、测试
7573069fe0797a1ea7.png

lemonboard 发表于 2026-5-9 13:35 | 显示全部楼层
这么高级的MCU还使用单字节接收与处理的方式,是不是落后了呀
逆鳞风暴 发表于 2026-5-15 08:15 | 显示全部楼层
测试结果如何?LED的控制是否达到了预期的效果?期待看到更多的测试数据和性能分析。
 楼主| 袁胜富 发表于 2026-5-15 22:46 | 显示全部楼层
逆鳞风暴 发表于 2026-5-15 08:15
测试结果如何?LED的控制是否达到了预期的效果?期待看到更多的测试数据和性能分析。
...

达到了
LOVEEVER 发表于 2026-5-18 13:21 | 显示全部楼层
modnusRTU标准协议还是很开源的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

37

主题

186

帖子

2

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