打印
[应用相关]

STM32与labview 2019 组成的测控系统

[复制链接]
楼主: 東南博士
手机看帖
扫描二维码
随时随地手机跟帖
41
東南博士|  楼主 | 2019-9-4 16:41 | 只看该作者 回帖奖励 |倒序浏览
定义了寄存器的起始与数量!如果起始设定为1,则在上位机程序中测试的时候,就不要从0开始了!就容易出现问题!

使用特权

评论回复
42
東南博士|  楼主 | 2019-9-4 16:41 | 只看该作者
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs );
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode );
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode );
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete );

使用特权

评论回复
43
東南博士|  楼主 | 2019-9-4 16:41 | 只看该作者
四个解析函数!

使用特权

评论回复
44
東南博士|  楼主 | 2019-9-4 16:42 | 只看该作者
//******************************保持寄存器回调函数**********************************
//******************************输入寄存器回调函数**********************************
//****************************线圈状态寄存器回调函数********************************
//****************************离散输入寄存器回调函数********************************

使用特权

评论回复
45
東南博士|  楼主 | 2019-9-4 16:42 | 只看该作者
//******************************输入寄存器回调函数**********************************
//函数定义: eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
//描    述:输入寄存器相关的功能(读、连续读)
//入口参数:pucRegBuffer : 回调函数将Modbus寄存器的当前值写入的缓冲区
//                        usAddress    : 寄存器的起始地址,输入寄存器的地址范围是1-65535。
//                        usNRegs      : 寄存器数量
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;
    USHORT *        pusRegInputBuf;
    UCHAR           REG_INPUT_START;
    UCHAR           REG_INPUT_NREGS;
    UCHAR           usRegInStart;


    pusRegInputBuf = usSRegInBuf;
    REG_INPUT_START = S_REG_INPUT_START;
    REG_INPUT_NREGS = S_REG_INPUT_NREGS;
    usRegInStart = usSRegInStart;

    if( ( usAddress >= REG_INPUT_START )
            && ( usAddress + usNRegs <= REG_INPUT_START + REG_INPUT_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegInStart );
        while( usNRegs > 0 )
        {
            *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] >> 8 );
            *pucRegBuffer++ = ( unsigned char )( pusRegInputBuf[iRegIndex] & 0xFF );
            iRegIndex++;
            usNRegs--;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}

使用特权

评论回复
46
東南博士|  楼主 | 2019-9-4 16:42 | 只看该作者
//******************************保持寄存器回调函数**********************************
//函数定义: eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
//描    述:保持寄存器相关的功能(读、连续读、写、连续写)
//入口参数:pucRegBuffer : 如果需要更新用户寄存器数值,这个缓冲区必须指向新的寄存器数值。
//                         如果协议栈想知道当前的数值,回调函数必须将当前值写入这个缓冲区
//                        usAddress    : 寄存器的起始地址。
//                        usNRegs      : 寄存器数量
//          eMode        : 如果该参数为eMBRegisterMode::MB_REG_WRITE,用户的应用数值将从pucRegBuffer中得到更新。
//                         如果该参数为eMBRegisterMode::MB_REG_READ,用户需要将当前的应用数据存储在pucRegBuffer中
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;
       
       
    USHORT *        pusRegHoldingBuf;
    UCHAR           REG_HOLDING_START;
    UCHAR           REG_HOLDING_NREGS;
    UCHAR           usRegHoldStart;

    pusRegHoldingBuf = usSRegHoldBuf;
    REG_HOLDING_START = S_REG_HOLDING_START;
    REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
    usRegHoldStart = usSRegHoldStart;

    if( ( usAddress >= REG_HOLDING_START ) &&
            ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
    {
        iRegIndex = ( int )( usAddress - usRegHoldStart );
        switch ( eMode )
        {
        /* Pass current register values to the protocol stack. */
        case MB_REG_READ:
            while( usNRegs > 0 )
            {
                                                       
                *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] >> 8 );
                *pucRegBuffer++ = ( unsigned char )( pusRegHoldingBuf[iRegIndex] & 0xFF );
                iRegIndex++;
                usNRegs--;
            }
            break;

        /* Update current register values with new values from the
         * protocol stack. */
        case MB_REG_WRITE:
            while( usNRegs > 0 )
            {
                pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
                pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
                iRegIndex++;
                usNRegs--;
                                                       
                                                       
            }
            break;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
    return eStatus;
}

使用特权

评论回复
47
東南博士|  楼主 | 2019-9-4 16:42 | 只看该作者
//****************************线圈状态寄存器回调函数********************************
//函数定义: eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
//描    述:线圈状态寄存器相关的功能(读、连续读、写、连续写)
//入口参数:pucRegBuffer : 位组成一个字节,起始寄存器对应的位处于该字节pucRegBuffer的最低位LSB。
//                         如果回调函数要写这个缓冲区,没有用到的线圈(例如不是8个一组的线圈状态)对应的位的数值必须设置位0。
//                        usAddress    : 第一个线圈地址。
//                        usNCoils     : 请求的线圈个数
//          eMode        ;如果该参数为eMBRegisterMode::MB_REG_WRITE,用户的应用数值将从pucRegBuffer中得到更新。
//                         如果该参数为eMBRegisterMode::MB_REG_READ,用户需要将当前的应用数据存储在pucRegBuffer中
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex , iRegBitIndex , iNReg;
    UCHAR *         pucCoilBuf;
    UCHAR           COIL_START;
    UCHAR           COIL_NCOILS;
    UCHAR           usCoilStart;
    iNReg =  usNCoils / 8 + 1;        //占用寄存器数量

    pucCoilBuf = ucSCoilBuf;
    COIL_START = S_COIL_START;
    COIL_NCOILS = S_COIL_NCOILS;
    usCoilStart = usSCoilStart;

    if( ( usAddress >= COIL_START ) &&
            ( usAddress + usNCoils <= COIL_START + COIL_NCOILS ) )
    {
        iRegIndex    = ( int )( usAddress - usCoilStart ) / 8 ;    //每个寄存器存8个
        iRegBitIndex = ( int )( usAddress - usCoilStart ) % 8 ;           //相对于寄存器内部的位地址
        switch ( eMode )
        {
        /* Pass current coil values to the protocol stack. */
        case MB_REG_READ:
            while( iNReg > 0 )
            {
                *pucRegBuffer++ = xMBUtilGetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex , 8);
                iNReg --;
            }
            pucRegBuffer --;
            usNCoils = usNCoils % 8;                        //余下的线圈数
            *pucRegBuffer = *pucRegBuffer <<(8 - usNCoils); //高位补零
            *pucRegBuffer = *pucRegBuffer >>(8 - usNCoils);
            break;

        /* Update current coil values with new values from the
         * protocol stack. */
        case MB_REG_WRITE:
            while(iNReg > 1)                                                                         //最后面余下来的数单独算
            {
                xMBUtilSetBits(&pucCoilBuf[iRegIndex++] , iRegBitIndex  , 8 , *pucRegBuffer++);
                iNReg--;
            }
            usNCoils = usNCoils % 8;                            //余下的线圈数
            if (usNCoils != 0)                                  //xMBUtilSetBits方法 在操作位数量为0时存在bug
            {
                xMBUtilSetBits(&pucCoilBuf[iRegIndex++], iRegBitIndex, usNCoils,
                               *pucRegBuffer++);
            }
            break;
        }
    }
    else
    {
        eStatus = MB_ENOREG;
    }
    return eStatus;
}

使用特权

评论回复
48
東南博士|  楼主 | 2019-9-4 16:43 | 只看该作者
//****************************离散输入寄存器回调函数********************************
//函数定义: eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
//描    述:离散输入寄存器相关的功能(读、连续读)
//入口参数:pucRegBuffer : 用当前的线圈数据更新这个寄存器,起始寄存器对应的位处于该字节pucRegBuffer的最低位LSB。
//                         如果回调函数要写这个缓冲区,没有用到的线圈(例如不是8个一组的线圈状态)对应的位的数值必须设置为0。
//                        usAddress    : 离散输入的起始地址
//                        usNDiscrete  : 离散输入点数量
//出口参数:eMBErrorCode : 这个函数将返回的错误码
//备    注:Editor:Armink 2010-10-31    Company: BXXJS
//**********************************************************************************
eMBErrorCode
eMBRegDiscreteCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex , iRegBitIndex , iNReg;
    UCHAR *         pucDiscreteInputBuf;
    UCHAR           DISCRETE_INPUT_START;
    UCHAR           DISCRETE_INPUT_NDISCRETES;
    UCHAR           usDiscreteInputStart;
    iNReg =  usNDiscrete / 8 + 1;        //占用寄存器数量


    pucDiscreteInputBuf = ucSDiscInBuf;
    DISCRETE_INPUT_START = S_DISCRETE_INPUT_START;
    DISCRETE_INPUT_NDISCRETES = S_DISCRETE_INPUT_NDISCRETES;
    usDiscreteInputStart = usSDiscInStart;

    if( ( usAddress >= DISCRETE_INPUT_START )
            && ( usAddress + usNDiscrete <= DISCRETE_INPUT_START + DISCRETE_INPUT_NDISCRETES ) )
    {
        iRegIndex    = ( int )( usAddress - usDiscreteInputStart ) / 8 ;    //每个寄存器存8个
        iRegBitIndex = ( int )( usAddress - usDiscreteInputStart ) % 8 ;           //相对于寄存器内部的位地址
        while( iNReg > 0 )
        {
            *pucRegBuffer++ = xMBUtilGetBits(&pucDiscreteInputBuf[iRegIndex++] , iRegBitIndex , 8);
            iNReg --;
        }
        pucRegBuffer --;
        usNDiscrete = usNDiscrete % 8;                     //余下的线圈数
        *pucRegBuffer = *pucRegBuffer <<(8 - usNDiscrete); //高位补零
        *pucRegBuffer = *pucRegBuffer >>(8 - usNDiscrete);
    }
    else
    {
        eStatus = MB_ENOREG;
    }

    return eStatus;
}

使用特权

评论回复
49
東南博士|  楼主 | 2019-9-4 16:43 | 只看该作者
OK!基本上就配置完毕了!
在while 主函数中 这样写!先测试一下是否通讯正常!

使用特权

评论回复
50
東南博士|  楼主 | 2019-9-4 16:43 | 只看该作者
int main(void)
{

    Disable_JTAG_SWD();

    eMBInit(MB_RTU, 0x01, 1, 115200, MB_PAR_NONE);
    eMBEnable();

    ADCx_Init();

    while(1)
    {
        eMBPoll();//使能MODBUS
        usSRegHoldBuf[1]++;
        //
                usSRegHoldBuf[2]=1;
                usSRegHoldBuf[3]=2;
                usSRegHoldBuf[4]=3;
                usSRegHoldBuf[5]=4;
    }
}

使用特权

评论回复
51
東南博士|  楼主 | 2019-9-4 16:44 | 只看该作者
对于 hoding 寄存器,随便赋初值!

使用特权

评论回复
52
東南博士|  楼主 | 2019-9-4 16:44 | 只看该作者

使用特权

评论回复
53
東南博士|  楼主 | 2019-9-4 16:44 | 只看该作者
labview 编程的时候,确保串口打开之后,再读取!从寄存器1,对应读取5个寄存器的地址!

使用特权

评论回复
54
東南博士|  楼主 | 2019-9-4 16:45 | 只看该作者

读到一个数组,然后索引数组,得到的是:
        usSRegHoldBuf[1]++;
数据!

使用特权

评论回复
55
東南博士|  楼主 | 2019-9-4 16:46 | 只看该作者

使用特权

评论回复
56
東南博士|  楼主 | 2019-9-4 16:46 | 只看该作者
索引,这里没有写。默认是0.即可以读出数据!

使用特权

评论回复
57
東南博士|  楼主 | 2019-9-4 16:47 | 只看该作者
为什么是0呢?因为,我们读取数据的起始地址是从1开始的!
如果从0开始的话,就要修改单片机的起始寄存器地址。但是这样,可能会出现问题!默认从1开始比较好!

使用特权

评论回复
58
東南博士|  楼主 | 2019-9-4 16:48 | 只看该作者
是不是感觉很简单?这样就完成了一个最基本的modbus 的测控程序!另外,我们如果想配置数据该如何开发呢?

使用特权

评论回复
59
東南博士|  楼主 | 2019-9-4 16:49 | 只看该作者

使用特权

评论回复
60
東南博士|  楼主 | 2019-9-4 16:50 | 只看该作者

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则