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

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
sad-angel
Встал на лапы
Сообщения: 122
Зарегистрирован: Пт июл 11, 2008 21:49:40
Откуда: Украина

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

Сообщение 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(;;);
}
Аватара пользователя
koyodza
Собутыльник Кота
Сообщения: 2623
Зарегистрирован: Вс июл 17, 2011 11:51:52
Контактная информация:

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

Сообщение koyodza »

Всё просто, когда буфер пуст, Вы пишете и в UDR, и в буфер. Но когда записанное в UDR уйдёт на передачу, возникнет прерывание, и обработчик снова отправит тот же байт в UDR, теперь из буфера
Аватара пользователя
sad-angel
Встал на лапы
Сообщения: 122
Зарегистрирован: Пт июл 11, 2008 21:49:40
Откуда: Украина

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

Сообщение 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;
}

Как исправить чтобы первое число отсилалось только один раз?
Аватара пользователя
koyodza
Собутыльник Кота
Сообщения: 2623
Зарегистрирован: Вс июл 17, 2011 11:51:52
Контактная информация:

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

Сообщение koyodza »

Первый раз Вы отсылаете в Write_TX_Buffer, когда буфер пуст, а второй раз тот же самый байт отсылается уже Read_TX_Buffer, вызываемой из обработчика прерывания, когда первый байт передаётся.

Избавиться от эффекта можно по-разному. Правильнее всего будет не писать в UDR в самой Write_TX_Buffer, а вместо этого устанавливать флаг прерывания, что буфер пуст, чтобы запись в UDR была только в одном месте, в обработчике прерывания
Аватара пользователя
Meteor
Друг Кота
Сообщения: 3961
Зарегистрирован: Пн июл 13, 2009 14:37:39
Откуда: Московская область, наукоград.....
Контактная информация:

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

Сообщение Meteor »

Регистр передатчика имеет двойную буферизацию.
При записи в регистр, тут же устанавливается флаг что второй (он как бы внешний) буфер пуст.
Решением может быть косвенная адресация данных с постинкрементом, которая организуется в прерывании опустошенного буфера передатчика.
Загружая на вход компьютера "мусор", на выходе получим "мусор^32".
PS. Не работаю с: Proteus, Multisim, EWB, Micro-Cap... не спрашивайте даже
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»