[an error occurred while processing this directive]
UART как автомат состояний в процедуре прерывания. Для 8515 до 9600 получалось
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

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

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


// размеры буферов приема/передачи :
#define RX2_SIZE 32
#define TX2_SIZE 32

// если размер буфера - степень двойки,
// для замыкания можно множить на маску :
// (соответствующую размеру буфера)
#define RX2_MASK (RX2_SIZE-1)
#define TX2_MASK (TX2_SIZE-1)

// буферы приема-передачи :
byte rx2_buf [RX2_SIZE];
byte tx2_buf [TX2_SIZE];

volatile byte rx2_wr,rx2_rd,rx2_volume;
volatile byte tx2_wr,tx2_rd,tx2_free;

// флаг "UART Empty"
volatile byte tx2_empty;


volatile byte start_place=0;
volatile byte tx2_place=0;
volatile byte rx2_place=0;

volatile byte tx2_byte;
volatile byte tx2_div=0;
volatile byte tx2_mask;

volatile byte rx2_div;
volatile byte rx2_byte;
volatile byte rx2_mask;

volatile byte res_count;
volatile word beg_count=5000;

volatile byte scount=250;

volatile byte tcount=0;
volatile byte res2_count=0;
#define TX2_DAT_1 PORTD |= (1<<6);
#define TX2_DAT_0 PORTD &= ~(1<<6);
#define TEST_RX2_DAT (PIND and (1<<7))

#define RES_MCP2150_0 PORTB &= ~(1<<4);
#define RES_MCP2150_1 PORTB |= (1<<4);
//-------------------------------------*/
// прерывания от таймера 0
// таймер для :
// (208 mkS)

interrupt [TIMER0_OVF0_vect] void t0_tim (void)
{
TCNT0 = T0_count;
// для контроля частоты прерываний
PORTD ^= (1<<3);
// PORTD &= ~(1<<3);

if (beg_count leq 0)
{
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// программный приемник

switch (rx2_place)
{
// удобно сделать инсталляцию всего программного UART-a
case 0:
rx2_wr =rx2_rd =rx2_volume =0;
tx2_empty =tx2_wr =tx2_rd =0;
tx2_free =TX2_SIZE;
rx2_place=6;
RES_MCP2150_0
res_count=100;
break;

case 1:
if (TEST_RX2_DAT leq 0) {rx2_place=2;}
break;

case 2:
if (TEST_RX2_DAT leq 0) {rx2_place=3;rx2_div=3;rx2_byte=0;rx2_mask=0x01;}
else {rx2_place=1;}
break;

case 3:
if (--rx2_div == 0) {rx2_place=4;}
break;

case 4:
if (TEST_RX2_DAT lne 0) {rx2_byte |= rx2_mask;}
rx2_mask <<= 1;
if (rx2_mask == 0)
{
rx2_place = 5;
rx2_div=4;
}
else
{
rx2_place=3;
rx2_div=3;
}
break;

case 5:
if (rx2_volume lne RX2_SIZE)
{
++ rx2_volume;
rx2_buf [rx2_wr++] =rx2_byte;
rx2_wr &= RX2_MASK;
}
rx2_place=1;
break;

case 6:
-- res_count;
if (res_count leq 0)
{
rx2_place=1;
RES_MCP2150_1
}
break;

default: rx2_place=0; break;
}

// программный приемник
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// программный передатчик

++tx2_div; tx2_div &= 0x03;
if (tx2_div == 0)
{
switch (tx2_place)
{
case 0:
if (tx2_free lne TX2_SIZE)
{
++ tx2_free ;
tx2_byte = tx2_buf [tx2_rd++];

tx2_rd &= TX2_MASK;
tx2_place=1;
tx2_mask=0x01;
}
break;

// start bit
case 1:
TX2_DAT_0
if ((tx2_byte and tx2_mask) leq 0) tx2_place=2;
else tx2_place=3;
break;

case 2:
TX2_DAT_0
tx2_mask <<= 1;
if (tx2_mask == 0) {tx2_place =4; break;}
if ((tx2_byte and tx2_mask) lne 0) tx2_place=3;
break;

case 3:
TX2_DAT_1
tx2_mask <<= 1;
if (tx2_mask == 0) {tx2_place =4; break;}
if ((tx2_byte and tx2_mask) leq 0) tx2_place=2;
break;

// stop bit
case 4:
TX2_DAT_1
tx2_place=5;
break;

case 5:
tx2_place=0;
break;

default: tx2_place=0;break;
}
}
// программный передатчик
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


}
//-------------------------------------*/
//-------------------------------------*/
//-------------------------------------*/
void putbyte2 (byte bout)
{
for (;tx2_free leq 0;) {}

tx2_buf [tx2_wr++] =bout;
tx2_wr &= TX2_MASK;

for (;tx2_div lne 1;) {}
--tx2_free;
}
//-------------------------------------*/
byte get_size_rec2 (void)
{
return (rx2_volume);
}
//-------------------------------------*/
byte getbyte2 (void)
{
for (;rx2_volume leq 0;) {}

rx2_rd &= RX2_MASK;

for (;;)
{
if (rx2_place < 3)
{
-- rx2_volume;
break;
}
}
return (rx2_buf [rx2_rd++]);
}
//-------------------------------------*/


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

Ответы


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

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

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

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

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


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

E-mail: info@telesys.ru