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

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

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

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

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

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

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

 
Опции темы
Непрочитано 11.09.2019, 22:20  
nml
Супер-модератор
 
Аватар для nml
 
Регистрация: 13.03.2004
Адрес: Minsk
Сообщений: 2,378
Сказал спасибо: 1,948
Сказали Спасибо 1,327 раз(а) в 578 сообщении(ях)
nml на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Сообщение от bdn62 Посмотреть сообщение
Но контроль последнего отправленного бита выполняется в строке
while(!( UCSR0A & (1 ‹‹ TXC0)));//
Если верить даташиту, то TXC сбрасывается либо при записи туда 1, либо при обработке соотв. прерывания. В вашем примере я не увидел ни того, ни того. Так что он взводится после окончания передачи ПЕРВОГО байта и не очищается никогда.

А буферизация у меги есть. Так что опережение на два байта вполне закономерно. Один в регистре сдвига - передается, второй в буфере.
Реклама:
__________________
[ жизнь приятна и красива, если выпить литр пива ]

Последний раз редактировалось nml; 11.09.2019 в 22:50.
nml вне форума  
Непрочитано 11.09.2019, 23:41  
bdn62
Частый гость
 
Регистрация: 19.05.2010
Сообщений: 27
Сказал спасибо: 76
Сказали Спасибо 8 раз(а) в 2 сообщении(ях)
bdn62 на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Еще раз спасибо за внимание!
Но:
while(!( UCSR0A & (1 ‹‹ TXC0)));//

UCSR0A |= (1 ‹‹ TXC0);
т е сначала жду установки TXC0, затем его обнуляю
А вот про буферизацию это интересно. Хотя как обрабатывать этот редчайший, но после "заскока" ежесекундно повторяющийся "глюк" пока не понимаю.
bdn62 вне форума  
Непрочитано 12.09.2019, 01:09  
j-Roger
Гражданин KAZUS.RU
 
Регистрация: 17.06.2008
Адрес: Украина
Сообщений: 676
Сказал спасибо: 360
Сказали Спасибо 753 раз(а) в 358 сообщении(ях)
j-Roger на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Странно; функция RS485_U0_send в посте #1 написана один-в-один по даташиту с учетом буферизации и ожиданием окончания передачи последнего бита. Все как бы должно работать. Эррата молчит.
А прерывания запрещать на время передачи ( вдруг кто-то портит порт в прерываниях ) тогда уж так:


Код:
void RS485_U0_send(unsigned char *buff, unsigned char len)
{
 int cnt;
 unsigned char tmp;

	tmp = SREG;
	__asm__ ("cli");
	PORTB |= (1 ‹‹ PB4);//and set high level

	cnt = 0;
	while(cnt ‹ len)
	{
		while(!( UCSR0A & (1 ‹‹ UDRE0)));
		UDR0 = buff[cnt ++];
	}
	while(!( UCSR0A & (1 ‹‹ TXC0)));//

	UCSR0A |= (1 ‹‹ TXC0); 
	PORTB &= ~(1 ‹‹ PB4);//set R/W low level
	SREG = tmp;
	inc_tranzaction_MB1();
}
Можно (на всякий случай ) еще бит прерывания этого передатчика почистить.
j-Roger вне форума  
Сказали "Спасибо" j-Roger
bdn62 (12.09.2019)
Непрочитано 12.09.2019, 07:35  
akegor
Гуру портала
 
Аватар для akegor
 
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 18,841
Сказал спасибо: 2,531
Сказали Спасибо 11,764 раз(а) в 5,895 сообщении(ях)
akegor на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Сообщение от j-Roger Посмотреть сообщение
прерывания запрещать на время передачи ( вдруг кто-то портит порт в прерываниях )
Интересное предложение. Вообще-то, прерывания служат для того, чтобы выполнить что-то "именно здесь и сейчас". А если выполнение этого можно отложить на неопределенное время (миллисекунды!), как в данном предложении, то нахрена тогда использовать прерывания?!
Сообщение от nml Посмотреть сообщение
опережение на два байта вполне закономерно. Один в регистре сдвига - передается, второй в буфере.
Очень уж должны сойтись звезды... Но тут поможет запрет переключения на прием при непустом регистре данных передачи.
Сообщение от bdn62 Посмотреть сообщение
Проверил поисковиком редактора все файлы проекта - нигде больше нет обращения к биту PORTB.PB4
Нужно проверить ВСЕ обращения к порту. Бит может быть изменен не только обращением к одному биту, групповуха тоже возможна.
Еще возможно формирование буфера на два байта короче (не записана контрольная сумма), потому как в самой функции передачи буфера, вроде бы, все в порядке.
А еще возможно пересечение стека и области переменных. Уже говорил. В этом случае возможны зависания, нарушения в алгоритме и вообще ХЗЧ.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.
akegor вне форума  
Непрочитано 12.09.2019, 09:20  
dgrishin
Почётный гражданин KAZUS.RU
 
Регистрация: 12.02.2013
Сообщений: 1,015
Сказал спасибо: 43
Сказали Спасибо 273 раз(а) в 214 сообщении(ях)
dgrishin на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Код программы написан в дурном стиле. Если в посылке несколько (десяток) байт - то тогда код сойдёт. Такие вещи "по взрослому" надо делать на DMA.
А от дурного программирования до дурного поведения программы один шаг.
dgrishin вне форума  
Сказали "Спасибо" dgrishin
makakus (12.09.2019)
Непрочитано 12.09.2019, 10:07  
AR_Favorit
Почётный гражданин KAZUS.RU
 
Регистрация: 13.03.2010
Сообщений: 2,901
Сказал спасибо: 499
Сказали Спасибо 3,061 раз(а) в 1,425 сообщении(ях)
AR_Favorit на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Сообщение от dgrishin Посмотреть сообщение
Такие вещи "по взрослому" надо делать на DMA.
Ну вот и самые внимательные подтянулись))) ДМА в меге...
AR_Favorit вне форума  
Сказали "Спасибо" AR_Favorit
nml (17.09.2019)
Непрочитано 12.09.2019, 10:24  
mimuh64
Прописка
 
Регистрация: 29.10.2008
Сообщений: 272
Сказал спасибо: 0
Сказали Спасибо 102 раз(а) в 95 сообщении(ях)
mimuh64 на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Сообщение от bdn62 Посмотреть сообщение
Но именно иногда происходит зависание, иллюстрируемое осциллограммой 1, которая и вызывает у меня оторопь. Причем в этом зависании устройство сидит "вечно", до аппаратной инициализации МК.
Про зависание... это тоже не понятно, самое главное что видно по осциллограмме - это потеря 2х байтов...

Допустим что ТС описал нам все так как происходит и с регистром UCSR0A, в момент работы макроса RS485_U0_send, никто ни чего не делает, то такой баг (пропуск контроля выдачи 2х байт) может возникать только тогда, когда бит TXC0 равен единице на момент его проверки процедурой while(!( UCSR0A & (1 ‹‹ TXC0)));. Почему? пока не понятно... Сам, многократно контролировал выдачу выдачу подобным образом, никогда проблем не было...

Согласно ДШ такого не должно быть - бит TXC0 устанавливается в 1 только тогда, когда из сдвигового регистра (TRANSMIT SHIFT REGISTER) все выдано (вплоть до стопового бита) и в буферном регистре UDR0 (UDR (Transmit)) тоже ничего нет. Что в общем-то противоречит тому что мы видим. Но, оно есть...

Если бы в макросе RS485_U0_send была ошибка, то он бы стабильно работал неправильно, смущает то, что периодически выдача идет правильно (если верить ТС).

Есть одно замечание по макросу RS485_U0_send. Насколько я знаю, - сброс ФЛАГОВ програмным путем регистров АВР должен делаться не через UCSR0A |= (1 ‹‹ TXC0); (чтение-модификация-запись), а через UCSR0A = (1 ‹‹ TXC0); - просто запись в регистр (именно так изменится один бит)...Но, настаивать не буду - это ТС легко проверит в железе... Достаточно установить в UCSR0A|=(1‹‹U2X0); двойную скорость... если выполнение команды UCSR0A = (1 ‹‹ TXC0); очистит регистр - восстановит скорость до нормальной (смотреть осциллографом), то сброс бита нужно делать через UCSR0A |= (1 ‹‹ TXC0);

Далее...ТС попробуй следующее...
Для такой реализации макроса RS485_U0_send, я бы его переписал следующим образом
PHP код:
void RS485_U0_send(unsigned char *buffunsigned char len)
{
    
int cnt;
    
PORTB |= (‹‹ PB4);//and set high level

    
cnt 0;
    while(
cnt ‹ len)
    {
        
UDR0 buff[cnt ++]; // при первом запуске макроса регистр пустой...
                
while(!( UCSR0A & (‹‹ UDRE0))); // переставили контроль буфера...!!!!!!!!!

    
}
    
UCSR0A = (‹‹ TXC0);  // сбросим перед проверкой, мы точно знаем что один байт еще не выдан....
    
while(!( UCSR0A & (‹‹ TXC0)));//

     
UCSR0A = (‹‹ TXC0); 
    
PORTB &= ~(‹‹ PB4);//set R/W low level
    
inc_tranzaction_MB1();

Такая реализаци даст возможность контролировать только один - последний байт. И если будет потеря, то только одного байта, тогда будем думать еще...
Сброс UCSR0A = (1 ‹‹ TXC0); перед while - на всякий случай. Нужно проверить с ним и без....
согласно ДШ сам он сбрасывается только через прерывание (прерываний нет, значит сброс программно...)

bdn62 , попробуй... и отпишись...

Последний раз редактировалось mimuh64; 12.09.2019 в 11:08.
mimuh64 вне форума  
Непрочитано 12.09.2019, 11:53  
pt200
Прописка
 
Регистрация: 30.08.2010
Сообщений: 143
Сказал спасибо: 237
Сказали Спасибо 35 раз(а) в 28 сообщении(ях)
pt200 на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Если в момент передачи произойдет долгое прерывание( дольше передачи 1 или 2 байта), то TXC0 будет взведен( и сам уже не сброситься)!

Для начала можно попробовать такой велосипед:
Код:
while(cnt ‹ len)
{
	while(!( UCSR0A & (1 ‹‹ UDRE0)));
	__asm__ ("cli");
	UDR0 = buff[cnt ++];
	UCSR0A |= (1 ‹‹ TXC0); 
	__asm__ ("sei");
}
while(!( UCSR0A & (1 ‹‹ TXC0)));//
pt200 вне форума  
Сказали "Спасибо" pt200
bdn62 (12.09.2019)
Непрочитано 12.09.2019, 13:09  
bdn62
Частый гость
 
Регистрация: 19.05.2010
Сообщений: 27
Сказал спасибо: 76
Сказали Спасибо 8 раз(а) в 2 сообщении(ях)
bdn62 на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Велосипед
__asm__ ("cli");
UDR0 = buff[cnt ++];
UCSR0A |= (1 ‹‹ TXC0);
__asm__ ("sei");
пока работает, буду ждать...
bdn62 вне форума  
Непрочитано 12.09.2019, 13:26  
akegor
Гуру портала
 
Аватар для akegor
 
Регистрация: 06.05.2005
Адрес: Краснодар, возле укротворного моря.
Сообщений: 18,841
Сказал спасибо: 2,531
Сказали Спасибо 11,764 раз(а) в 5,895 сообщении(ях)
akegor на пути к лучшему
По умолчанию Re: Странный баг управления драйвером RS-485

Сообщение от pt200 Посмотреть сообщение
Если в момент передачи произойдет долгое прерывание( дольше передачи 1 или 2 байта), то
такого программера надо лупить розгами до просветления и осознания.

И вообще - организация передачи сообщения так, как сделано у ТС (циклом), заслуживает общественного осуждения и порицания. Нормально - с использованием прерываний, раз уж ПДП нету.
__________________
Не бейте больно, ежели чо, ну не удержался... А вааще,
"Мы за все хорошее, против всей х..., По лугам некошеным чтобы шли ступни,
Чтобы миром правила правда, а не ложь, Мы за все хорошее, нас не на...!
..." (Ленинград)
Я не несу ответственности за свои действия в Вашей голове.

Последний раз редактировалось akegor; 12.09.2019 в 13:30.
akegor вне форума  
Сказали "Спасибо" akegor
makakus (12.09.2019)
 

Закладки
Опции темы

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Книги (не радиотехнической тематики) Mike79 Делимся опытом 4264 16.08.2023 23:52
Ускорить компьютер 7Fantomas7 Ремонт оргтехники 111 08.08.2018 05:27


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


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