OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8915|回复: 7

在freertos系统中使用modbus rtu和裸机程序中有区别吗

[复制链接]

6

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2019-1-25
在线时间
17 小时
发表于 2019-2-28 15:29:40 | 显示全部楼层 |阅读模式
5金钱
我将裸机程序中的modbus rtu从机程序,移植到freemodbus中。发现程序并没有成功的实现功能。

modbus从机使用了一个硬件定时器,和一个串口。
串口使用接收中断,硬件定时器来判断一帧数据是否结束。然后在程序中不断调用 RS485_Service()函数,实现modbus485从机功能。
裸机程序是已经使用很长时间的稳定程序,一直都工作正常。


移植到freertos中,程序没有报错,但是实际程序功能并没有实现。
int main(void)
{
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4       
     delay_init();                                            //延时函数初始化       
     Start_Init();           //信号点初始化LED
    //创建任务
     AppTaskCreate();
    //启动调度,开始执行任务
    vTaskStartScheduler();

}

void AppTaskCreate (void)
{
            taskENTER_CRITICAL();           //进入临界区
       
        xTaskCreate( Modbus485_task,                    /* 任务函数  */
                 "Modbus485_task",                  /* 任务名    */
                 256,                         /* stack大小,单位word,也就是4字节 */
                 NULL,                        /* 任务参数  */
                 4,                           /* 任务优先级*/
                 &Modbus485Task_Handler ); /* 任务句柄  */
       
        xTaskCreate( led1_task,                     /* 任务函数  */
                 "led1_task",                   /* 任务名    */
                 50,                            /* 任务栈大小,单位word,也就是4字节 */
                 NULL,                           /* 任务参数  */
                 3,                              /* 任务优先级*/
                 &LED1Task_Handler );   /* 任务句柄  */               
                                                                 
                                                                 
        xTaskCreate( led0_task,                     /* 任务函数  */
                                                         "led0_task",                   /* 任务名    */
                                                         50,                            /* 任务栈大小,单位word,也就是4字节 */
                                                         NULL,                           /* 任务参数  */
                                                         2,                              /* 任务优先级*/
                                                         &LED0Task_Handler );   /* 任务句柄  */                                                                         
       
        taskEXIT_CRITICAL();            //退出临界区                                         
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
}




正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2019-1-25
在线时间
17 小时
 楼主| 发表于 2019-2-28 15:31:52 | 显示全部楼层
//LED0任务函数
void led0_task(void *pvParameters)
{
    while(1)
    {
                                CHR=~CHR;                       
        vTaskDelay(500);
    }
}


//LED1任务函数
void led1_task(void *pvParameters)
{
    while(1)
    {
        DCHR=0;
        vTaskDelay(200);
        DCHR=1;
        vTaskDelay(800);

    }
}

//485通讯任务/////////////////////////////////////////////////////////////////////////////////
void Modbus485_task(void *pvParameters)
{
                RS485_Init();
    while(1)
    {                       
                        RS485_Service();
                        LED2=!LED2;       
                        vTaskDelay(50);
    }
}
回复

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14286
金钱
14286
注册时间
2018-8-3
在线时间
1147 小时
发表于 2019-2-28 15:45:57 | 显示全部楼层
帮顶!!
回复

使用道具 举报

6

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
64
金钱
64
注册时间
2019-1-25
在线时间
17 小时
 楼主| 发表于 2019-2-28 16:03:59 | 显示全部楼层
移植到freertos中,可以看到几个led灯都正确的动作了,说明几个任务都执行了。

但是modbus从机程序不正常了,没有反应
回复

使用道具 举报

51

主题

2165

帖子

2

精华

论坛元老

Rank: 8Rank: 8

积分
10652
金钱
10652
注册时间
2017-4-14
在线时间
2780 小时
发表于 2019-2-28 17:48:31 | 显示全部楼层
本帖最后由 nashui_sx 于 2019-2-28 17:50 编辑

有问题一般都是portevent估计    freemodbus从机带不带系统没影响     主机portevent_m要改成带系统的 或者不带系统的 反正要移植几个函数
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-27 13:40:21 | 显示全部楼层
移植 FreeMODBUS 需要修改的源文件

(1)、移植FreeMODBUS需要修改DEMO\BARE文件夹demo.c文件内容
demo.c文件中的4个回调函数的内容需要拷贝到工程项目中,4个回调函数具体如下:  
(1.1)、操作输入寄存器的回调函数 eMBErrorCode eMBRegInputCB( UCHAR *
pucRegBuffer, USHORT usAddress, USHORT usNRegs )
(1.2)、操作保持寄存器的回调函数 eMBErrorCode eMBRegHoldingCB( UCHAR *
pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode )
(1.3)、操作线圈的回调函数eMBErrorCode eMBRegCoilsCB( UCHAR * pucRegBuffer,
USHORT usAddress, USHORT usNCoils, eMBRegisterMode eMode )
(1.4)、操作离散寄存器的回调函数 eMBErrorCode eMBRegDiscreteCB( UCHAR *
pucRegBuffer, USHORT usAddress, USHORT usNDiscrete )

(2)、移植FreeMODBUS需要修改DEMO\BARE\port 文件夹以下文件内容:
(2.1)、需要修改port.h
(2.2)、需要修改portserial.c  
(2.3)、需要修改porttimer.c
(3)、移植FreeMODBUS需要修改\modbus\rtu\mbrtu.c
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-27 13:41:06 | 显示全部楼层
port.h

/*
* FreeModbus Libary: MSP430 Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
* File: $Id: port.h,v 1.2 2006/11/19 03:36:01 wolti Exp $
*/

#ifndef _PORT_H
#define _PORT_H

/* ----------------------- Platform includes --------------------------------*/

#include "stm32f4xx.h"
#if defined (__GNUC__)
#include <signal.h>
#endif
#undef CHAR

/* ----------------------- Defines ------------------------------------------*/
#define        INLINE
#define PR_BEGIN_EXTERN_C           extern "C" {
#define        PR_END_EXTERN_C             }

#define ENTER_CRITICAL_SECTION( )   __disable_irq();
#define EXIT_CRITICAL_SECTION( )    __enable_irq();
#define assert( expr )

typedef char    BOOL;
typedef unsigned char UCHAR;
typedef char    CHAR;
typedef unsigned short USHORT;
typedef short   SHORT;
typedef unsigned long ULONG;
typedef long    LONG;

#ifndef TRUE
#define TRUE            1
#endif

#ifndef FALSE
#define FALSE           0
#endif

#endif
回复

使用道具 举报

19

主题

334

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1108
金钱
1108
注册时间
2018-11-6
在线时间
240 小时
发表于 2019-12-27 13:42:00 | 显示全部楼层
portserial.c

/*
* FreeModbus Libary: MSP430 Port
* Copyright (C) 2006 Christian Walter <wolti@sil.at>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*
* File: $Id: portserial.c,v 1.3 2006/11/19 03:57:49 wolti Exp $
*/

/* ----------------------- Platform includes --------------------------------*/
#include "port.h"

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


/* ----------------------- static functions ---------------------------------*/
static void prvvUARTTxReadyISR( void );
static void prvvUARTRxISR( void );

/* ----------------------- Static variables ---------------------------------*/
UCHAR           ucGIEWasEnabled = FALSE;
UCHAR           ucCriticalNesting = 0x00;



/* ----------------------- Start implementation -----------------------------*/
void
vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
    ENTER_CRITICAL_SECTION(  );
    if( xRxEnable )               
    {
                //MODBUS_RS485_RECIEVE();
                USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);        //禁止USART3接收不为空中断
    }
    else
    {
                //MODBUS_RS485_SEND();
                USART_ITConfig(USART3, USART_IT_RXNE, DISABLE);
    }
       
    if( xTxEnable )
    {
                //数据空中断模式传输
                //USART_ITConfig(USART3, USART_IT_TXE, ENABLE);
               
                //完成中断模式传输               
                //MODBUS_RS485_SEND();
                USART_ITConfig(USART3, USART_IT_TC, ENABLE);
    }
    else
    {
                //数据空中断模式传输
                //USART_ITConfig(USART3, USART_IT_TXE, DISABLE);
               
                //完成中断模式传输               
                //MODBUS_RS485_RECIEVE();
                USART_ITConfig(USART3, USART_IT_TC, DISABLE);
    }
    EXIT_CRITICAL_SECTION(  );
}



BOOL
xMBPortSerialInit( UCHAR ucPort, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
        BOOL    bInitialized = TRUE;
        GPIO_InitTypeDef GPIO_InitStructure;
        USART_InitTypeDef USART_InitStructure;


        USART_DeInit(USART3);
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3 , ENABLE);
        RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);       
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
        GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);            
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
        GPIO_Init(GPIOB, &GPIO_InitStructure);       
       
       
        USART_InitStructure.USART_BaudRate = ulBaudRate;
        switch ( eParity )
        {
                case MB_PAR_NONE:
                        USART_InitStructure.USART_Parity = USART_Parity_No;
                        break;
                case MB_PAR_ODD:
                        USART_InitStructure.USART_Parity = USART_Parity_Odd;
                        break;
                case MB_PAR_EVEN:
                        USART_InitStructure.USART_Parity = USART_Parity_Even;
                        break;
        }
       
        switch ( ucDataBits )
        {
                case 8:
                        if (eParity == MB_PAR_NONE)
                                USART_InitStructure.USART_WordLength = USART_WordLength_8b;
                        else
                                USART_InitStructure.USART_WordLength = USART_WordLength_9b;
                        break;
                case 7:
                        break;
                default:
                        bInitialized = FALSE;
        }
       
        if( bInitialized )
        {
                ENTER_CRITICAL_SECTION(  );
                USART_InitStructure.USART_StopBits = USART_StopBits_1;
                USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
                USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
                USART_Init(USART3, &USART_InitStructure);
                USART_Cmd(USART3, ENABLE);
                EXIT_CRITICAL_SECTION(  );
        }
       
        return bInitialized;
}



BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
        //数据空中断模式传输
        //USART_SendData(USART1, ucByte);
        //while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == 0) __NOP();  //等待发送完成
       
        //完成中断模式传输
        USART_SendData(USART3, ucByte);
       
        return TRUE;
}



BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{
        //USART_ClearFlag(USART3, USART_IT_RXNE) ;                 //中断接收
        //while(USART_GetFlagStatus(USART1, USART_IT_RXNE) == 0);  //等待接收标志
       
    *pucByte = (u8)USART_ReceiveData(USART3);
    return TRUE;
}



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

/* Create an interrupt handler for the receive interrupt for your target
* processor. This function should then call pxMBFrameCBByteReceived( ). The
* protocol stack will then call xMBPortSerialGetByte( ) to retrieve the
* character.
*/
static void prvvUARTRxISR( void )
{
    pxMBFrameCBByteReceived(  );
}


void USART3_IRQHandler(void)
{
        if (USART_GetITStatus(USART3,USART_IT_TC))//完成中断模式传输
        {
            //pxMBFrameCBTransmitterEmpty(  );
                prvvUARTTxReadyISR();
                USART_ClearITPendingBit(USART3, USART_IT_TC);
        }
        else if(USART_GetITStatus(USART3,USART_IT_RXNE))
        {
                //pxMBFrameCBByteReceived(  );
                prvvUARTRxISR();
                USART_ClearITPendingBit(USART3, USART_IT_RXNE);
        }
}


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-22 22:10

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表