Ответ: как то раз мне тоже понадобиля 2-UART, и вот что получилось:
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

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

Отправлено -Tумблер- 18 ноября 2004 г. 13:12
В ответ на: Пишу софтовый передатчик для UARTA (на 2400) на Си для Мега. Проблема ника не получается передать байт , принимается не тот байт который шлю. отправлено dmx 18 ноября 2004 г. 03:23


(это автомат состояний в процедуре прерывания)


// размеры буферов приема/передачи :
#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 shl 6);
#define TX2_DAT_0 PORTD &= ~(1 shl 6);
#define TEST_RX2_DAT (PIND and (1 shl 7))

#define RES_MCP2150_0 PORTB &= ~(1 shl 4);
#define RES_MCP2150_1 PORTB |= (1 shl 4);
//-------------------------------------*/
// прерывания от таймера 0
// таймер для :
// (208 mkS)
// мне надо 208 мкс, поточнее
#define delta0 3
#define T0_count 256 -208 +delta0

interrupt [TIMER0_OVF0_vect] void t0_tim (void)
{
TCNT0 = T0_count;
// для контроля частоты прерываний
PORTD ^= (1 shl 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 = rx2_mask shl 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 = tx2_mask shl 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 = tx2_mask shl 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;
}
}
// программный передатчик
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


-- scount;
if (scount leq 0)
{
scount=250;
// 50 mS

-- tcount;
if (tcount leq 0)
{
tcount=100;
res2_count=2;
}

if (res2_count lne 0)
{
-- res2_count;
RES_MCP2150_0
}
else
{
RES_MCP2150_1
}

}

}
else
{
-- beg_count;
}


}
//-------------------------------------*/
//-------------------------------------*/
//-------------------------------------*/
void set_tout (byte c)
{
tcount=c;
}
//-------------------------------------*/
byte get_tout (void)
{
return (tcount);
}
//-------------------------------------*/
void res_mcp2150 (void)
{
rx2_place=0;
}
//-------------------------------------*/
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: info@telesys.ru