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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Гарантия того, что по USART все данные ушли
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

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

 


RSS Текстовая версия Сейчас: 17th June 2025 - 23:03
Рейтинг@Mail.ru


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