Slavka_online
@Slavka_online
Интересная личность

FreeModBus на lpc2378 rs485, не считывает данные, из за чего может быт time out?

/*
  * FreeModbus Libary: LPC214X Port
  * Copyright (C) 2007 Tiago Prado Lone <tiago@maxwellbohr.com.br>
 *
 * 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(  );
}


Вот код примера который я переделал из FreeModBus, правильно ли я работаю в с портом RTS ?
  • Вопрос задан
  • 516 просмотров
Пригласить эксперта
Ответы на вопрос 1
Ocelot
@Ocelot
Нужно сначала понять, что вообще у вас происходит.
1) Slave принимает фрейм? Поднимите на контроллере отладочный UART и шлите в него всё, что принято по RS-485. Все ок? Едем дальше.
2) Slave передает ответ? Подключите к линии RS-485 отдельный адаптер и посмотрите через терминал, что там вообще передается. Посмотрите осциллографом, что творится на выводах UART контроллера. Проверьте, что пин RTS действительно работает. Нет осциллографа - хотя бы светодиоды воткните, будет видно, тишина там или какие-то шевеления.
3) На физическом уровне все хорошо, но MODBUS все равно дает отлуп по таймауту? HEX-редактор в зубы, и изучайте перехваченные фреймы. Ответ формируется корректно? Размер поля данных соответствует заголовку? Контрольная сумма правильно считается?
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы