查看: 3055|回复: 6

[原创] 【正点原子-号令者】【08-Modbus-RTU协议】

[复制链接]
  • TA的每日心情
    开心
    2024-4-7 13:52
  • 签到天数: 326 天

    连续签到: 1 天

    [LV.8]以坛为家I

    发表于 2018-8-8 22:24:45 | 显示全部楼层 |阅读模式
    分享到:
    看了两个礼拜的国标,前两天在32 上面实现了,今天移植到RT1052上来,费了不少时间,也算给自己一个交代了哈哈哈,先上图!!证明Modbus-RTU 是调试通过了的。

    Modbuschenggong.png

    还是按照原来的风格来文末附代码!

    首先在Modbus-RTU 的国标中抠出CRC校验的函数,分别分为.c和.h两个文件这里 就直接附代码了,
    《这里是直接使用FreeModbus 协议栈里面的代码---》


    1. /*
    2. * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
    3. * Copyright (c) 2006 Christian Walter <wolti@sil.at>
    4. * All rights reserved.
    5. *
    6. * Redistribution and use in source and binary forms, with or without
    7. * modification, are permitted provided that the following conditions
    8. * are met:
    9. * 1. Redistributions of source code must retain the above copyright
    10. *    notice, this list of conditions and the following disclaimer.
    11. * 2. Redistributions in binary form must reproduce the above copyright
    12. *    notice, this list of conditions and the following disclaimer in the
    13. *    documentation and/or other materials provided with the distribution.
    14. * 3. The name of the author may not be used to endorse or promote products
    15. *    derived from this software without specific prior written permission.
    16. *
    17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27. *
    28. * File: $Id: mbcrc.c,v 1.7 2007/02/18 23:50:27 wolti Exp $
    29. */

    30. #include "mbcrc.h"
    31. static const unsigned char  aucCRCHi[] = {
    32.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    33.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    34.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    35.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    36.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    37.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    38.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    39.     0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    40.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    41.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    42.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    43.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    44.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    45.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    46.     0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    47.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    48.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    49.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
    50.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    51.     0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
    52.     0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
    53.     0x00, 0xC1, 0x81, 0x40
    54. };

    55. static const unsigned char  aucCRCLo[] = {
    56.     0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
    57.     0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
    58.     0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
    59.     0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
    60.     0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
    61.     0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
    62.     0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
    63.     0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
    64.     0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
    65.     0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
    66.     0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
    67.     0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
    68.     0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
    69.     0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
    70.     0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
    71.     0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
    72.     0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
    73.     0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
    74.     0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
    75.     0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
    76.     0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
    77.     0x41, 0x81, 0x80, 0x40
    78. };
    79. /*-----------------------*/
    80. unsigned short  usMBCRC16( unsigned char  * pucFrame, unsigned short   usLen )
    81. {
    82.     unsigned char            ucCRCHi = 0xFF;
    83.     unsigned char            ucCRCLo = 0xFF;
    84.     int             iIndex;

    85.     while( usLen-- )
    86.     {
    87.         iIndex = ucCRCLo ^ *( pucFrame++ );
    88.         ucCRCLo = ( unsigned char  )( ucCRCHi ^ aucCRCHi[iIndex] );
    89.         ucCRCHi = aucCRCLo[iIndex];
    90.     }
    91.     return ( unsigned short  )( ucCRCHi << 8 | ucCRCLo );
    92. }












    93. /*---------------------------------  end  of  the  files        -- 小申 ---------------------*/
    复制代码



    头文件里面包含的也比较少,只有那个
    1. /*
    2. * FreeModbus Libary: A portable Modbus implementation for Modbus ASCII/RTU.
    3. * Copyright (c) 2006 Christian Walter <wolti@sil.at>
    4. * All rights reserved.
    5. *
    6. * Redistribution and use in source and binary forms, with or without
    7. * modification, are permitted provided that the following conditions
    8. * are met:
    9. * 1. Redistributions of source code must retain the above copyright
    10. *    notice, this list of conditions and the following disclaimer.
    11. * 2. Redistributions in binary form must reproduce the above copyright
    12. *    notice, this list of conditions and the following disclaimer in the
    13. *    documentation and/or other materials provided with the distribution.
    14. * 3. The name of the author may not be used to endorse or promote products
    15. *    derived from this software without specific prior written permission.
    16. *
    17. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
    18. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
    19. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    20. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
    21. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
    22. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    23. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    24. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
    26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    27. *
    28. * File: $Id: mbcrc.h,v 1.5 2006/12/07 22:10:34 wolti Exp $
    29. */

    30. #ifndef _MB_CRC_H
    31. #define _MB_CRC_H


    32. unsigned short          usMBCRC16( unsigned char  * pucFrame, unsigned short  usLen );

    33. #endif
    复制代码



    Modbus-RTU 的结束标志是3.5T的时间内没有接收到数据就代表数据接收完成,所以我们这里的定时器设置为1us中断一次,方便Modbus-RTU 计算协议结束的标志,这也是国标上的指导做法。
    整个数据的接收在串口中断中进行,第一次接收到中断就打开定时器,第二次接收到数据就将计数器清零-这样才能保证3.5T 的数据时真实有效的,当接收的计时超过3.5T的时候就将接收结束标志位置1 这样处理函数才知道我这一个Modbus帧接收完了,可以进行处理了
    下面贴上定时器的处理代码----

    1. #include "TIM.h"
    2. #include "Modbus.h"
    3. int count=0;
    4. //--定义1us 中断一次----
    5. void TIM_X_Init(void)
    6. {
    7.   gpt_config_t gpt1_onfig;
    8.         GPT_GetDefaultConfig(&gpt1_onfig);        //先初始化GPT1为默认值
    9.         gpt1_onfig.clockSource=  kGPT_ClockSource_Periph;        //初始化时钟源perclk_clk_root
    10.         gpt1_onfig.divider=75-1;                //设置分频值--取值范围:1-4096
    11.         GPT_Init(GPT1,&gpt1_onfig);
    12.         //
    13.         GPT_SetOutputCompareValue(GPT1,kGPT_OutputCompare_Channel1,1);            //设置比较计数值
    14.         GPT_EnableInterrupts(GPT1,kGPT_OutputCompare1InterruptEnable);                        //使能GPT比较通道1中断
    15.         NVIC_SetPriority(GPT1_IRQn,1);
    16.         EnableIRQ(GPT1_IRQn);        //使能GPT1中断
    17.         GPT_StopTimer(GPT1);        //关闭定时器---        

    18. }

    19. //GPT1中断服务函数
    20. void GPT1_IRQHandler(void)
    21. {
    22.     //OCR1中断
    23.     if(GPT_GetStatusFlags(GPT1,kGPT_OutputCompare1Flag))
    24.     {
    25.                                 GPT_ClearStatusFlags(GPT1,kGPT_OutputCompare1Flag);//清除中断标志位
    26.                                 MB_Uart4.T35_Count++;
    27.                                 if(MB_Uart4.T35_Count>MB_Uart4.T35)//--3.5T 时间到了 ----
    28.                                 {
    29.                                                 // 发送结束标志位--
    30.                                                 MB_Uart4.T35_Count=0;//--clear the count data
    31.                                                 MB_Uart4.RxEndFlag=1;//--接收标志位设置为1 -表示接收数据完成
    32.                                                 //--添加关闭时钟--
    33.                                         GPT_StopTimer(GPT1);
    34.                                 }
    35.     }
    36. }










    复制代码
    在整个处理过程中,均按照Modbus国标做指导完成,下面就是今天最核心的东西,Modbus-RTU 处理函数,在代码中做了详细的介绍,所以这里就不多做介绍了,将来肯定用得到的,哈哈哈。

    1. #include "SystemIncludes.h"
    2. #include "Modbus.h"
    3. ModbusDatastruct MB_Uart4;

    4. unsigned short REG_Data[50]={0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,
    5. 0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,
    6. 0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,
    7. 0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,
    8. 0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55,0xaa55};

    9. void MB_InitData(unsigned char Station_ADDR)
    10. {
    11. int i=0;
    12.         
    13.   MB_Uart4.MB_Addr=Station_ADDR;//--站号
    14.         MB_Uart4.DataSourse=4;//--信号源为串口四
    15.         MB_Uart4.MB_RxData_Len=0;
    16.         MB_Uart4.MB_TxData_Len=0;
    17.         MB_Uart4.RxDataFlag=0;
    18.         MB_Uart4.RxEndFlag=0;
    19.         MB_Uart4.RxStartFlag=0;
    20.         MB_Uart4.SendFlag=0;
    21.         MB_Uart4.T35=90;
    22.         MB_Uart4.T35_Count=0;
    23.         for(i=0;i<256;i++)
    24.         {
    25.           MB_Uart4.MB_RxData[i]=0;
    26.                 MB_Uart4.MB_TxData[i]=0;
    27.         }
    28. }





    29. unsigned short        ReadMultReg_03(unsigned char *Buffer,unsigned short StartAddr,unsigned short Length)//--读取函数 :数据存储介质--  起始地址 ------ 以及数量--
    30. {
    31.                         unsigned char  i=0,j=0;
    32.                         CopyBoard CopyData;  //中间变量存储--
    33.                         unsigned char  *DataAddr;  //**
    34.                         CopyData.DataByteNum=Length*2;//--读取字节变量的数量--由于读取寄存器是16位的,而这里是按照字节处理的-所以要*2
    35.                         CopyData.ReturnDataLength=Length*2;//--返回数据的长度----
    36.                         CopyData.StartBytePosition=StartAddr;//--起始地址--
    37. //                        DataAddr=(unsigned char *)&AI_AO_Data[CopyData.StartBytePosition];
    38.                         //--开始拷贝数据----
    39.                  for (i=0;i<Length;i++)
    40.                                 {//--
    41.                                           Buffer[2*i]=((REG_Data[i+StartAddr]>>8)&0xff);//--复制数据--
    42.                                           Buffer[2*i+1]=(REG_Data[i+StartAddr]&0xff);
    43.                                 }
    44.       return CopyData.ReturnDataLength;//--返回拷贝的字节数量----
    45. }

    46. void ModbusProscess(ModbusDatastruct *MB)
    47. {
    48.                 unsigned short  CRC_Data=0;
    49.           unsigned int i=0;
    50.                 unsigned short RTN_DataLen=0;//--函数返回的获取到的字符的长度----
    51.                 unsigned int DataLimit=0;
    52.                 MB->SendFlag=0;
    53. //          MB.ProtocalStr.CRCData=MB.MB_RxData[MB_CRC_H]<<8|MB.MB_RxData[MB_CRC_L];
    54. //         //--开始计算CRC--
    55. //        //--在这里进行数据处理----
    56.                 MB->ProtocalStr.Addr=MB->MB_RxData[MB_Addr];
    57.                 MB->ProtocalStr.FunCode=MB->MB_RxData[MB_FunCode];
    58.                 MB->ProtocalStr.MB_StartAddr=MB->MB_RxData[MB_StartAddr]<<8|MB->MB_RxData[MB_StartAddr+1];
    59. //                MB->ProtocalStr.MB_DataNum=MB->MB_RxData[MB_DataNum]<<8|MB->MB_RxData[MB_DataNum+1];
    60.           MB->ProtocalStr.CRCData=MB->MB_RxData[MB->MB_RxData_Len-1]<<8|MB->MB_RxData[MB->MB_RxData_Len-2];//--填入CRC数值--

    61.   CRC_Data=usMBCRC16(MB->MB_RxData,MB->MB_RxData_Len-2);//--从站只是接受命令,所以长度固定----
    62.         if(CRC_Data==MB->ProtocalStr.CRCData)//--如果CRC 校验过了 就可以继续下面的数据处理了----
    63.         {
    64.                 //--        首先将数据整理到结构体中--此处应当还需要判断是读还是写--
    65.                 if(MB->ProtocalStr.Addr==MB->MB_Addr)//--判断Modbus地址是否为本机地址----
    66.                 {
    67.                     //--是否是支持的功能码----
    68.                                 if((MB->ProtocalStr.FunCode<5)&&(MB->ProtocalStr.FunCode>2))//--判断功能码是否有效----
    69.                                 {
    70.                                         switch (MB->ProtocalStr.FunCode)
    71.                                         {
    72.                                                 

    73.                                                 case ReadMultRegister :    //--功能码:03   -- 读多个寄存器----
    74.                                                                 {
    75.                        MB->ProtocalStr.MB_DataNum=MB->MB_RxData[MB_DataNum]<<8|MB->MB_RxData[MB_DataNum+1];
    76.                              MB->ProtocalStr.CRCData=MB->MB_RxData[MB->MB_RxData_Len-1]<<8|MB->MB_RxData[MB->MB_RxData_Len-2];//--填入CRC数值--
    77.                                                                                        
    78.                                                                                         //--进入这里,说明地址和功能码都满足了,现在需要做的事判断输出数量是否在规定范围内--
    79.                                                                             //--IO数量的计算应当从起始地址+数量来计算--如果起始地址加上数量之后大于IO的点数,
    80.                                                                             //--此时应当报错处理--
    81.                                                                                         DataLimit=MB->ProtocalStr.MB_StartAddr + MB->ProtocalStr.MB_DataNum;//--起始地址+读取数量---
    82.                                                                                         if((DataLimit>=1)&&(DataLimit<MaxiunReadREG_Data))
    83.                                                                                         {
    84.                                                                                          
    85.                                                                                                                 MB->MB_TxData[TX_MB_Addr]=MB->MB_RxData[MB_Addr];//--填充站号---
    86.                                                                                                                 MB->MB_TxData[TX_MB_FunCode]=MB->MB_RxData[MB_FunCode];//--填充功能码--
    87.                                                                                                                 //--读取线圈的函数----unsigned short        ReadMultReg_03(u8 *Buffer,unsigned short StartAddr,unsigned short Length)
    88.                                                                                                                 RTN_DataLen=ReadMultReg_03(&MB->MB_TxData[TX_MB_DataBase],MB->ProtocalStr.MB_StartAddr,MB->ProtocalStr.MB_DataNum);
    89.                                                                                                                 //--填充字节数--
    90.                                                                                                                 MB->MB_TxData[TX_MB_TxNum]=(unsigned char )(RTN_DataLen&0xff); //--填充字节数--
    91.                                                                                                                 //--开始填充数据--
    92.                                                                                                                 //计算CRC---校验和----校验是按照从包头开始 -- 一直到数据结束---
    93.                                                                                                                 CRC_Data=usMBCRC16( MB->MB_TxData, RTN_DataLen+3 );//--计算CRC的数值
    94.                                                                                        
    95.                                                                                                                 RTN_DataLen=RTN_DataLen+5;  //--这里是包含了CRC校验的----站号 +功能码 +数量+CRCData*2=5
    96.                                                                                                     MB->MB_TxData_Len=RTN_DataLen;//--传入带发送的字节长度--
    97.                                                                                                                 MB->MB_TxData[RTN_DataLen-2]=(CRC_Data&0xff);  //--CRC-H
    98.                                                                                                                 MB->MB_TxData[RTN_DataLen-1]=((CRC_Data>>8)&0xff);  //--CRC-L
    99.                                                                                                                 //        完成数据包的组包
    100.                                                                                                                 //--        发送标志----
    101.                                                                                                                 MB->SendFlag=1;
    102.                                                                                         }
    103.                                                                                         else/*--说明--超出范围了---应当返回异常码------  --*/
    104.                                                                                         {
    105.                                                                                                   MB->MB_TxData[MB_Addr]=(0x80+ MB->MB_RxData[MB_FunCode]);//--填充站号--
    106.                           MB->MB_TxData[MB_FunCode]=MB_ERR_Output_Outof_RangeNum;//--填充功能码--错误码--               
    107.                                                                                                   MB->MB_TxData_Len=2;
    108.                                                                                                   MB->SendFlag=1;
    109.                                                                                         }
    110.                                                                 }
    111.                                                                 break ;
    112.                                                                 //--
    113.                                                 case ReadinputRegister :   //--功能码:04   -- 读输入寄存器----
    114.                                                                 {
    115.                                                                
    116.                                                                 }
    117.                                                                 break ;
    118.                                         }
    119.                  //--清除标接收缓冲区的数据
    120.                                         MB->MB_RxData_Len=0;
    121.                                         MB->RxStartFlag=0;
    122.                                         MB->RxEndFlag=0;
    123.                                         for(i=0;i<256;i++)
    124.                                                 {
    125.                                                    MB->MB_RxData[i]=0;
    126.                                                 }                        
    127.                                 }
    128.                                 else  //--说明功能码不在可用的范围内--应当返回的 0x80 + 功能码  为地址的数据---
    129.                                 {
    130.                                        
    131.                                         for(i=0;i<256;i++)
    132.                                         {
    133.                                                 MB->MB_TxData[i]=0;
    134.                                                 MB->MB_RxData[i]=0;
    135.                                         }
    136.                                         MB->RxEndFlag=0;
    137.                                         MB->RxStartFlag=0;
    138.                                                         MB->MB_TxData[MB_Addr]=(0x80+ MB->MB_RxData[MB_FunCode]);//--填充站号--
    139.                                                         MB->MB_TxData[MB_FunCode]=MB_ERR_UnsupportedFuncode;//--填充功能码--                                
    140.                                 }        
    141.         //--此处添加发送函数
    142.                                         switch(MB->DataSourse)
    143.                                         {
    144.                                                 case 1 :
    145.                                                 {
    146.                                                 }break;
    147.                                         case 2 :
    148.                                                 {
    149.                                                 }break;
    150.                                         case 3 :
    151.                                                 {
    152.                                                 }break;
    153.                                                 
    154.                                                 case 4 :/*--串口4--*/
    155.                                                 {
    156.                                                          if(MB->SendFlag==1)
    157.                                                                 {
    158.                                                                         MB->SendFlag=0;//--清除发送标志位
    159.                                                                   MB->RxStartFlag=0;
    160.                                                                         for(i=0;i<MB->MB_TxData_Len;i++)
    161.                                                                         {
    162.                                                                                         UART_SendChar(LPUART4,MB->MB_TxData[i]);
    163.                                                                         }
    164.                                                                         //--发送完成之后-清除数据区
    165.                                                                         //--清除标志位--
    166.                                                                         for(i=0;i<256;i++)
    167.                                                                                 {
    168.                                                                                   MB->MB_TxData[i]=0;
    169.                                                                                         MB->MB_RxData[i]=0;
    170.                                                                                 }
    171.                                                                 }
    172.                                                 }break;
    173.                                         }
    174.                 }
    175.                 else/*--站号不是本机的站号---*/
    176.                 {
    177.                
    178.                 }
    179. }

    180.                         for(i=0;i<256;i++)
    181.                                 {
    182.                                         MB->MB_TxData[i]=0;
    183.                                         MB->MB_RxData[i]=0;
    184.                                 }
    185.                                 MB->RxEndFlag=0;
    186.                                 MB->RxStartFlag=0;
    187. }



























    复制代码


    好啦!今天的分享就到这里,对大家肯定有帮助!!!!!!!!!!!!

    //============================================================
    Modbus-RTU: RT1052-Demo-Modbus.rar (922.74 KB, 下载次数: 8, 售价: 5 与非币)
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-8 08:37
  • 签到天数: 92 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2022-2-26 10:11:00 | 显示全部楼层
    为啥不能下载啊。。。。。。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-8 08:37
  • 签到天数: 92 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2022-3-1 07:31:33 | 显示全部楼层
    特定用户?才能下载
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-8 08:37
  • 签到天数: 92 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2022-3-11 18:14:49 | 显示全部楼层
    顶顶,期待能下载的
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-8 08:37
  • 签到天数: 92 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2023-2-8 16:59:03 | 显示全部楼层
    大哥,可以把下载权限放低点吗?70.。。有生之年
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-8 08:37
  • 签到天数: 92 天

    连续签到: 1 天

    [LV.6]常住居民II

    发表于 2023-2-8 17:00:01 | 显示全部楼层
    刚看见可以下载啦!谢谢UP主!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-5-20 17:46 , Processed in 0.155844 second(s), 28 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.