Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2018-сен-24 16:33

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 27 ]  На страницу Пред.  1, 2
Автор Сообщение
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2017-сен-15 14:29 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 158
Откуда: ПКК "Миландр"
Цитата:
Вот именно этого я и не наблюдал, а чем тоже писал. Повторю. Я смотрю значения регистров делителя, там НОВОЕ значение. Смотрю на линию - там тишина. Далее мастером посылаю пакеты, но обмены происходят только на СТАРОЙ скорости.


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

_________________
Отдел технической поддержки support@milandr.ru


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2017-сен-18 14:59 
Не в сети

Зарегистрирован: 2015-фев-25 09:17
Сообщения: 12
Прикрепляю проект, воспроизводящий ошибку.
1. Проект основан на примере к демоплате, использует "стандартную библиотеку из гитхаба" (в архиве все нужные файлы скопированы, внешнего ничего не надо). Внешний HSE стоит 16 (на плате изначально 8 ), дефайном можно подправить. Среда IAR 7.80, конфиги для МК взяты с форума. Моменты, связанные с проблемой отмечены комментами с тэгом #debug
2. После инициализации запускается UART1 на 115200, потом через ~3сек переключается на 3000000. И там и там эхо. Думаю, скорости можно взять другие.
3. Воспроизводится так. Запускается прошивка, снаружи по уарту выдается непрерывная выдача на скорости 3000000 (само значение не думаю, что критично) рандома на 5 секунд. Далее видно, что предделители значения поменяли, а уарт МК продолжает работать на 115200.
4. Ошибка проявляется при UART_DeInit/UART_Init из библиотеки. Не проявляется, если использовать UartSetBaud из предыдущих постов. Зато, если чуть подправить (в комментах описано) UartSetBaud - опять начинает проявляться.


Вложения:
uart_test.zip [78.21 КБ]
Скачиваний: 45
Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2017-сен-19 14:58 
Не в сети

Зарегистрирован: 2017-апр-26 14:51
Сообщения: 158
Откуда: ПКК "Миландр"
В спецификации на стр. 324:
"Содержимое регистров LCR_H, IBRD и FBRD совместно образует общий 30-разрядный регистр LCR, который обновляется по стробу, формируемому при записи в LCR_H. Таким образом, для того, чтобы изменение параметров коэффициента деления частоты обмена данными вступило в силу, после их изменения значения регистров IBRD и/или FBRD необходимо осуществить запись данных в регистр LCR_H."

Возможно наблюдаемое поведение связано с этим, неверной последовательностью записи регистров. Добавил Ваш #DEBUG код в свой тест, скорость по прежнему меняется успешно.

Код:
void UartSetBaud(uint32_t baudRate, uint32_t freqCPU)
{
    uint32_t divider = freqCPU / (baudRate >> 2);
    uint32_t CR_tmp = UART_X->CR;
    uint32_t LCR_tmp = UART_X->LCR_H;
   
    while ( (UART_X->FR & UART_FLAG_BUSY) ); // wait

//#DEBUG
  UART_X->CR = 0;
  UART_X->LCR_H = 0;
  UART_X->IBRD = 0;
  UART_X->FBRD = 0;
//#DEBUG
   
    UART_X->CR = 0;
    UART_X->IBRD = divider >> 6;
    UART_X->FBRD = divider & 0x003F;
    UART_X->LCR_H = LCR_tmp;
    UART_X->CR = CR_tmp;
}

_________________
Отдел технической поддержки support@milandr.ru


Последний раз редактировалось Vasiliy 2017-сен-19 15:31, всего редактировалось 3 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2017-сен-19 15:07 
Не в сети

Зарегистрирован: 2014-май-15 11:04
Сообщения: 128
Откуда: Москва
Себе как-то давно пометочку делал, теперь она из проекта в проект кочует с файлом настройки УСАППа:
Код:
/*
   Порядок обращение к регистрам:
   IBRD->FBRD->LCR_H, или FBRD->IBRD->LCR_H.
*/

стр. 324.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 14:25 
Не в сети

Зарегистрирован: 2018-мар-01 11:21
Сообщения: 14
Здравствуйте!
Хотелось бы уточнить один момент: в контроллерах серии 1986ве9х есть возможность определения начала приема у UART'a?
Пытаюсь реализовать modbus. Для определения окончания пакета включаю таймер в подпрограмме прерывания после каждого принятого байта, т.о. определяю задержку в 3,5 бита. Если к концу этого временного промежутка прием не начат, обрабатываю принятый пакет. Так вот, каким образом можно определить начал ли принимать данные UART, или нет?
Если это определить невозможно, то какими еще путями можно определить задержку в 3,5 бита, или окончания передачи пакета?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 14:58 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1145
Откуда: Тула
ТСКЯ.431296.001СП стр. 381 писал(а):
UARTRTINTR
Прерывание по таймауту приемника возникает в случае, если буфер FIFO приемника не
пуст, и на вход приемника не поступало новых данных в течение периода времени,
необходимого для передачи 32 бит. Прерывание по таймауту снимается либо после считывания
данных из буфера приемника до его опустошения (или считывания одного байта в случае, если
буфер FIFO запрещен), либо путем записи 1 в соответствующий бит регистра сброса
прерывания UARTICR.
Кажется из аппаратного - это всё...
ИМХО, существующий контроллер последовательного порта в ВЕ9х/1/3/4 не оптимизирован для модбасов...

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 15:12 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 73
Да никак не определишь, что прием символа начат, но но еще не завершен. Бит BUSY регистра UART->FR, например, работает только с передатчиком.
В вашем случае можно посмотреть на прерывание UARTRTINTR.

Цитата:
UARTRTINTR
Прерывание по таймауту приемника возникает в случае, если буфер FIFO приемника не
пуст, и на вход приемника не поступало новых данных в течение периода времени,
необходимого для передачи 32 бит. Прерывание по таймауту снимается либо после считывания
данных из буфера приемника до его опустошения (или считывания одного байта в случае, если
буфер FIFO запрещен), либо путем записи 1 в соответствующий бит регистра сброса
прерывания UARTICR.
(стр. 381 ТСКЯ.431296.001СП)


Конечно, пауза будет гораздо больше, чем 3,5 бита, но зато не надо никаких таймеров подцеплять. Я, во всяком случае, Modbus так и сделал.
Только аппаратный буфер приемника не забудьте включить.

ЗЫ:
Извиняюсь. Пока писал, то же самое уже ответили.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 15:25 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1145
Откуда: Тула
andelie писал(а):
Я, во всяком случае, Modbus так и сделал.
Только аппаратный буфер приемника не забудьте включить.
ЗЫ:
Извиняюсь. Пока писал, то же самое уже ответили.

Вот, кстати, вы приёмный буфер вычитываете до конца или оставляете немного?
Т.е. чтобы не случилось такого, что вычитали весь буфер, включая последний байт посылки и прерывания UARTRTINTR не произойдёт. Что приведёт к невызову ф-ции модбаса, если её вызов настроить (а это видимо единственный вариант в таком случае) на прерывание UARTRTINTR.

Кстати, с передачей в полудуплексе ещё веселее: если приёмопедедатчик физ.уровня как обычно включен с отключением приёмника при включении передатчика - то для засекания таймаута нужен аппаратный таймер.

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 15:35 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 73
Цитата:
Вот, кстати, вы приёмный буфер вычитываете до конца или оставляете немного?

На счет этого - бдительность :-). Если прерывание от RX, то в обработчике прерывания читаю один символ и кладу в программный буфер. Если же прерывание от RT, то высасываю аппаратный буфер до дна, кладу его содержимое в программный буфер и формирую Event, сообщающей соответствующей задаче, что входящий пакет готов и его надо обработать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 16:09 
Не в сети

Зарегистрирован: 2009-июл-21 14:13
Сообщения: 1145
Откуда: Тула
andelie писал(а):
Если прерывание от RX, то в обработчике прерывания читаю один символ ...

Вот о том и речь. На пример: настраиваете приёмный буфер на прерывание по заполнению на 7/8 (14 символов).
Если случается прерывание от приёмника UARTRXINTR, то вычитывать не один, а, допустим, 13 символов, оставляя 1 в буфере. Ну а дальше всё как у Вас. Когда скорость за мегабит - сильно снизит нагрузку на ядро.

В принципе, ответ на свой вопрос я кажется понял: всё соответствует тексту спецификации
Цитата:
если буфер FIFO приемника не пуст, и на вход приемника не поступало новых данных в течение периода времени, необходимого для передачи 32 бит.
хоть один там байт, хоть полон.

А ещё: как сделали контроль окончания передачи для переключения rx/tx?

_________________
сочувствующий…


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 16:39 
Не в сети

Зарегистрирован: 2014-июн-25 09:29
Сообщения: 73
Цитата:
А ещё: как сделали контроль окончания передачи для переключения rx/tx?

По-разному делал в зависимости от скорости передачи.
Для скоростей до 115200 кбит/с включительно ставил под Keil RTX программный таймер с дискретностью 1 мс или 100 мкс. Он реализован на основе Systick.
Для больших скоростей просто крутился в пустом цикле с подобранным количеством итераций. Отправку сообщений обычно выполняю с использованием DMA.
Кстати, Modbus никогда не делал на скоростях выше 115200 кбит/с. А другие протоколы неоднократно реализовывал.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: UART изменение скорости
СообщениеДобавлено: 2018-мар-23 17:15 
Не в сети

Зарегистрирован: 2010-сен-21 12:57
Сообщения: 666
Откуда: г. Санкт-Петербург
Lumpa писал(а):
...
Для определения окончания пакета включаю таймер в подпрограмме прерывания после каждого принятого байта, т.о. определяю задержку в 3,5 бита. Если к концу этого временного промежутка прием не начат, обрабатываю принятый пакет. Так вот, каким образом можно определить начал ли принимать данные UART, или нет?...

Если очень надо, то можно попробовать такое кривое решение:
1) Если вход приемника UART соединить с входом захвата таймера то:
1. Предварительно настроить вход захвата таймера на спад.
2. Прерывание по приему происходит во время стопового бита (в середине);
3. При входе в прерывание от приемника первым делом сбросить бит захвата в TIMER->STATUS (успеть пока стоп бит = 1)
4. Если есть вероятность, что не успеваете то проверить вход приемника на "1" (прочитать порт), если там "0" (старт бит или уже нулевой бит данных), то начался новый прием.
5. Включить задержку (таймер, прерывание и т.п.) на 3,5 бита
6. В конце задержки проанализировать событие захвата(если есть, значит начался новый прием).
На скорости 115200 на частоте ядра близкой к максимальной должны успеть (на всю процедуру у Вас 8,6 мкс).
2) Если есть возможность, то в течение задержки непрерывно читать порт приемника и проверять его на "0".


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 27 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 3


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

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB