Страница 1 из 1

USART с использованием кольцевого буфера

Добавлено: Пн авг 01, 2011 10:57:59
sad-angel
Нужно передавать даные по USART через кольцевой буфер,всё сделал как написано в
http://microsin.ru/content/view/1098/44/ , МК ATmega16,компилятор WinAVR. Проблемма в том что каждый раз дважды отсылается первое числоИзображение
,как можно исправить проблемму?

Код: Выделить всё

#define BUF_SIZE 16 
#define BUF_MASK (BUF_SIZE-1)

unsigned char idxIN_TX, idxOUT_TX;
unsigned char TX_Buffer [BUF_SIZE];

void Write_TX_Buffer(unsigned char value)
{
if (idxIN_TX == idxOUT_TX) //буфер пустой, запись значения в для передачи по USART
{
UDR=value;
}

TX_Buffer[idxIN_TX++] = value;
idxIN_TX &= BUF_MASK; // if inxIN=15,then inxIN=0;
}

void Read_TX_Buffer(void)
{
if (idxIN_TX != idxOUT_TX)
{
UDR = TX_Buffer[idxOUT_TX++];
idxOUT_TX &= BUF_MASK;
}
}

void task2()
{
time2=t2;
Write_TX_Buffer(1);
Write_TX_Buffer(2);
Write_TX_Buffer(3);
Write_TX_Buffer(4);
Write_TX_Buffer(5);
Write_TX_Buffer(6);
}

ISR(USART_TXC_vect)
{
Read_TX_Buffer();
}

int main(void)
{
fof(;;);
}

Re: USART с использованием кольцевого буфера

Добавлено: Пн авг 01, 2011 11:03:38
koyodza
Всё просто, когда буфер пуст, Вы пишете и в UDR, и в буфер. Но когда записанное в UDR уйдёт на передачу, возникнет прерывание, и обработчик снова отправит тот же байт в UDR, теперь из буфера

Re: USART с использованием кольцевого буфера

Добавлено: Пн авг 01, 2011 11:19:40
sad-angel
koyodza писал(а):Всё просто, когда буфер пуст, Вы пишете и в UDR, и в буфер. Но когда записанное в UDR уйдёт на передачу, возникнет прерывание, и обработчик снова отправит тот же байт в UDR, теперь из буфера


не могу понять почему отсылается дважды,ведь буфер пустой только сначала (idxIN_TX == idxOUT_TX),потом уже (idxIN_TX != idxOUT_TX)

void Write_TX_Buffer(unsigned char value)
{
if (idxIN_TX == idxOUT_TX) //буфер пустой, запись значения в для передачи по USART
{
UDR=value;
}

TX_Buffer[idxIN_TX++] = value;
idxIN_TX &= BUF_MASK; // if inxIN=15,then inxIN=0;
}

Как исправить чтобы первое число отсилалось только один раз?

Re: USART с использованием кольцевого буфера

Добавлено: Пн авг 01, 2011 11:25:39
koyodza
Первый раз Вы отсылаете в Write_TX_Buffer, когда буфер пуст, а второй раз тот же самый байт отсылается уже Read_TX_Buffer, вызываемой из обработчика прерывания, когда первый байт передаётся.

Избавиться от эффекта можно по-разному. Правильнее всего будет не писать в UDR в самой Write_TX_Buffer, а вместо этого устанавливать флаг прерывания, что буфер пуст, чтобы запись в UDR была только в одном месте, в обработчике прерывания

Re: USART с использованием кольцевого буфера

Добавлено: Пн авг 01, 2011 11:29:27
Meteor
Регистр передатчика имеет двойную буферизацию.
При записи в регистр, тут же устанавливается флаг что второй (он как бы внешний) буфер пуст.
Решением может быть косвенная адресация данных с постинкрементом, которая организуется в прерывании опустошенного буфера передатчика.