как принять байт больше, чем обьем FIFO/порог триггера? при остановке в прерывании из 18 принимается 16 байт (размер буфера uart), остальные исчезают
при работе проги без остановок принимаются последние 4 байта (18-триггер_на_14)
т.е. как бы возникают и ReceiveDataAvailable, и CharacterTimeOut, но теряется либо то, либо другое...
и в U0FCR триггер на 14байт, на другие пороги не меняется(
//*******************************
<pre>
#include "uart0.h"
//----------------------------------------------------------------
extern byte buffer[32];
extern TRealTimeClocks RTC; //часы реального времени
//----------------------------------------------------------------
void Uart0::Init(word baud)
{
word divisor = peripheralClockFrequency() / (16 * baud);
U0LCR = 0x83; /* 8 bit, 1 stop bit, no parity, enable DLAB */
U0DLL = divisor & 0xFF;
U0DLM = (divisor >> 8) & 0xFF;
U0LCR &= ~0x80; /* Disable DLAB */
//PINSEL0 = PINSEL0 & ~(0xFFFF << 16) | (0x5555 << 16);
PINSEL0 = PINSEL0 & ~(0x000F) | (0x0005);
U0IER = U0IER_RBR_Interrupt_Enable;
U0FCR = 1; //юзать FIFO
byte x = 0;
x |= 0x2 << U0FCR_Rx_Trigger_Level_Select_BIT;
x &= ~U0FCR_Rx_Trigger_Level_Select_MASK;
U0FCR &= ~U0FCR_Rx_Trigger_Level_Select_MASK; //сброс числа байт fifo до 1
U0FCR |= 0x2 << U0FCR_Rx_Trigger_Level_Select_BIT; //установка размера fifo на 14 байт
// U0FCR = 0; //не юзать FIFO
x = U0FCR;
BaudRate = baud;
memset(RxBuffer, 0, sizeof(RxBuffer));
RxBufferIndex = 0;
RxBufferDataCount = 0;
lastAccessTick = 65535;
}
//----------------------------------------------------------------
enum {
iidReceiveLineStatus = 0x3,
iidReceiveDataAvailable = 0x2,
iidCharacterTimeOut = 0x6,
iidTHRE = 0x1};
//----------------------------------------------------------------
#define TIMER1_INT 5
void Uart0::ISR()
{
bool interruptPending = (U0IIR & 0x01 == 0);
byte lsr = U0LSR;
byte interruptId = (U0IIR >> 1) & 0x07;
bool receiverDataReady = ((lsr & U0LSR_RDR_MASK) == U0LSR_RDR);
bool overrunError = ((lsr & U0LSR_OE_MASK) == U0LSR_OE);
bool parityError = ((lsr & U0LSR_PE_MASK) == U0LSR_PE);
bool framingError = ((lsr & U0LSR_FE_MASK) == U0LSR_FE);
bool breakError = ((lsr & U0LSR_BI_MASK) == U0LSR_BI);
bool transmitterHoldingRegisterEmpty = ((lsr & U0LSR_THRE_MASK) == U0LSR_THRE);
bool transmitterEmpty = ((lsr & U0LSR_TEMT_MASK) == U0LSR_TEMT);
bool receiverFifoError = ((lsr & U0LSR_RXFE_MASK) == U0LSR_RXFE);
bool anyError = ((lsr & 0x9E) != 0x00);
// byte x = U0RBR;
// if(RxBufferIndex == 0) memset(RxBuffer, 0, sizeof(RxBuffer));
// RxBuffer[RxBufferIndex++] = x;
// if(interruptId == iidCharacterTimeOut)
// {
// RxBuffer[RxBufferIndex++] = '*';
// RxBufferDataCount = RxBufferIndex;
// RxBufferIndex = 0;
// strcpy((char*)buffer, (char*)RxBuffer);
// }
// if((interruptId == iidReceiveDataAvailable))
if(receiverDataReady || (interruptId == iidReceiveDataAvailable) || (interruptId == iidCharacterTimeOut))
// if(interruptId == iidCharacterTimeOut)
{
while((U0LSR & U0LSR_RDR_MASK) == U0LSR_RDR)
{
RxBuffer[RxBufferIndex++] = U0RBR;
RxBufferDataCount++;
}
U0FCR |= U0FCR_Rx_FIFO_Reset_MASK;
}
// if(interruptId == iidCharacterTimeOut)
// {
// while((U0LSR & U0LSR_RDR_MASK) == U0LSR_RDR)//считывание данных из FIFO, пока они там есть (бит RDR)
// {
// byte x = U0RBR;
// RxBuffer[RxBufferIndex++] = x;
// RxBufferDataCount++;
// }
// }
//if(RxBufferIndex > sizeof(RxBuffer) - 1) RxBufferIndex = 0;
T1TCR = 3;//включение счетчика таймера 1 и сброс его
T1TCR = 1;//
ctl_unmask_isr(TIMER1_INT);
}
//----------------------------------------------------------------
void Uart0::TimerOutISR(void)
{
T1TCR = 2;//сброс счетчика таймера 1 и выключение таймера
ctl_mask_isr(TIMER1_INT);
RxBufferIndex = 0;
U0FCR |= U0FCR_Rx_FIFO_Reset_MASK;
strcpy((char*)buffer, (char*)RxBuffer);
memset(RxBuffer, 0, sizeof(RxBuffer));
}
//----------------------------------------------------------------
#ifndef __uart0_h__
#define __uart0_h__
#include "includes.h"
//----------------------------------------------------------------
class Uart0
{
public:
void Init(word baud); //инициализация uart, скоростью baud
void ISR(); //процедура обработки прерываний uart
void TimerOutISR(); //процедура обработки прерываний по Timer1 - для определения конца передачи
int BaudRate; //установленная скорость работы интерфейса
private:
byte RxBuffer[50]; //буфер приёма
int RxBufferIndex; //индекс принимаемого байта
int RxBufferDataCount; //число принятых байт в буфере
word lastAccessTick; //время последнего приема
};
//----------------------------------------------------------------
#endif // __uart0_h__</pre>
-
- Ответ: Andy Mozzhevilov(243 знак., 30.03.2006 07:33, , ссылка)
- спасибо, помогло - rius(31.03.2006 15:43, )
- т.е. почему оно глючит... - rius(29.03.2006 21:54, )
- Ответ: Andy Mozzhevilov(243 знак., 30.03.2006 07:33, , ссылка)