[an error occurred while processing this directive]
спорам с UART и помощи Сергея Борща посвящается :)
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено ы 26 июля 2005 г. 13:14
В ответ на: Вот понадобилось софтовый UART сделать на прием, вижу такой алгоритм отправлено <font color=gray>ВинниПух</font> 26 июля 2005 г. 10:13

/*

4********** ***** ***
3 * * * *
2 * * * *
1 * * * *
0 ***************** *****
s 1 1 1 0 0 0 0 0 1 1 0 0 1
0

*/
volatile u32_t Ao;
volatile u32_t RxShft;
volatile u32_t SmplRxCnt;
volatile u32_t RxGet;
volatile u32_t RxCnt;


/******************************************************************************
* DESCRIPTION:
* check rx byte
*****************************************************************************/
__irq void GpsUartIrq(void) {

register u32_t _RxGet;
register u32_t _SmplRxCnt;
register u32_t _Ao;
register u32_t _An;
register u32_t _RxCnt;

TMR02138->IR = BIN8(00000001); //clr MR0 int

/////////////// samble bits ////////////////////////////////
_RxGet = RxGet;
_SmplRxCnt = SmplRxCnt;
_Ao = Ao;

// temporary use _RxCnt
_RxCnt = RxShft >> 1;
if (GET_RX())
_RxCnt |= BIN8(00001000);

_An = ((u32_t *)&bitnum4tbl)[_RxCnt]; //__one_cnt
RxShft = _RxCnt;

////////////////////////////////////////////////////////////
_RxCnt = RxCnt;
if (_An != _Ao) {
if (!(_An & BIN8(00000011))) {

if (!_SmplRxCnt) {
// clr prev bit
_RxGet &= 0x7fffffff;
} else {
// new bit
_RxGet >>= 1;
_RxCnt++;
}

if (_An) {
_RxGet |= 0x80000000; // An=4
}
_SmplRxCnt = 7; // next will 0
}
}

if (_SmplRxCnt == 3) {
// 01=0, 2=xz, 34=1
_RxGet >>= 1; // put 0

if (_An > 2) {
_RxGet |= 0x80000000;
}
if (_An == 2) {
if (_An < _Ao) {
_RxGet |= 0x80000000;
}
}
_RxCnt++;
}

Ao = _An;
RxGet = _RxGet;
SmplRxCnt = (_SmplRxCnt + 1) & 3; //0123

/////////////// check rx bit ////////////////////////////////
// xxxsbbbb bbbb0
// 12345678 9ABCDEF
// 00000000 00000000 00000000 00000000
// 76543210 76543210 76543210 76543210
// 31 24 23 16 15 8 7 0

if (_RxCnt == 0x0D) {
if (!(_RxGet & (1 << 19))) {
_RxCnt -= 10;
if (_RxGet & (1 << 28)) {
__RxByte(_RxGet >> 20);
}
} else {
_RxCnt--;
}
}

RxCnt = _RxCnt;


/* Update VIC priorities */
VIC2138->VICVectAddr = 0;
}


немного комментов к исходнику на скорую руку:

упрощенный вариант оверсемплинга


Ao - старый семпл
An - новый семпл

семпл = число едениц в переменной RxShft
число семплов 4, скорость 19200, прерывания от таймера каждые 1/(19200*4)
бит вылавливаем когда SmplRxCnt = 4 если при
SmplRxCnt = 4 счетчик RxShft = 2 то зона не определенности, значение
бита смотрим в зависимости от того An>Ao или An < Ao
Если An достигает 0 или 4 и An!=Ao а перед этим было защелкивание
бита то старый бит удаляем и защелкиваем новый бит (если An=0, то новый
бит =0, если An=4 то новый бит = 1) при этом переменную SmplRxCnt обнуляем
- синхронизация




Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 
NoIX ключ Запомнить

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru