S
S
Slavka2015-12-09 00:56:10
C++ / C#
Slavka, 2015-12-09 00:56:10

FreeModBus on lpc2378 rs485 doesn't read data, what could cause time out?

/*
  * FreeModbus Libary: LPC214X Port
  * Copyright (C) 2007 Tiago Prado Lone <[email protected]>
 *
 * 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.1 2007/04/24 23:15:18 wolti Exp $
 */

#include <lpc23xx.h>

#include "port.h"

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

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

/* ----------------------- Start implementation -----------------------------*/
     void            vMBPortSerialEnable( BOOL xRxEnable, BOOL xTxEnable )
{
    if( xRxEnable )
    {		
        FIO0CLR |= (1<<4); //rs485 на чтение
        
        U0IER |= 0x01;
        
    }
    else
    {   
        U0IER &= ~0x01;
    }
    if( xTxEnable )
    {
        
        FIO0SET |= (1<<4);   //rs485 на отправку 
        
        U0IER |= 0x02;
        prvvUARTTxReadyISR(  );
    }
    else
    {   
        U0IER &= ~0x02;
    }
}

void
vMBPortClose( void )
{
}

BOOL
xMBPortSerialInit( UCHAR ucPORT, ULONG ulBaudRate, UCHAR ucDataBits, eMBParity eParity )
{
    BOOL            bInitialized = TRUE;
    USHORT          cfg = 0;
    ULONG           reload = (12000000 * 5) / (ulBaudRate * 16 * 4); //( ( PCLK / ulBaudRate ) / 16UL );
    volatile char   dummy;

    ( void )ucPORT;
    /* Configure UART0 Pins */
    PINSEL0 &= ~(0xF0);       /* Enable RxD0 and TxD0 */
    PINSEL0 |= (0x50);   
  
    switch ( ucDataBits )
    {
    case 5:
        break;

    case 6:
        cfg |= 0x00000001;
        break;

    case 7:
        cfg |= 0x00000002;
        break;

    case 8:
        cfg |= 0x00000003;
        break;

    default:
        bInitialized = FALSE;
    }

    switch ( eParity )
    {
    case MB_PAR_NONE:
        break;

    case MB_PAR_ODD:
        cfg |= 0x00000008;
        break;

    case MB_PAR_EVEN:
        cfg |= 0x00000018;
        break;
    }

    if( bInitialized )
    {
        U0LCR = cfg;            /* Configure Data Bits and Parity */
        U0IER = 0;              /* Disable UART0 Interrupts */

        U0LCR |= 0x80;          /* Set DLAB */
        U0DLL = reload;         /* Set Baud     */
        U0DLM = reload >> 8;    /* Set Baud */
        U0LCR &= ~0x80;         /* Clear DLAB */

        /* Configure UART3 Interrupt */
        VICVectAddr6 = ( unsigned long )sio_irq;
        VICVectCntl6 = (0xFF);
        VICIntEnable |= 1 << 6;  /* Enable UART0 Interrupt */

        dummy = U0IIR;          /* Required to Get Interrupts Started */
    }

    
    

    
  
    
    return bInitialized;
}

BOOL
xMBPortSerialPutByte( CHAR ucByte )
{
    U0THR = ucByte;
     
    /* Wait till U0THR and U0TSR are both empty */
    while( !( U0LSR & 0x20 ) )
    {
    }

    return TRUE;
}

BOOL
xMBPortSerialGetByte( CHAR * pucByte )
{  
    while( !( U0LSR & 0x01 ) )
    {
    }

    /* Receive Byte */
    *pucByte = U0RBR;

    return TRUE;
}


void
sio_irq( void )
    __irq
{
    volatile char   dummy;
    volatile char   IIR;

    while( ( ( IIR = U0IIR ) & 0x01 ) == 0 )
    {
        switch ( IIR & 0x0E )
        {
        case 0x06:             /* Receive Line Status */
            dummy = U0LSR;      /* Just clear the interrupt source */
            
        break;

        case 0x04:             /* Receive Data Available */
            
        case 0x0C:             /* Character Time-Out */
            prvvUARTRxISR(  );
            break;

        case 0x02:             /* THRE Interrupt */
            
            prvvUARTTxReadyISR(  );
            break;

        case 0x00:             /* Modem Interrupt */
            dummy = U1MSR;      /* Just clear the interrupt source */
            break;

        default:
            break;
        }
    }

    VICVectAddr = 0xFF;         /* Acknowledge Interrupt */
}


/* 
 * 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(  );
}

Here is the example code that I remade from FreeModBus, am I working correctly with the RTS port?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
Ocelot, 2015-12-09
@Ocelot

You need to first understand what is going on with you.
1) Slave receives the frame? Raise the debug UART on the controller and send everything that is received via RS-485 to it. All OK? Let's go further.
2) Does the slave send a response? Connect a separate adapter to the RS-485 line and see through the terminal what is generally transmitted there. Look with an oscilloscope to see what's going on at the controller's UART pins. Check that the RTS pin is really working. There is no oscilloscope - at least plug in the LEDs, it will be seen whether there is silence or some movement.
3) At the physical level, everything is fine, but MODBUS still gives a timeout hit? HEX editor in the teeth, and study the intercepted frames. Is the answer correct? Does the data field size match the header? Is the checksum correct?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question