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

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

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

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

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

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

AVR Раздел по микроконтроллерам компании Atmel - AVR / ATtiny / ATmega / ATMega128 / ATxmega, вопросы по программированию в AVR studio и все, относящееся к AVR...

 
Опции темы

Глюк с UART при засыпании

Непрочитано 02.09.2013, 07:53  
Wiza_
Гражданин KAZUS.RUN
 
Регистрация: 29.12.2012
Адрес: Питер
Сообщений: 980
Сказал спасибо: 131
Сказали Спасибо 230 раз(а) в 157 сообщении(ях)
Wiza_ на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

Код:
ISR(USART1_TX_vect)					// обработчик передачи на шину rs485
	{

		if (tx1_len == 0)
			PORTG &= ~(1 ‹‹ 2);							// switch tranceiver to receive
		if (tx1_len › 0)
			{
				TCNT0 = 0x100 - rs485_timeout;
				UDR1 = tx1_transmission[tx1_ptr];
				tx1_ptr++;
				tx1_len--;
			}
	}
В своё время делал так
Реклама:
Wiza_ вне форума  
Непрочитано 02.09.2013, 10:35  
av0000
Частый гость
 
Регистрация: 27.08.2008
Адрес: Москва
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 1 раз в 1 сообщении
av0000 на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

_Артём_, TXCIE как флаг не годится - байт ещё не передан в этот момент. Всё равно ждать TXC. А вот сам TXC при пустом буфере - вполне . И да, сон - это всё, что кроме Idle (либо ADC, либо PWR_DOWN), а 485-й - закладка на универсальность, потому как бывает и так, и эдак.


Godzilla82, не, _delay_ms сама по себе - зло мало того, что "тормозит" программу без учёта скорости передачи, так ещё и от неё код распухает ибо она практически везде инлайнится. У кого-то подсмотрел и активно пользую обёртку с принудительным __noinline__ для экономии

Wiza_, Ну, как-то так и у меня сделано. Пока, правда, раздельно в UDRIE и TXCIE, но, по мере чистки, сольётся в TXCIE.
av0000 вне форума  
Непрочитано 02.09.2013, 14:46  
Someone
Гражданин KAZUS.RUN
 
Регистрация: 16.06.2005
Сообщений: 942
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
Someone на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

Сообщение от av0000 Посмотреть сообщение
- отправили последний байт в обработчике TXC
- счетчик байт обнулили /TXC сбросился/
- О! вот тут ответ на вопрос - здесь же запретили прерывания, раз счётчик нулевой.
- в tx_flush ждём взвода TXC
Ну, можно и так, усложнить, и потом героически преодолеть.
Хотя проще в прерывании ТХС уменьшить счётчик, и если он стал равен 0, выход из прерывания (для 485 интерфейса отключаем передатчик, включаем приём). Иначе пихаем у UDR очередной символ из буфера, и выход из прерывания. И тогда флуш вообще не нужон, ведь в прерывание мы попадаем уже после завершения передачи символа, т.е. условие флуша выполнено, в отличии от прерывания UDRE.
Someone вне форума  
Непрочитано 02.09.2013, 18:07  
_Артём_
Гражданин KAZUS.RUN
 
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
_Артём_ на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

Сообщение от av0000 Посмотреть сообщение
TXCIE как флаг не годится - байт ещё не передан в этот момент. Всё равно ждать TXC. А вот сам TXC при пустом буфере - вполне .
Годится в случае использования для передачи прерывания TXC, а не DRE. Тогда пока передача активна прерывание TXC разрешено, после передачи последнего байта прврывание TXC запрещается (TXCIE=0). В основной программе проверяем TXCIE.
_Артём_ вне форума  
Непрочитано 02.09.2013, 19:34  
Godzilla82
Почётный гражданин KAZUS.RUN
 
Регистрация: 29.10.2006
Сообщений: 1,449
Сказал спасибо: 99
Сказали Спасибо 318 раз(а) в 234 сообщении(ях)
Godzilla82 на пути к лучшему
Сообщение Re: Глюк с UART при засыпании

Сообщение от _Артём_ Посмотреть сообщение
Тогда пока передача активна прерывание TXC разрешено, после передачи последнего байта прврывание TXC запрещается (TXCIE=0). В основной программе проверяем TXCIE.
В сотый раз говорю - зачем запрещать - разрешать. Ни к чему эти телодвижения. Да ещё при отправке каждого байта.

У нас и так есть флаг _tx.cnt - количество байт, требующих отправки. Если ноль - значит всё. Ждём, пока передаётся последний байт и в сон или на дачу - кому как. А ждать можно и через delay(). Не намного она код распушает. Да и используем её только в 1 месте - перед сном, ну попозже уснули на миллисекунду - ничё страшного, подумаешь - бессоница мучала.
Godzilla82 вне форума  
Непрочитано 02.09.2013, 19:37  
Wiza_
Гражданин KAZUS.RUN
 
Регистрация: 29.12.2012
Адрес: Питер
Сообщений: 980
Сказал спасибо: 131
Сказали Спасибо 230 раз(а) в 157 сообщении(ях)
Wiza_ на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

Поддерживаю. ТХС запрещать не имеет никакого смысла
delay использовать - тоже никакого
Wiza_ вне форума  
Непрочитано 03.09.2013, 09:34  
av0000
Частый гость
 
Регистрация: 27.08.2008
Адрес: Москва
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 1 раз в 1 сообщении
av0000 на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

Народ!
Не ссорьтесь Никто и не говорит о запрете/разрешении TXCIE при передаче каждого байта! Только по окончании передачи буфера. Повторюсь, хоть какой, но признак окончания отправки таки нужен при использовании глубокого сна...

Кажется, дошло, что имелось в виду:
PHP код:
ISR(USART_TXC_vect) {
  if (_tx.cnt)  _tx.cnt--; 
  if (_tx.cnt) {
   _tx.out = (_tx.out + 1) & UART_TX_BUF_MASK;
   UDR = _tx.buf[_tx_out];
  }
}
// ...
void flush_tx() {
  while(_tx.cnt ) ;
} 

Последний раз редактировалось av0000; 03.09.2013 в 09:40.
av0000 вне форума  
Непрочитано 03.09.2013, 20:26  
Godzilla82
Почётный гражданин KAZUS.RUN
 
Регистрация: 29.10.2006
Сообщений: 1,449
Сказал спасибо: 99
Сказали Спасибо 318 раз(а) в 234 сообщении(ях)
Godzilla82 на пути к лучшему
Сообщение Re: Глюк с UART при засыпании

Сообщение от av0000 Посмотреть сообщение
что имелось в виду:
PHP код:
ISR(USART_TXC_vect) {
  if (_tx.cnt)  _tx.cnt--; 
  if (_tx.cnt) {
   _tx.out = (_tx.out + 1) & UART_TX_BUF_MASK;
   UDR = _tx.buf[_tx_out];
  }
}
// ...
void flush_tx() {
  while(_tx.cnt ) ;
} 
Так оно побыстрее работать будет, да и код поменьше:
PHP код:
 
ISR(USART_TXC_vect)
{
if (_tx.cnt)    {
                _tx.cnt--;
                _tx.out++;
                _tx.out &= UART_TX_BUF_MASK;
                UDR = _tx.buf[_tx_out];
                }
}

void flush_tx()
{
while(_tx.cnt );
_delay_ms(5);
} 
_delay_ms(5) необходима, так как _tx.cnt становится равным нулю ещё до окончания передачи байта.

Для скорости 115200 достаточно _delay_us(90);
Godzilla82 вне форума  
Непрочитано 04.09.2013, 00:17  
Someone
Гражданин KAZUS.RUN
 
Регистрация: 16.06.2005
Сообщений: 942
Сказал спасибо: 25
Сказали Спасибо 174 раз(а) в 123 сообщении(ях)
Someone на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

Сообщение от av0000 Посмотреть сообщение
Повторюсь, хоть какой, но признак окончания отправки таки нужен при использовании глубокого сна
И чем не устраивает равенство нулю счётчика байт?
Код:
ISR(USART1_TX_vect)     // прерывание завершения передачи символа
{
 ByteCountUART--;     // уменьшаем счётчик переданных байт
 if(!ByteCountUART)     // если передали все байты
 {
  TransiverOff();     // отключаем передатчик RS485
  return;       // завершаем прерывание
 }
 UDR1 = *PosBuferUART1++;   // если послали не всё, посылаем очередной байт
}
Очевидно же, что если ByteCountUART равен 0, передача была полностью завершена, и можно спать или заниматься чем угодно.
Someone вне форума  
Непрочитано 04.09.2013, 10:30  
av0000
Частый гость
 
Регистрация: 27.08.2008
Адрес: Москва
Сообщений: 29
Сказал спасибо: 6
Сказали Спасибо 1 раз в 1 сообщении
av0000 на пути к лучшему
По умолчанию Re: Глюк с UART при засыпании

Someone, в итоге примерно так и вышло.
Оговорка: декремент счётчика без проверки может вызвать переполнение, потому, уменьшаем только если не ноль

А по поводу UDRE - я понял, в чём бонус - в отличие от TXC, прерывание возникает при пустом буфере - не требуется дублировать код отправки первого байта в uart_putch().
av0000 вне форума  
 

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

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблемы с передачей по UART, нужна помощь sansan25 Микроконтроллеры, АЦП, память и т.д 3 28.01.2012 13:19
Водка и как с ней бороться SerjT Отвлекитесь, эмбеддеры! 108 29.09.2009 21:25
Проблема с электропитанием квартиры tourent Делимся опытом 85 16.09.2009 07:51
[Решено] Сборник перлов любителей кабельщины mikesmith Отвлекитесь, эмбеддеры! 135 14.08.2007 15:49


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


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.