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

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

Войти через центр авторизации
Похожие вопросы