Цитата(Gerasimov @ Apr 9 2008, 11:49)

...совершая вот такие действия каждые 4 секунды я заставляю уарт жить. В чём может быть проблема?
Была полная ересь с UART2,3 при использовании KEIL mdk3.03 или 3.05. Принимал порой черте-что, отказывался посылать байты, генерил ошибки и т.п. Это было только с UART2 и 3!!!!!!!!
Сначала думал, что глючный камень, посылал запрос на NXP-те сказали что все ОК. Потом вышел новый KEIL (3.11)-все заработало без проблем(и до сих пор). В проекте используются UART0,2,3 - проблем нет. Обработчики прерываний U2,3 переписаны с примера UART0. Единственное - везде убрал использование вложенных прерываний( IENABLE,IDISABLE).
Код
PCONP |= (1 << 24); // Питание UART2 и UART3
PCONP |= (1 << 25);
UARTInit(0, 38400); // UART0, 38400 b/s
UARTInit(2, 9600); // UART2, 9600 b/s
UARTInit(3, 9600); // UART3, 9600 b/s
/*****************************************************************************
Function name: UARTInit
*****************************************************************************/
DWORD UARTInit( DWORD PortNum, DWORD baudrate )
{
DWORD Fdiv;
if ( PortNum == 0 )
{
U0LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
Fdiv = ( Fpclk / 16 ) / baudrate; //baud rate
U0DLM = Fdiv / 256;
U0DLL = Fdiv % 256;
U0LCR = 0x03; // DLAB = 0
U0FCR = 0x07; // Enable and reset TX and RX FIFO.
VICVectAddr6 = (unsigned long)UART0Handler; // UART0 Interrupt -> Vector 6
VICVectCntl6 = 0x05; // UART0 Interrupt -> Priority 5
VICIntEnable = 1 << 6; // Enable UART0 Interrupt
U0IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */
return (TRUE);
}
else if ( PortNum == 2 )
{
U2LCR = 0x83; // 8 bits, no Parity, 1 Stop bit
Fdiv = ( Fpclk / 16 ) / baudrate; //baud rate
U2DLM = Fdiv / 256;
U2DLL = Fdiv % 256;
U2LCR = 0x03; // DLAB = 0
U2FCR = 0x07; // Enable and reset TX and RX FIFO.
VICVectAddr28 = (unsigned long)UART2Handler; // UART2 Interrupt -> Vector 28
VICVectCntl28 = 0x02; // UART2 Interrupt -> Priority 2
VICIntEnable = 1 << 28; // Enable UART2 Interrupt
U2IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART2 interrupt */
return (TRUE);
}
else if ( PortNum == 3 )
{
U3LCR = 0x83; /* 8 bits, no Parity, 1 Stop bit */
Fdiv = ( Fpclk / 16 ) / baudrate; /*baud rate */
U3DLM = Fdiv / 256;
U3DLL = Fdiv % 256;
U3LCR = 0x03; /* DLAB = 0 */
U3FCR = 0x07; /* Enable and reset TX and RX FIFO. */
// if ( install_irq( UART3_INT, (void *)UART3Handler, 0x01 ) == FALSE )
// {
// return (FALSE);
// }
VICVectAddr29 = (unsigned long)UART3Handler; // UART3 Interrupt -> Vector 29
VICVectCntl29 = 0x01; // UART3 Interrupt -> Priority 1
VICIntEnable = 1 << 29; // Enable UART3 Interrupt
U3IER = IER_RBR | IER_THRE | IER_RLS; /* Enable UART0 interrupt */
return (TRUE);
}
return( FALSE );
}
//***************************************************************************
// Function name: UART3Handler
//***************************************************************************
void UART3Handler (void) __irq
{
BYTE IIRValue, LSRValue;
volatile BYTE Dummy;
//__enable_interrupt(); /* handles nested interrupt */
IIRValue = U3IIR;
IIRValue >>= 1; /* skip pending bit in IIR */
IIRValue &= 0x07; /* check bit 1~3, interrupt identification */
if ( IIRValue == IIR_RLS ) /* Receive Line Status */
{
LSRValue = U3LSR;
/* Receive Line Status */
if ( LSRValue & (LSR_OE|LSR_PE|LSR_FE|LSR_RXFE|LSR_BI) )
{
/* There are errors or break interrupt */
/* Read LSR will clear the interrupt */
UART3Status = LSRValue;
Dummy = U3RBR; /* Dummy read on RX to clear interrupt, then bail out */
VICVectAddr = 0; /* Acknowledge Interrupt */
return;
}
if ( LSRValue & LSR_RDR ) /* Receive Data Ready */
{
/* If no error on RLS, normal ready, save into the data buffer. */
/* Note: read RBR will clear the interrupt */
UART3Buffer[UART3Count] = U3RBR;
UART3Count++;
if ( UART3Count == BUFSIZE )
{
UART3Count = 0; /* buffer overflow */
}
}
}
else if ( IIRValue == IIR_RDA ) /* Receive Data Available */
{
/* Receive Data Available */
UART3Buffer[UART3Count] = U3RBR;
UART3Count++;
if ( UART3Count == BUFSIZE )
{
UART3Count = 0; /* buffer overflow */
}
}
else if ( IIRValue == IIR_CTI ) /* Character timeout indicator */
{
/* Character Time-out indicator */
UART3Status |= 0x100; /* Bit 9 as the CTI error */
}
else if ( IIRValue == IIR_THRE ) /* THRE, transmit holding register empty */
{
/* THRE interrupt */
LSRValue = U3LSR; /* Check status in the LSR to see if valid data in U3THR or not */
if ( LSRValue & LSR_THRE )
{
UART3TxEmpty = 1;
}
else
{
UART3TxEmpty = 0;
}
}
VICVectAddr = 0; /* Acknowledge Interrupt */
}