реклама на сайте
подробности

 
 
> Гарантия того, что по USART все данные ушли
admiral
сообщение Jan 14 2010, 10:27
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 14-12-07
Из: Беларусь, Гомель
Пользователь №: 33 305



Здравствуйте, не могли бы вы разъяснить такую ситуацию?
Перед входом в спящий режим мне нужно убедиться, что все данные ушли в линию. Для этого есть флаг ТХС. В даташите сказано:
Флаг устанавливается в 1 после передачи всех битов посылки из сдвигового регистра передатчика при условии, что в регистр данных UDR не было загружено новое значение. Флаг сбрасывается аппаратно при выполнении подпрограммы обработки прерывания или программно, записью в него лог. 1

Прерываний я не активировал, т.е. получается что после первой передачи, когда данные ушли, и в буфер я данных для отсылки не заносил, этот флаг установится в 1 и больше никогда не сбросится?
Если да, то получается, что после каждой передачи мне нужно программно сбрасывать этот бит?
Go to the top of the page
 
+Quote Post
4 страниц V   1 2 3 > »   
Start new topic
Ответов (1 - 51)
Rst7
сообщение Jan 14 2010, 10:45
Сообщение #2


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Если да, то получается, что после каждой передачи мне нужно программно сбрасывать этот бит?


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


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
admiral
сообщение Jan 14 2010, 11:29
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 14-12-07
Из: Беларусь, Гомель
Пользователь №: 33 305



Цитата(Rst7 @ Jan 14 2010, 14:45) *
По науке - перед последней передачей. Если байты могут передаваться с задержкой между ними, то перед передачей последнего байта.

Спасибо, а если неизвестно последний это байт или нет? Тогда придется каждый раз сбрасывать этот бит перед посылкой очередного байта?
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jan 14 2010, 11:32
Сообщение #4


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Спасибо, а если неизвестно последний это байт или нет?


Если неизвестно, то смысл тогда знания, что байт отправлен и можно спать?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 14 2010, 11:38
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Rst7 @ Jan 14 2010, 13:45) *
По науке - перед последней передачей. Если байты могут передаваться с задержкой между ними, то перед передачей последнего байта.
Можно словить "косяка", если между сбросом ТХС и загрузкой в UDR последнего байта закончилась передача байта из сдвигового регистра, а UDR был пуст... Выкручивался из этой ситуации сбросом TХC после загрузки последнего байта в UDR при закрытых прерываниях (между загрузкой и сбросом), при условии малой скорости передачи.

Цитата(admiral @ Jan 14 2010, 14:29) *
Спасибо, а если неизвестно последний это байт или нет? Тогда придется каждый раз сбрасывать этот бит перед посылкой очередного байта?
Вам, ведь, нужно убедиться, что все данные ушли в линию, значит - Вы знаете: последний байт или нет.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jan 14 2010, 11:49
Сообщение #6


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
Выкручивался из этой ситуации сбросом TХC после загрузки последнего байта в UDR при закрытых прерываниях (между загрузкой и сбросом), при условии малой скорости передачи.


Безусловно, смысл в таком действии есть. Но уж лучше подходить с позиций изначально правильного проектирования софта, дабы на такие грабли не наступать smile.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 14 2010, 12:07
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Rst7 @ Jan 14 2010, 14:49) *
Но уж лучше подходить с позиций изначально правильного проектирования софта, дабы на такие грабли не наступать
Имхо, такие извращения - не результат неправильного проектирования софта, а результат неправильного проектирования аппаратуры USART: бит ТХС следовало бы, наверное, аппаратно сбрасывать при зазрузке байта в UDR.
Кстати, всегда интересовало: как другие разработчики определяют окончание передачи (это актуально при использовании RS-485: включение/отключение приёмника) при использовании прерываний и записи байта по освобождению UDR.
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 14 2010, 12:33
Сообщение #8


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Палыч @ Jan 14 2010, 14:07) *
Кстати, всегда интересовало: как другие разработчики определяют окончание передачи (это актуально при использовании RS-485: включение/отключение приёмника) при использовании прерываний и записи байта по освобождению UDR.

Не знаю как другие, но я - исключительно по прерыванию TXC от USART. Потому что:
Цитата
Флаг сбрасывается аппаратно при выполнении подпрограммы обработки прерывания

На кой ляд анализировать какой-то флаг, когда есть TXC event, который аппаратно управляет флагом.
Go to the top of the page
 
+Quote Post
V_G
сообщение Jan 14 2010, 12:43
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



На мой взгляд, как раз широкое использование прерываний и является одним из признаков грамотного проектирования софта.
В данном случае при передаче последнего символа в обработке прерывания DRE я запрещаю прерывание DRE и разрешаю TXC, а по приходу последнего окончательно завершаю передачу (иногда и запрещаю для перевода ноги в высокий импеданс)

Сообщение отредактировал V_G - Jan 14 2010, 12:44
Go to the top of the page
 
+Quote Post
Rst7
сообщение Jan 14 2010, 12:48
Сообщение #10


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



Цитата
На мой взгляд, как раз широкое использование прерываний и является одним из признаков грамотного проектирования софта.


Тут немного не в том дело. Если задумана непрерывная передача пакета, а, например, процессор может оказаться занят в интервале между передачей двух байт чем-то другим и не успеет записать в UDR, то зопа произойдет в любом случае, хоть прерывание, хоть poll. Вот что я имею в виду под неправильным проектированием.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
admiral
сообщение Jan 14 2010, 12:57
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 14-12-07
Из: Беларусь, Гомель
Пользователь №: 33 305



Объясню ситуацию:
делаю устройство, т.к. питаться оно будет от батарей, то приходится экономить энергию вводя в спящий режим контроллер.
Для отладки использую usart, по нему контроллер передает в комп информацию что он в данный момент делает.
И вот была у меня беда - контроллер в ком-порт выдавал какой-то мусор вместо членораздельных фраз. Бился я бился над этим пока не попробовал отрубить вход в спяшщий режим.
В результате оказалось, что контроллер засыпал не успев отправить кусокпоследнего байта. Когда же он просыпался - то досылал оставшийся кусок и за ним новые данные.
Начал рыть документацию - оказывается, что флаг UDRE - указывает только на то, что контроллер готов принять новую порцию данных для отсылки, но не гарантирует, что данные уже отправлены.
Прерывания я не использую, поэтому флаг TXC сам не сбросится. Придется его сбрасывать программно.
И вот вопрос: контроллеру нужно заснуть, как убедится, что все данные отосланы? Будет ли нормально, если я перед каждой посылкой байта (неважно последний он или нет) буду сбрасывать этот флаг?
Не пойму почемуони не сделали, что бы, к примеру, при записи данных в UDR флаг TXC сбрасывался аппаратно?
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 14 2010, 13:04
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(defunct @ Jan 14 2010, 15:33) *
Не знаю как другие, но я - исключительно по прерыванию TXC от USART.
Это-то - понятно. Интересует: как у Вас устроена программа, что по этому прерыванию Вы гарантировано знаете, что все байты переданы? Поясню свой вопрос на примере "неправильного" софта (который такой гарантии не даёт, ну, или не во всех случаях):
1. Данные загружаются в UDR по прерыванию USART Data Register Empty
2. Перед загругкой последнего байта сбрасывается флаг TXC; последний байт загружается в UDR; разрешаются прерывания от USART Tx Complete
3. Наступает прерывание по TXC - считаем, что все байты переданы, что не всегда верно (см. выше - сообщение #5).

Цитата(admiral @ Jan 14 2010, 15:57) *
И вот вопрос: контроллеру нужно заснуть, как убедится, что все данные отосланы? Будет ли нормально, если я перед каждой посылкой байта (неважно последний он или нет) буду сбрасывать этот флаг?
Это - не повредит...
Цитата(admiral @ Jan 14 2010, 15:57) *
Не пойму почему они не сделали, что бы, к примеру, при записи данных в UDR флаг TXC сбрасывался аппаратно?
И я тоже этому в своё время был очень удивлён
Go to the top of the page
 
+Quote Post
V_G
сообщение Jan 14 2010, 13:31
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Посмотрел на симуляторе - у меня флаг TXC сброшен ПОСТОЯННО. Возможно, потому, что передатчик запрещен постоянно и разрешается только, когда надо что-то передать. При разрешении передачи (и прерываний DRE, TXC) сразу возникает прерывание DRE, а TXC дергаться и не думает, и никогда в жизни я его программно не сбрасывал.

А передавать байты с большими паузами, что TXC успевает дернуться - это что за задача такая? Я формирую передающий буфер до начала передачи, в результате передача посылки идет непрерывно. И медленно в масштабе времени процессора, так что паузам просто неоткуда взяться!

Да, и еще признаки грамотно спроектированного сорта - минимальное прерывание проца внутри обработки прерываний и минимальная длительность участков запрещения прерываний. Вот тут уж паузам действительно неоткуда взяться, смело используйте TXC для фиксации окончания посылки.
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jan 14 2010, 13:42
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(Палыч @ Jan 14 2010, 16:04) *
Поясню свой вопрос на примере "неправильного" софта (который такой гарантии не даёт, ну, или не во всех случаях):
1. Данные загружаются в UDR по прерыванию USART Data Register Empty
2. Перед загругкой последнего байта сбрасывается флаг TXC; последний байт загружается в UDR; разрешаются прерывания от USART Tx Complete
3. Наступает прерывание по TXC - считаем, что все байты переданы, что не всегда верно (см. выше - сообщение #5).

Поменяйте в пункте 2 "Перед загрузкой" на "сразу после загрузки" и получите свою гарантию.
Я не то что сбрасываю TXC, но и само это прерывание разрешаю именно внутри прерывания от UDRIE после загрузки последнего байта.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 14 2010, 13:48
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Rst7 @ Jan 14 2010, 15:48) *
Тут немного не в том дело. Если задумана непрерывная передача пакета, а, например, процессор может оказаться занят в интервале между передачей двух байт чем-то другим и не успеет записать в UDR, то зопа произойдет в любом случае, хоть прерывание, хоть poll. Вот что я имею в виду под неправильным проектированием.

Цитата(V_G @ Jan 14 2010, 16:31) *
А передавать байты с большими паузами, что TXC успевает дернуться - это что за задача такая? Я формирую передающий буфер до начала передачи, в результате передача посылки идет непрерывно. И медленно в масштабе времени процессора, так что паузам просто неоткуда взяться!
Да, и еще признаки грамотно спроектированного сорта - минимальное прерывание проца внутри обработки прерываний и минимальная длительность участков запрещения прерываний. Вот тут уж паузам действительно неоткуда взяться, смело используйте TXC для фиксации окончания посылки.
Задача, на которой у меня возникли такие проблемы - простая: передавать данные по RS-485 со скоростью 2Мбод (конечно, не только передавать, но и снимать информацию с датчиков, отрабатывать..). Даже с минимумом действий внутри обработчиков прерываний - не всегда можно успеть положить вовремя байт в UDR (прерывание по UDRE имеет невысокий приоритет, а механизма изменить приоритет в AVR - нет).
Как уже выше писал: решил проблему сбросом TXC после выдачи байта в UDR.

Цитата(Qwertty @ Jan 14 2010, 16:42) *
Поменяйте в пункте 2 "Перед загрузкой" на "сразу после загрузки" и получите свою гарантию. Я не то что сбрасываю TXC, но и само это прерывание разрешаю именно внутри прерывания от UDRIE после загрузки последнего байта.
Значит, не один я так делаю. Почему же советы: "перед выдачей - сбросьте ТХС"?
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jan 14 2010, 13:57
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(Палыч @ Jan 14 2010, 16:48) *
Значит, не один я так делаю. Почему же советы: "перед выдачей - сбросьте ТХС"?

Думаю так делают все, кто работает с RS485. Я правда использую намного более низкие скорости 19200-38400, так что и по прерываниям все получается неплохо. Но и при 2-х мегабитах интервал передачи байта 80 тактов, так что если в критическую секцию обернуть и выдачу в UDR и сброс TXC, все должно работать нормально.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 14 2010, 13:59
Сообщение #17


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Палыч @ Jan 14 2010, 17:04) *
1. Данные загружаются в UDR по прерыванию USART Data Register Empty
2. Перед загругкой последнего байта сбрасывается флаг TXC; последний байт загружается в UDR; разрешаются прерывания от USART Tx Complete
3. Наступает прерывание по TXC - считаем, что все байты переданы, что не всегда верно (см. выше - сообщение #5).


1. Иниц. указателя и счетчика байт
2. Разрешение UDRIE
Код
volatile uint8_t *tx_ptr;
volatile uint8_t tx_cnt;
void new_xmit(void *buff, uint8_t len)
{
  tx_ptr = buff;
  tx_cnt = len;
  UCSRB |= (1<<UDRIE);
}


3. Прерывание подхватывает поток: (GCC)
Код
// ATOMIC_BLOCK(ATOMIC_RESTORESTATE){
UDR= *tx_ptr++;
UCSRA &= ~(1<<TXC);
//}
if(--tx_cnt==0)
{
  UCSRB &= ~(1<<UDRIE);
  UCSRB |= (1<<TXCIE);
}


4. Программа смотрит, разрешено ли прерывание UDRE или TXC в зависимости от того что надо.

Если используем неблокирующие прерывания, приходится применять критическую секцию. laughing.gif

Если надо непрерывную передачу, контроль правильности/непрерывности можно сделать проверкой TXC перед передачей.
Go to the top of the page
 
+Quote Post
ILYAUL
сообщение Jan 14 2010, 15:16
Сообщение #18


Профессионал
*****

Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339



Цитата(admiral @ Jan 14 2010, 15:57) *
И вот вопрос: контроллеру нужно заснуть, как убедится, что все данные отосланы? Будет ли нормально, если я перед каждой посылкой байта (неважно последний он или нет) буду сбрасывать этот флаг?
Не пойму почемуони не сделали, что бы, к примеру, при записи данных в UDR флаг TXC сбрасывался аппаратно?

Если взглюнуть на структурную схему USART можно увидеть , что флаг TXC установиться при условии , что установлен флаг UDR и закончена передача байта , собственно он и сигнализирует о том , что сдвиговый регистр пуст и новых данных в буфере передачи нет . А , что Вы будете делать с ним дальше - значение не имеет , можете сбросить , записав единицу и уйти спать


--------------------
Закон Мерфи:

Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 14 2010, 17:30
Сообщение #19


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(admiral @ Jan 14 2010, 14:57) *
Прерывания я не использую, поэтому флаг TXC сам не сбросится. Придется его сбрасывать программно.

или придется начать использовать прерывания.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Jan 14 2010, 17:44
Сообщение #20


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(admiral @ Jan 14 2010, 15:57) *
Объясню ситуацию...
Сделайте отправку целиком по TXC, без UDRE. При отправке данных в цикле и по флагам, по-моему, ничуть не тормознее получится, и гарантированно отправите данные...
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 14 2010, 18:08
Сообщение #21


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Палыч @ Jan 14 2010, 15:04) *
Это-то - понятно. Интересует: как у Вас устроена программа, что по этому прерыванию Вы гарантировано знаете, что все байты переданы?

Ваш изначальный вопрос касался 485-го. Так вот в контексте 485-го все держится на модели "запрос-ответ". Драйверу UARTа попросту не дается следующий __пакет__ до тех пор пока нас об этот не попросят, либо до тех пор пока нам не ответят, либо до тех пор пока не завершится таймаут.

Из этого построение программы такое:
Есть кольцевой буфер и есть put() который пишет в этот буфер. TXC прерывание разрешено постоянно и управляет направлением трансивера 485-го. (По TXC драйвер переключается на прием.) Флаг TXC руками не трогается никогда.

В буфер помещается отправляемый пакет. Перед записью в UDR делается переключение трансивера 485 на передачу.. По UDRE - вычитка и отправка следующего байта из буфера.

В системе нет настолько тяжелых обработчиков прерываний чтобы UDRE прерывание откладывалось настолько долго, что за это время могло возникнуть TXC прерывание, (суммарная латентность всех прерываний не превышает интервала одного символа UART'а). Поэтому все прекрасно работает.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 14 2010, 18:53
Сообщение #22


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(defunct @ Jan 14 2010, 22:08) *
Флаг TXC руками не трогается никогда.

В системе нет настолько тяжелых обработчиков прерываний чтобы UDRE прерывание откладывалось настолько долго, что за это время могло возникнуть TXC прерывание, (суммарная латентность всех прерываний не превышает интервала одного символа UART'а). Поэтому все прекрасно работает.

Вот я - не понимаю:
1) откуда берется священная корова непрерывности данных в пакете, без тайм-аутов.
2) для чего TXC прерывание все время держать разрешенным.
Объясните, пожалуйста
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение Jan 14 2010, 19:03
Сообщение #23


Местный
***

Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101



RS485, скорости до 115200. Делаю так же: формирую сообщение в буфере, переключаю на передачу, записываю первый байт в UDR. Дальше работают только прерывания: UDRE досыпает следующий байт, TXC переключает интерфейс на приём.

Как я узнаю, что все байты ушли? А как я знаю, сколько байтов передавать? По счётчику! Пока он больше 0 (или, если строка ASCIIZ байт данных не равен 0) работаем на передачу. Я успеваю это делать в прерывании UDRE. Если бы не успевал, проверил бы счётчик и в TXC, пока не переключил на приём.

Сообщение отредактировал Maik-vs - Jan 14 2010, 19:07
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 14 2010, 19:37
Сообщение #24


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(_Pasha @ Jan 14 2010, 20:53) *
1) откуда берется священная корова непрерывности данных в пакете, без тайм-аутов.

application драйверу его так передает. Я так строю программу и гарантирую эту непрерывность.

Цитата
2) для чего TXC прерывание все время держать разрешенным.

А зачем его смыкать туда-сюда, код раздувать? Один раз при настройке уарта разрешили и забыли о нем вообще.
Ведь все что оно делает, это:

__interrupt void uart_TxCompleteHandler(void)
{
#if (UART0_RS485)
// handle 485 driver direction
PortX &= ~(1 << RS485_REDE_Pin);
#endif
}
Go to the top of the page
 
+Quote Post
HALFer
сообщение Jan 14 2010, 20:35
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 21-04-09
Пользователь №: 48 019



admiral,
если "правильность" софта не пугает и это будет временной мерой, то достаточно будет перед засыпанием установить задержку в виде N*2 холостых циклов. где N - это к-во тактов необходимые для отправки одного байта по USART. а умножаем на 2, т к у USART'а двойная буферизация.

глупее не бывает, но вроде как временная мера сойдет
Go to the top of the page
 
+Quote Post
Qwertty
сообщение Jan 14 2010, 20:58
Сообщение #26


Местный
***

Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527



Цитата(defunct @ Jan 14 2010, 22:37) *
А зачем его смыкать туда-сюда, код раздувать? Один раз при настройке уарта разрешили и забыли о нем вообще.

Если есть возможность прогнозировать приход прерываний, то это работает. Если же нет, то RS485 идет в лес. sad.gif
А ведь есть более приоритетные, нежели от UDRE, прерывания - INTx, абсолютно асинхронные. Тут прогнозы не всегда работают.

Цитата(defunct @ Jan 14 2010, 22:37) *
Ведь все что оно делает, это:
__interrupt void uart_TxCompleteHandler(void)
{
#if (UART0_RS485)
// handle 485 driver direction
PortX &= ~(1 << RS485_REDE_Pin);
#endif
}

А добавить туда еще проверку счетчика байт и проблема тоже решится. Не все передали - выходим из прерывания без переключения направления драйвера. ИМХО тоже вариант.
Go to the top of the page
 
+Quote Post
SysRq
сообщение Jan 15 2010, 06:45
Сообщение #27


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(_Pasha @ Jan 14 2010, 21:53) *
1) откуда берется священная корова непрерывности данных в пакете, без тайм-аутов.
Один из вариантов - канал RS-485 без растяжек (+ к питанию, - к земле). Если все абоненты молчат, то состояние линии не определено, и от помех появляется мусор, успешно принимающийся МК. Поэтому во время передачи пакета на приём переключаться нельзя до окончания передачи всего пакета ;(
Также, если более чем один мастер в канале...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 15 2010, 07:48
Сообщение #28


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(SysRq @ Jan 15 2010, 10:45) *
Если все абоненты молчат, то состояние линии не определено, и от помех появляется мусор, успешно принимающийся МК. Поэтому во время передачи пакета на приём переключаться нельзя до окончания передачи всего пакета ;(

Вы неверно представляете этот вариант. Или я smile.gif
Объясняю своими словами:
Если передающий встал на передачу, и между символами будет пауза, то эта пауза - не повод отключать TXE, если это все в пределах наперед заданного тайм-аута. Какого именно? Такого, чтобы в наихудшем случае программа успевала отослать данные. В этом случае мусор в линию не валится и на приемнике имеем красивый "1".
Go to the top of the page
 
+Quote Post
SysRq
сообщение Jan 15 2010, 08:02
Сообщение #29


Чайник, 1 литр
****

Группа: Свой
Сообщений: 655
Регистрация: 17-05-06
Из: Moscow
Пользователь №: 17 168



Цитата(_Pasha @ Jan 15 2010, 10:48) *
Объясняю своими словами...
Ммм.. да, я под непрерывностью имел в виду именно это smile.gif
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 15 2010, 08:12
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(defunct @ Jan 14 2010, 21:08) *
В системе нет настолько тяжелых обработчиков прерываний чтобы UDRE прерывание откладывалось настолько долго, что за это время могло возникнуть TXC прерывание, (суммарная латентность всех прерываний не превышает интервала одного символа UART'а). Поэтому все прекрасно работает.
Это - хорошо, когда нет тяжелых прерываний... "Тяжесть" - штука относительная. Число "лёгких" прерываний с приоритетом выше чем у USART может быть достаточно для того, чтобы в сумме они составили "одно тяжелое". Да и "тяжелость" отпределяет ещё и скоростью передачи, особенно на очень высоких скоростях (тут уж - как не облегчай прерывания, а при некотором числе высокоприоритетных прерываний они всё равно превращаются в "тяжелое").
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 15 2010, 09:23
Сообщение #31


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



А кто как борется с коллизиями?
RXE всегда включен - это ясно.
При отправке байта пишем его в переменную типа:
Код
volatile uint8_t RS485_last_sent;
//...............................................
UDR = RS485_last_sent = *rx_ptr++;

Прерывание от RX не выключается никогда.
Но можно нарваться на момент, когда прерывание RX не успело подхватить RS485_last_sent и сравнить его. Поскольку UDR буферизирован, прочтем старое принятое значение - и кирдык. Ложная реакция обеспечена.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Jan 15 2010, 09:43
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(_Pasha @ Jan 15 2010, 12:23) *
А кто как борется с коллизиями?
Если один мастер и "Команда мастера - ответ слэйва", то и бороться не нужно. А, другого - и не использую.
Go to the top of the page
 
+Quote Post
V_G
сообщение Jan 15 2010, 10:59
Сообщение #33


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(_Pasha @ Jan 15 2010, 19:23) *
А кто как борется с коллизиями?

Если имеется в виду исключение одновременного выхода на линию нескольких мастеров, то
1. Все слушают всех и не выходят в передачу, когда линия занята
2. После освобождения линии у каждого девайса СВОЙ таймаут выхода в передачу (с повторной проверкой свободности линии)
3. Для большей надежности можно завести прерывание по старт-биту (на переход в 0 сигнала на линии), по нему - таймаут на передачу байта-полутора, и если в заданный промежуток перепадов больше не пришло - линия свободна. UART контроллер при этом не задействован, и проблемы с буферированием исчезают
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 15 2010, 11:54
Сообщение #34


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(Палыч @ Jan 15 2010, 10:12) *
Да и "тяжелость" определяется ещё и скоростью передачи, особенно на очень высоких скоростях (тут уж - как не облегчай прерывания, а при некотором числе высокоприоритетных прерываний они всё равно превращаются в "тяжелое").

Да все так, только давайте посмотрим что может бегать по 485-му:

В Modbus RTU например, который бегает по 485-му, недопустимы какие-то непрогнозируемые паузы между символами. Пауза больше чем 1.5 символа по стандарту является поводом для отбраковки всего пакета!
Чтобы получить несвоевременный TXC, обработка UDRE должна опоздать аж на 2 символа! Т.е. межсимвольная пауза в системе где может случайно вылезти TXC посреди пакета - может достигать 2х символов. Как следствие этого - работа в Modbus RTU протоколе становится невозможной впринципе в такой системе.

Что делать? Отказаться от RTU? - нельзя, причины сами знаете.

Поэтому обработчики более выскоприоритетных прерываний строятся так, чтобы была гарантия отработки более низкоприоритетных во-время. Если не получается это сделать на одном AVR, тогда ставится еще один чип в помощь, либо берется другой МК, т.к. заранее известно, что система без этого захлебнется.

PS: С очень высокими скоростями по UART'у на AVRках не работаю - 115200 макс.
AVRки у меня всегда не ниже 11.059 тактируются, в основном 14.7456.
Go to the top of the page
 
+Quote Post
admiral
сообщение Jan 18 2010, 07:31
Сообщение #35


Участник
*

Группа: Участник
Сообщений: 19
Регистрация: 14-12-07
Из: Беларусь, Гомель
Пользователь №: 33 305



Цитата(HALFer @ Jan 15 2010, 00:35) *
admiral,
если "правильность" софта не пугает и это будет временной мерой, то достаточно будет перед засыпанием установить задержку в виде N*2 холостых циклов. где N - это к-во тактов необходимые для отправки одного байта по USART. а умножаем на 2, т к у USART'а двойная буферизация.

глупее не бывает, но вроде как временная мера сойдет

Я так и сделал - установил задержку 2мс перед засыпанием и стало все нормально.
Просто мучал меня этот вопрос т.к. нерационально получается - вдруг когда-то придется использовать USART не только для отладки. Да и думал может в документации ошибка закралась, т.к. не пойму почему не сделали сброс флага TXC при занесении данных в UDR.
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение Jan 20 2010, 12:35
Сообщение #36


Местный
***

Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101



Цитата(admiral @ Jan 18 2010, 10:31) *
Я так и сделал - установил задержку 2мс перед засыпанием и стало все нормально.
Просто мучал меня этот вопрос т.к. нерационально получается - вдруг когда-то придется использовать USART не только для отладки. Да и думал может в документации ошибка закралась, т.к. не пойму почему не сделали сброс флага TXC при занесении данных в UDR.

Сбрасывать флаг прерывания должно только прерывание, иначе разрушится мир smile.gif Затраты на сброс флага невелики - если прерывание разрешено, это время на 2 загрузки адреса + 1 такт на reti. Если же флаг сбрасывать при загрузке UDR, то вы не сможете отследить те самые разрывы между байтами, которые могут быть критичны.

Вам нужно вместо задержки 2 мс поставить ожидание флага TXC, его сброс (записью в TXC единицы!) и можно засыпать. Прерывание TXC должно быть запрещено (бит TXCIE =0), чтобы флаг TXC стоял не сбрасывался.
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение Jan 20 2010, 22:47
Сообщение #37


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



Цитата
Если же флаг сбрасывать при загрузке UDR, то вы не сможете отследить те самые разрывы между байтами, которые могут быть критичны.

А что мешает отслежить состояние флага перед записью в UDR?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 21 2010, 11:10
Сообщение #38


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(defunct @ Jan 15 2010, 14:54) *
В Modbus RTU например, который бегает по 485-му, недопустимы какие-то непрогнозируемые паузы между символами. Пауза больше чем 1.5 символа по стандарту является поводом для отбраковки всего пакета!
Вы забыли упомянуть ещё о такой особенности таймаутов Modbus RTU:
Код
#define MB_MIN_15T_TIMEOUT              MB_SEC_TO_TCNT_TIC( 0.000750f ) // 750 us    if bps>19200
#define MB_MIN_35T_TIMEOUT              MB_SEC_TO_TCNT_TIC( 0.001750f ) // 1.750 ms  if bps>19200
Я её использую.
Раз уж пошёл разговор про Modbus RTU, то хочу спросить кто как обеспечивает гарантию паузы 3,5T меду пакетами?
Я всегда отправляю преамбулу из 4 dummy байтов с отключенным передатчиком драйвера RS485.
Какие у Вас соображения на сей счёт? Может это лишняя паранойя, ведь я и так отлавливаю конец посылки по паузе?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 21 2010, 11:32
Сообщение #39


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(demiurg_spb @ Jan 21 2010, 15:10) *
кто как обеспечивает гарантию паузы 3,5T между пакетами?

Никакая не паранойя - можно позволить УАРТУ за счет собственных средств не только разделять пакеты при передаче, но и обнаруживать паузу при приеме, отсылая также пустые фреймы.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 21 2010, 12:03
Сообщение #40


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



А я вот всё больше и больше склоняюсь к тому что это лишне.
Будь я slave или master, я ловлю конец посылки по паузе в 3,5Т ВСЕГДА - это ведь и есть гарантия разделения пакетов.
Так что слейв может отвечать немедленно без преамбулы сразу по факту получения пакета.
ИМХО. Я сейчас поэкспериментирую.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
defunct
сообщение Jan 21 2010, 17:28
Сообщение #41


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(demiurg_spb @ Jan 21 2010, 13:10) *
Я всегда отправляю преамбулу из 4 dummy байтов с отключенным передатчиком драйвера RS485.

Такой подход имеет смысл применять тогда, когда мастер отправляет несколько broadcast сообщений (address 0x00 / 0xFF) подряд, не дожидаясь ни от кого ответа. Настройка системы, синхронизация времени, старт синхро-измерения и т.п.
Во всех остальных случаях - достаточно факта определения конца посылки по паузе в 3,5Т, и мастеру и слейвам.

Но на мой взгляд отправка 4х dummy байтов с отключенным передатчиком ломает всю "тупизну и прямолинейность" smile.gif драйвера UART'a. Если без этого действует простейший алгоритм:

- включить передатчик
- отправить символ
- выключить передатчик если TXC.

то в случае с преамбулой будут варианты.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 22 2010, 18:26
Сообщение #42


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(_Pasha @ Jan 21 2010, 14:32) *
Никакая не паранойя - можно позволить УАРТУ за счет собственных средств не только разделять пакеты при передаче, но и обнаруживать паузу при приеме, отсылая также пустые фреймы.
Поясните если не трудно про: "обнаруживать паузу при приеме, отсылая также пустые фреймы". Интересно...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение Jan 22 2010, 20:18
Сообщение #43


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



Что ж тут непонятного. Время на передачу байта фиксированное. Оно и используется в качестве таймера. А байт дальше драйвера 485 не уйдет.
На быcтрую руку примерно так:
По RxC: UDR = dummy; TimeOut = 0;
По TxC: if (++TimeOut <= N) {UDR = dummy;} else {DoOnTimeOut}
N, по моему, должен быть равен 4.
таким образом обнаруживается пауза > (4T...5T) (т.е. не факт, что пауза 4,5Т будет обнаружена)

P.S. Можно в качестве dummy-байта взять 0x0F. ТОгда получим фронт в середине байта на 0,5Т. И выход Tx завести на прерывание (по фронту). ТОгда можно будет обнаруживать паузы > (3,5Т...4,5Т). Но надо ли? laughing.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 23 2010, 05:02
Сообщение #44


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Александр Куличок @ Jan 23 2010, 00:18) *
ТОгда получим фронт в середине байта на 0,5Т.

Вы ж не забывайте, что длительности в 1,5 и 3,5 Т выбирались исходя их соображений накрыть всех "опоздавших" и "неуспевающих" однозначным событием разделения данных. Имхо, если внутри распознается соответственно 2 и 4 Т, ничего страшного и "роняющего перфоманс" не происходит. Проще надо быть с модбасом smile.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 29 2010, 18:26
Сообщение #45


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(_Pasha @ Jan 23 2010, 08:02) *
Проще надо быть с модбасом smile.gif

Товарищи! Возник у меня ещё один вопрос про modbus.
Хотелось бы узнать какие-нибудь элегантные способы решения проблемы поддержания функционирования стандартных функций чтения-записи регистров и коилов в контексте 8-ми битного little-endian MCU.
Я решаю сейчас данную закавыку через remap-таблицу во FLASH.
Она зараза большая становится, когда много данных нужно ремапить, да и нудно её редактировать (хоть всё уже и так через макросы зафигачено).
Я уже и так и сяк, но ничего другого выдумать не могу. Прошу ALL не стеснятся и высказывать любые здравые предложения! Спасибо!


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 30 2010, 03:05
Сообщение #46


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(demiurg_spb @ Jan 29 2010, 21:26) *
Она зараза большая становится, когда много данных нужно ремапить, да и нудно её редактировать (хоть всё уже и так через макросы зафигачено).

1. Написать приблуду и работать с Ёкселем в формате *.csv
2. Проблема, кстати, сходная с созданием таблицы редактирования/доступа к параметрам: зоопарк валидаторов, read-only/write-only/rw, источник или приемник данных (функция/ОЗУ/eeprom/flash), clear after use...

Код
typedef struct
{
// неявное задание правил доступа RO WO RW - метод == NULL
size_t (*read)(void *src, size_t size);//если результат != заданному size, то ашипко
size_t (*write)(void *dst, void *src, size_t size);
} data_src_stream_t;

typedef struct
{
uint16_t log_addr;
void      *phy_addr;
void *validator; // там же хранится инфа о размере
void *stream;
} remap_tbl_t;
//........................................
struct Valid32_cnt //пример
{
  uint8_t size;// всегда первым байтом пойдет как тэг
  uint32_t low;
  uint32_t high;
} pause_tmr={4,120000,240000};

Про coil_read() или coil_write()
Иногда проще все уложить в switch(), но лучше imho избавляться от двухбайтового оверхеда.
Если нехватка флеша на таблицу - приходится все паковать в битовые поля.
Код
typedef struct
{
uint16_t log_addr;
void      *phy_addr;

uint8_t mate;// многоцелевой индекс - все, что не отображается в полях, потом делается через switch(remap.mate)

unsigned size:2;// elem size
unsigned pool:4;// register pool
unsigned perm_rd:1;
unsigned perm_wr:1;
} remap_t;


Вот видите - у меня тот же бардак smile.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 30 2010, 10:46
Сообщение #47


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(_Pasha @ Jan 30 2010, 06:05) *
1. Написать приблуду и работать с Ёкселем в формате *.csv
Тоже об этом думал, но пока что-то останавливает.
Цитата
2. Проблема, кстати, сходная с созданием таблицы редактирования/доступа к параметрам: зоопарк валидаторов, read-only/write-only/rw, источник или приемник данных (функция/ОЗУ/eeprom/flash), clear after use...
Схожая да не совсем. К параметрам меню не обращаются как к "raw big-endian 16-bit data", и не пытаются читать потоком данные например float или DWORD или BYTE или BIT. И "самое страшное" что могут обратится лишь к младшему или старшему полуслову float или DWORD, а про массивы я вообще молчу:-) И про то, что есть 5 отдельных адресных пространств SRAM, FLASH, EEPROM, DATAFLASH, RTC. Мама помоги!!!! Пока я это всё делал чуть не тронулся умом;-) А всё из-за этого &%@# modbus (нехорошего в общем и целом).
С меню у меня всё достаточно красиво получилось (писал на Си в "стиле С++", некое наследование путём включения базового типа menu_item_t во всех потомков, ну и таки да, реализация методов доступа через switch (item_type) - так компактнее получилось, структуры практически без callback'ов). Написал макросы для ассигнования этих типов и всё получилось читабельно и вменяемо (хоть работы проделано немало).
Цитата
Вот видите - у меня тот же бардак smile.gif
Ага, нормально:-)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 31 2010, 05:24
Сообщение #48


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(demiurg_spb @ Jan 30 2010, 13:46) *
И про то, что есть 5 отдельных адресных пространств ... Мама помоги!!!!

Поток ввода/вывода - это мама? или папа? smile.gif
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jan 31 2010, 11:13
Сообщение #49


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(_Pasha @ Jan 31 2010, 08:24) *
Поток ввода/вывода - это мама? или папа? smile.gif
Они родимые:-)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Maik-vs
сообщение Jan 31 2010, 14:54
Сообщение #50


Местный
***

Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101



Цитата(Александр Куличок @ Jan 21 2010, 01:47) *
А что мешает отслежить состояние флага перед записью в UDR?

Если паузы между байтами недопустимы, прерывание UDRE используется для загрузки следующего байта, пока текущий передаётся. Если паузы допустимы - UDRE пофиг и не используется. Смысл читать его ПЕРЕД записью?
Go to the top of the page
 
+Quote Post
Александр Куличо...
сообщение Jan 31 2010, 21:31
Сообщение #51


Местный
***

Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017



Речь шла о флаге TXC. И о возможности отслеживания разрывов:
Цитата
Если же флаг сбрасывать при загрузке UDR, то вы не сможете отследить те самые разрывы между байтами, которые могут быть критичны.

Если паузы недопустимы, то считывание его перед записью в UDR как раз позволяет проанализировать, была ли пауза при передаче. И принимать дальнейшее решение о том, что писать (или не писать) в UDR.
Одно только использование UDRE еще не дает гарантию, что пауз не будет. Особенно при большИх скоростях.
Go to the top of the page
 
+Quote Post
sitafern
сообщение Jan 31 2010, 22:26
Сообщение #52


Участник
*

Группа: Участник
Сообщений: 25
Регистрация: 8-08-05
Пользователь №: 7 466



Пользуюсь простым алгоритмом при реализации Modbus RTU (потолок скорости 115200).
Назначения:
1. Буфер приёмника/передатчика (первый байт - счётчик).
2. 1 РОН для счётчика "долгих" циклов.
3. 2 РОНа для хранения CRC16.
4. Функция подсчёта CRC "на лету".
5. Функция записи в буфер записывает последними в буфер 2 байта CRC16.
6. Функция передачи данных подсчитывает CRC16 "на лету".
Собственно проверка:
1. "Длинный" счётчик =0? Да.
2. РОНы контрольной суммы =0? Да.
Резюме: данные "уехали" без проблем.
CODE
;======================================================================
=============
; ЗАДАЧА 7 - Передача фрейма данных в хост-компьютер по USART0 по протоколу ModBusRTU
;===============================================================================
====
PLC_7:
sbrs rFlagPLC, flPLC_7
rjmp Exit_PLC_7

cbr rFlagPLC, (1<<flPLC_0) ; Запретить приём по USART0 на время передачи
sbrc rFlagUSART, flReady0 ; Начальная инициализация была?
rjmp lbLoadTxD0 ; Да
;-------------------------------------------------------------------
; Инициализация функции передачи данных
ldi rFuncL, N115200 ;1. Делитель частоты UBRR0H:UBRR0L = 0x0007
out UBRR0L, rFuncL ;2. Асинхронный режим UMSEL = 0
out UBRR0H, rZero ;3. Контроль чётности UPM1 = 1, UPM0 = 0
ldi rFuncL, 0xA6 ;4. Один стоп-бит USBS = 0
out UCSR0C, rFuncL ;5. Формат кадра 8бит UCSZ1 = 1, UCSZ0 = 1

lds rCounter0, pCountUSART0 ; Количество передаваемых байт данных
ldi XL, low(pAdressUSART0) ; Буфер передатчика начинается с адре-
ldi XH, high(pAdressUSART0) ; са УСО

sbi UCSR0B, TXEN0 ; Включить передатчик USART0!
sbr rFlagUSART, (1<<flReady0) ; PLC инициализирована
;---------------------------------------------------------------------------
; Загрузка байта данных для передачи
lbLoadTxD0:
cpse rCounter0, rZero ; Все байты фрейма загружены?
rjmp lbFrame0 ; Нет
rjmp lbEndTxD0 ; Да
lbFrame0:
sbis UCSR0A, UDRE0 ; Надо загрузить байт для передачи?
rjmp Exit_PLC_7 ; Нет.

ld rdUSART0, X+ ; Загрузить передаваемый байт
out UDR0, rdUSART0 ; Собственно загрузить байт данных для передачи
dec rCounter0 ; Уменьшаем счётчик передаваемых байт фрейма
cbi UCSR0A, UDRE0 ; Сбросить флаг требования загрузки
sbr rFlagUSART, (1<<flCRC160) ; Установить флаг требования подсчёта CRC16
;---------------------------------------------------------------------------
; Окончание функции передачи данных
lbEndTxD0:
sbis UCSR0A, TXC0 ; Ожидание передачи последнего байта
rjmp Exit_PLC_7
;-------------------------------------------------------------------
; Сброс передатчика USART0
clr rFuncL
out UCSR0B, rFuncL
;-------------------------------------------------------------------
; Проверка регистров CRC16 на ошибку
cpse rCRC160L, rZero
rjmp lbTxDError0
cpse rCRC160H, rZero
rjmp lbTxDError0
rjmp lbExitTxD0
;-------------------------------------------------------------------
lbTxDError0: ; Обработка ошибки подсчёта CRC16 "на лету"
sbr rErrInter, (1<<flCRC16T0xD)
lbExitTxD0:
sbi UCSR0A, TXC0
cbr rFlagUSART, (1<<flEmpty0)+(1<<flReady0)+(1<<flCRC160)+(1<<flFrame0)
cbr rFlagPLC, (1<<flPLC_7); Выключить функцию передачи данных по USART0
sbr rFlagPLC, (1<<flPLC_0); Включить функцию приёма данных по USART0
Exit_PLC_7:
nop
Go to the top of the page
 
+Quote Post

4 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 13th August 2025 - 04:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.01888 секунд с 7
ELECTRONIX ©2004-2016