Реклама на сайте English version  DatasheetsDatasheets

KAZUS.RU - Электронный портал. Принципиальные схемы, Datasheets, Форум по электронике

Новости электроники Новости Литература, электронные книги Литература Документация, даташиты Документация Поиск даташитов (datasheets)Поиск PDF
  От производителей
Новости поставщиков
В мире электроники

  Сборник статей
Электронные книги
FAQ по электронике

  Datasheets
Поиск SMD
Он-лайн справочник

Принципиальные схемы Схемы Каталоги программ, сайтов Каталоги Общение, форум Общение Ваш аккаунтАккаунт
  Каталог схем
Избранные схемы
FAQ по электронике
  Программы
Каталог сайтов
Производители электроники
  Форумы по электронике
Помощь проекту

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы
Непрочитано 08.04.2010, 12:49  
umgah
Частый гость
 
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
umgah на пути к лучшему
Печаль AVR USART+прерывания=потеря данных

Всем привет, коллеги.
Неприятно удивлен размером буфера UART на ATMega32 - похоже он всего 1 байт.
К МК (кристалл 8 Мгц) подключена клавиатура PC и эмуляция клавиатуры для PC.
Помимо этого прием данных с UART. То есть МК работает в режиме прозрачности для данных с клавиатуры, пересылая их на ПК, но может "добавить" пересылаемые данные теми, что поступают на UART.
Все работает, но если данные поступают на UART интенсивно (38400 8N1), то я вижу потерю данных, и это не радует.
Прерывания таймера и INT0 упрощать уже просто некуда, но передача и прием сигналов клавиатуры в случае приема - от меня не зависит - когда идет тогда и обрабатывай, а в случае передачи требовательна к таймингам. После двух дней жесткого мониторинга у самого меня идеи концились, видите ли вы выход ?
В качестве альтернативы я вижу ввод CTS-RTS, но очень ломает переделывать устройство. Альтернатива - ввести обратную связь по UART чтобы PC при необходимости повторял пропущеные байты. Тоже не радость, в основном по причине кривизны такого решения.
Еще мнения ?
Реклама:
umgah вне форума  
Непрочитано 08.04.2010, 13:05  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

Пиши данные при приёме байта с UART в прерывании в буффер, лучше кольцевой, читай из этого буфера когда надо. Передачу тоже можно буфферизировать. И не запрещай прерывания дольше чем принимается/передаётся один байт.
neiver вне форума  
Непрочитано 08.04.2010, 13:13  
umgah
Частый гость
 
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
umgah на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

Буфер есть.. Я не идиот) Два, на передачу тоже. PS два кольцевых на 256 байт без условий для пойнтеров начала и конца - все ровно и правильно )
Не запрещать - это как ? приоритет прерываний не может быть изменен - он просто есть и все. И в этом приоритете UART занимает одно из последних мест.
То есть: передача идет, буфер собирает данные, в это время щелкает таймер, по мере накопления идет передача с ноги, в то же время поступают прерывания на INT0. И в какой-то момент наступет ситуация, когда время выполнения внутри обработчиков прерывания (при этом другие прерывания запрещены разумеется) становится слишком велико и не считаный байт в буфере UART заменяется вновь поступающим.
umgah вне форума  
Непрочитано 08.04.2010, 13:18  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

Тогда код в студию.
У меня USART в похожих условиях отлично работает на 115200.
neiver вне форума  
Непрочитано 08.04.2010, 13:22  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

Чтобы при такой скорости были потери данных нужно не читать буффер ка минимум 260 мкс - это долго.
neiver вне форума  
Непрочитано 08.04.2010, 13:29  
umgah
Частый гость
 
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
umgah на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

UART: 38400 8N1
#pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
void uart0_rx_isr(void)
{
char ch=0;
//uart has received a character in UDR
// получили данные
ch=UDR;
if ((ch›=0x61) && (ch‹=0x7A)) ch=ch-0x20;
// ну типа поехали...
if (ch==0x0A) return;
if (ch==0x0D)
{
received++;
ch=0; // сделали zero-terminated строку
}
rx_buffer[rx_tale]=ch;
rx_tale++;
}

TIMER2 10uSec
#pragma interrupt_handler timer2_ovf_isr:iv_TIM2_OVF
void timer2_ovf_isr(void)
{
TCNT2 = 0xFF; //reload counter value
if (timer›0) timer--;
if (key_timeout›0) key_timeout--;
}

TIMER0 40uSec
#pragma interrupt_handler timer0_ovf_isr:iv_TIM0_OVF
void timer0_ovf_isr(void)
{
TCNT0 = 0xFB; //reload counter value
if (cmp2›0)
{
cmp2--;
if (cmp2==0)
{
PORTA=0;
PORTC=0;
}
}
}

INT0 - периодически, с частотой 10uSec, 24 раза за сессию (12 на спад фронта и 12 на старт фронта).
#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{

//external interupt on INT0
if ((MCUCR & 0x01)==0) // falling edge ?
{
MCUCR = MCUCR | 0x01;
bitcount++;
if (iscmd==0)
{
if ((bitcount›1) && (bitcount‹10))
{
keybkey=keybkey››1;
keybkey=keybkey | (PIND & 0x20) ‹‹ 2;
}
if (bitcount==11)
{
bitcount=0;
rx_key_buff[rx_key_tale]=keybkey;
rx_key_tale++;
}
}
}
else
{ // rising edge
MCUCR = MCUCR & 0xFE;
if (iscmd)
{
if ((bitcount›0) && (bitcount‹9))
{
PORTD=(PORTD & 0xDF) | ((cmds & 0x01) ‹‹ 5); // данные
if (cmds & 0x01) cmdp=cmdp^0x01;
cmds=cmds››1;
}
if (bitcount==9)
{
if (cmdp) PORTD&=0xDF; else PORTD|=0x20;
iscmd=2;
}
}
}
}

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

Последний раз редактировалось umgah; 08.04.2010 в 13:48.
umgah вне форума  
Непрочитано 08.04.2010, 14:00  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

У тебя случаем не первый(ые) байт в строке теряется?
Мне кажется, что во время обработки принятой строки данные продолжают записываться в буффер, а по окончании обработки строки сбрасывается rx_tale и всё что принялось в это время висит в буффере на правах мусора.
Попробуй именно кольцевой буффер использовать с индексами начала и конца валидных данных.
neiver вне форума  
Непрочитано 08.04.2010, 14:04  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

Могу свою реализацию предложить как пример, но она на WinAvr и написана на С++.

http://github.com/KonstantinChizhov/...p/containers.h
http://github.com/KonstantinChizhov/...avrcpp/usart.h
http://github.com/KonstantinChizhov/.../testUsart.cpp
neiver вне форума  
Непрочитано 08.04.2010, 14:05  
umgah
Частый гость
 
Регистрация: 15.01.2007
Сообщений: 20
Сказал спасибо: 3
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
umgah на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

не первый, типично - седьмой и далее.
С буфером все просто изумительно. rx_head и rx_tale образуют кольцевую работу на rx_buff ввиду того что rx_buff у меня 256 байт, а rx_head и rx_tale это unsigned char.
То есть, обращение rx_buff[rx_head] ВСЕГДА указывает на определенный байт в буфере, а при переполнении rx_head++ свыше размерности буфера он автоматически по переполнению становится равен 0 и смотрит в начало. Аналогично с rx_tale.
На всякий популярно:
rx_head был равен 255 (0xFF) и смотрел на последний элемент в кольце.
rx_head++
он стал равен нулю по переполнению и смотрит на начало. компактное совершенное решение.

Последний раз редактировалось umgah; 08.04.2010 в 14:08.
umgah вне форума  
Непрочитано 08.04.2010, 14:07  
neiver
Временная регистрация
 
Регистрация: 30.07.2007
Сообщений: 51
Сказал спасибо: 1
Сказали Спасибо 12 раз(а) в 7 сообщении(ях)
neiver на пути к лучшему
По умолчанию Re: AVR USART+прерывания=потеря данных

Да, действительно кольцевой - это хорошо. rx_head в приведенном коде не видно.
neiver вне форума  
 

Закладки

Метки
avr, uart
Опции темы

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача данных с ATmega8 на COM порт ПК sergx1300 Микроконтроллеры, АЦП, память и т.д 32 20.04.2010 14:19
прерывания usart в avr studio 4.13 zubr_ Микроконтроллеры, АЦП, память и т.д 6 14.10.2009 18:33


Часовой пояс GMT +4, время: 01:19.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot