发新帖我要提问
12
返回列表
打印
[应用相关]

STM32 上移植 FreeModbus RTU

[复制链接]
楼主: stm32jy
手机看帖
扫描二维码
随时随地手机跟帖
21
代码直接复制,这个是复制粘贴过来就有的功能吗?

使用特权

评论回复
22
sj8zw8| | 2020-2-27 20:21 | 只看该作者
我发不出来那种可以直接复制的,发出来格式就变了。

使用特权

评论回复
23
sj8zw8| | 2020-2-27 20:21 | 只看该作者

使用特权

评论回复
24
stm32jy|  楼主 | 2020-2-28 13:00 | 只看该作者
定时器中断服务函数 void TIM2_IRQHandler(void)
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
prvvTIMERExpiredISR();
}
}


使用特权

评论回复
25
stm32jy|  楼主 | 2020-2-28 13:01 | 只看该作者

高级工具里面有个 <>工具 ,放这里就行了

使用特权

评论回复
26
stm32jy|  楼主 | 2020-2-28 13:02 | 只看该作者
打开 port.h 文件,这个文件可以从\demo\BARE 文件夹下拷贝过来的



使用特权

评论回复
27
stm32jy|  楼主 | 2020-2-28 13:02 | 只看该作者
这是\demo\BARE 文件夹下原 port.h 文件的内容

使用特权

评论回复
28
stm32jy|  楼主 | 2020-2-28 13:03 | 只看该作者
在 port.h 文 件 补 充 完 成 以 下 两 个 函 数 ENTER_CRITICAL_SECTION( ) 和
EXIT_CRITICAL_SECTION( ),这两个函数跟中断有关,开或者关中断。

使用特权

评论回复
29
stm32jy|  楼主 | 2020-2-28 13:04 | 只看该作者
以下是工程项目文件夹下修改后的 port.h 文件内容

使用特权

评论回复
30
stm32jy|  楼主 | 2020-2-28 13:04 | 只看该作者
分别完善以下 4 个回调函数
4.3.1、操作输入寄存器 eMBErrorCode eMBRegInputCB( UCHAR * pucRegBuffer,
USHORT usAddress, USHORT usNRegs )
4.3.2、操作保持寄存器 eMBErrorCode eMBRegHoldingCB( UCHAR * pucRegBuffer,
USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
4.3.3、操作线圈 eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT
usAddress, USHORT usNCoils, eMBRegisterMode eMode )4.3.4、操作离散寄存器 eMBErrorCode eMBRegDiscreteCB( UCHAR * pucRegBuffer,
USHORT usAddress, USHORT usNDiscrete )

使用特权

评论回复
31
stm32jy|  楼主 | 2020-2-28 13:06 | 只看该作者
第一次编译报错,删除porttimer.c 中定时器使能和失能函数前的inline 字样。

使用特权

评论回复
32
stm32jy|  楼主 | 2020-2-28 13:06 | 只看该作者
再次编译,出现关于assert的错误

使用特权

评论回复
33
stm32jy|  楼主 | 2020-2-28 13:07 | 只看该作者
在主函数下面添加以下代码,即可解决以上问题,编译无误后开始添加测试代码来测试移植的FreeModbus是否成功。
#ifdef  USE_FULL_ASSERT
/**
  * [url=home.php?mod=space&uid=247401]@brief[/url]  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */  
void assert_failed(uint8_t* file, uint32_t line)  
{  
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */  
   
  /* Infinite loop */  
  while (1)  
  {  
  }  
}
#else
void __aeabi_assert(const char * x1, const char * x2, int x3)
{
}


使用特权

评论回复
34
stm32jy|  楼主 | 2020-2-28 13:07 | 只看该作者
若想使用FreeModbus,先对FreeModbus进行初始化,需要调用eMBInit函数和eMBEnable函数,eMBInit函数函数是设置硬件的,有五个参数,分别是01.Modbus的模式:这里可以选择RTUASCIITCP02.设备的地址:这里可以直接写死,也可以通过拨码开关来设置;03.Modbus选择的串口号,这里默认是串口204.波特率,默认写11520005.校验位,默认不效验。然后在主循环中调用eMBPoll函数不断查询。主函数具体如下:
int main(void)
{       
        delay_init();            //延时函数初始化                   
//初始化 RTU模式 从机地址为1 USART2 9600 无效验
eMBInit(MB_RTU, 0x01, 0x02, 9600, MB_PAR_NONE);
//启动FreeModbus
eMBEnable();
        while(1)
        {               
         //FreeMODBUS不断查询
    eMBPoll();
        }
}



使用特权

评论回复
35
stm32jy|  楼主 | 2020-2-28 13:08 | 只看该作者
添加测试代码部分,实现寄存器的读写操作,这里添加了一组寄存器的数据,和对其读写操作的函数
//Modbus 进程函数
void Modbus_app()
{
  ( void ) eMBPoll( );
}


使用特权

评论回复
36
stm32jy|  楼主 | 2020-2-28 13:09 | 只看该作者
添加输入寄存器、保持寄存器、线圈的起始地址和定义的内容,具体如下
/* ----------------------- Defines ------------------------------------------*/
//保持寄存器起始地址
#define REG_HOLDING_START 0x0001
//保持寄存器数量
#define REG_HOLDING_NREGS 8
//保持寄存器内容
uint16_t usRegHoldingBuf[REG_HOLDING_NREGS] = {0x147b,0x3f8e,0x147b,0x400e,0x1eb8,0x4055,0x147b,0x408e};

//输入寄存器起始地址
#define REG_INPUT_START 0x0001
//输入寄存器数量
#define REG_INPUT_NREGS 8
//输入寄存器内容
uint16_t usRegInputBuf[REG_INPUT_NREGS] = {0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,0x7777,0x8888};

//线圈寄存器起始地址
#define REG_COILS_START 0x0001
//线圈寄存器数量
#define REG_COILS_SIZE 16
//线圈寄存器内容
uint8_t ucRegCoilsBuf[REG_COILS_SIZE/8] = {0x00,0xFF};


使用特权

评论回复
37
stm32jy|  楼主 | 2020-2-28 13:09 | 只看该作者
添加输入寄存器、保持寄存器、线圈的处理函数,具体如下:
// 保持寄存器的读写函数 支持的命令为读 0x03 和写0x06 可读可写  
eMBErrorCode
eMBRegHoldingCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs,eMBRegisterMode eMode )
{
  //错误状态
  eMBErrorCode eStatus = MB_ENOERR;
  //偏移量
  int16_t iRegIndex;
  
        //判断寄存器是不是在范围内
  if( ( (int16_t)usAddress >= REG_HOLDING_START )&& ( usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS ) )
  {
    //计算偏移量
    iRegIndex = ( int16_t )( usAddress - REG_HOLDING_START);
    switch ( eMode )
   {
     //读处理函数
      case MB_REG_READ:
                                        while( usNRegs > 0 )
                                        {
                                                *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] >> 8 );
                                                *pucRegBuffer++ = ( uint8_t )( usRegHoldingBuf[iRegIndex] & 0xFF );
                                                iRegIndex++;
                                                usNRegs--;
                                        }
                        break;

    //写处理函数
     case MB_REG_WRITE:
                                        while( usNRegs > 0 )
                                        {
                                                usRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
                                                usRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
                                                iRegIndex++;
                                                usNRegs--;
                                        }
                 break;
  }
}
else
{
//返回错误状态
eStatus = MB_ENOREG;
}

return eStatus;
}

//读输入寄存器函数 支持的命令为读 0x04
eMBErrorCode
eMBRegInputCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNRegs )
{
    eMBErrorCode    eStatus = MB_ENOERR;
    int             iRegIndex;

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

    return eStatus;
}

//线圈处理函数 可读可写 支持的命令为读 0x01 0x05
eMBErrorCode
eMBRegCoilsCB( UCHAR * pucRegBuffer, USHORT usAddress, USHORT usNCoils,
               eMBRegisterMode eMode )
{
    //错误状态
    eMBErrorCode eStatus = MB_ENOERR;
    //寄存器个数
    int16_t iNCoils = ( int16_t )usNCoils;
    //寄存器偏移量
    int16_t usBitOffset;

   //判断寄存器是不是在范围内
   if( ( (int16_t)usAddress >= REG_COILS_START ) &&( usAddress + usNCoils <= REG_COILS_START + REG_COILS_SIZE ) )
   {
     //计算寄存器偏移量
     usBitOffset = ( int16_t )( usAddress - REG_COILS_START );
     switch ( eMode )
     {
                                //读操作
                                case MB_REG_READ:
                                                while( iNCoils > 0 )
                                                {
                                                        *pucRegBuffer++ = xMBUtilGetBits( ucRegCoilsBuf, usBitOffset,
                                                        ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ) );
                                                        iNCoils -= 8;
                                                        usBitOffset += 8;
                                                }
                          break;

                                //写操作
                                case MB_REG_WRITE:
                                                while( iNCoils > 0 )
                                                {
                                                        xMBUtilSetBits( ucRegCoilsBuf, usBitOffset,
                                                        ( uint8_t )( iNCoils > 8 ? 8 : iNCoils ),
                                                        *pucRegBuffer++ );
                                                        iNCoils -= 8;
                                                }
                                break;
    }
  }
        else
        {
           eStatus = MB_ENOREG;
        }
        return eStatus;
               
return MB_ENOREG;
}


使用特权

评论回复
38
stm32jy|  楼主 | 2020-2-28 13:10 | 只看该作者
本次成功的在STM32平台上移植了FreeModbus ,可以通过ModbusPoll工具进行测试

使用特权

评论回复
39
molo| | 2020-9-4 16:52 | 只看该作者
不错,能上传个源码工程下载吗?

使用特权

评论回复
40
星空520| | 2021-2-23 09:56 | 只看该作者
stm32jy 发表于 2020-2-28 13:10
本次成功的在STM32平台上移植了FreeModbus ,可以通过ModbusPoll工具进行测试

你这个测试软件能共享一下吗?

使用特权

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

本版积分规则