Регистр приёма байта RCREG имеет вид двухуровнего буфера FIFO, данные в который поступают из программно-недоступного регистра RSR.
Отсюда можно сделать вывод, что обработать первый байт программа может только по пришествии второго, потому что считанный байт записывается в верхний уровень RCREGa, а считывается программой с нижнего. Чтобы принятый байт с верхнего уровня провалился в нижний, придётся по пришествии первого байта считать мусор из нижнего уровня RCREG, и сразу же считать провалившийся с верхнего уровня на нижний этот самый первый пришедший байт. Тогда на верхнем уровне что будет? Случайный мусор, который в следующий раз придётся пропустить? Значит байты надо обрабатывать через один?
Наверное можно до цикла считывания приходящих байт, считать этот самый первый мусор из нижнего уровня, а потом просто с задержкой отправки в один байт проводить обработку. То есть отправленный, к примеру, пятый по очереди байт, будет всего лишь навсего обрабатываться по счёту шестым.
Что ж делать если произошла ошибка фрейма?
Вроде бы как делают так:
Код:
|
#int_rda // наступило прерывание по приёму байта в УСАРТ
void RDA_isr(void)
{
error_rcv=false;
if(FERR) {readbyte=RCREG; error_rcv=true;}
if(OERR) {/////.....................................}
if(error_rcv) return;
switch(readbyte)
{case 0: ....... break;
case 1: ....... break;
case 2: ....... break;
}
} |
Но ведь сомнителен только байт верхнего уровня, поэтому при FERR нужно считать и употребить байт нижнего уровня, тогда сомнительный переместится сверху вниз и только в последующем прерывании его нужно будет пропустить.
А что же тогда происходит при ошибке переполнения приёмника? Выставляется флаг OERR и логика приёмника выключается. Нужно считать два ожидающих байта и включить-выключить разрешение приёма, чтобы работа продолжилась. При этом потерян будет только один байт, который переполнил RSR. Но если я считаю два ожидающих обработки байта чтоже тогда останется в RCREG? Случайный мусор или нули? А при следующем прерывании что делать? Нижний уровень считать и проигнорировать, а уже при следующем прерывании считать и употребить байт нижнего уровня? Или при OERR считать RCREG только один раз, чтобы снова начать опаздывать с обработкой на один байт?
Что-то я совсем запутался в этих условиях... Если кто разобрался, пожалуйста разъясните.
А то я в одном проекте сделал так, в другом сяк, а всё равно глюки случаются
И ещё непонятки с getc();
RCREG расположен по адресу 0x01A
Дизассемблировав код на С я вообще не увидел где-то использование регистра с этим адресом.
Как компилятор CCS это делает?
И как же лучше писать: readbyte=RCREG или readbyte=getc(); ???