Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: STM32 новичку в ARM что к чему

Чт май 26, 2022 17:04:13

Быть может, стоило бы прочесть Reference Manual, раздел USART? Потому что там очень доходчиво, даже с диаграммами, расписано всё. Можете через гугл-переводчик, если проблемы с английским


Читал, но я много чего там не понимаю. Не в смысле языка, а а смысле работы всего этого хозяйства. Например, мне не понятно, выставляется ли бит RXNE при срабатывании прерывания по Idle. Со временем, думаю, пойму.

Re: STM32 новичку в ARM что к чему

Чт май 26, 2022 19:23:43

Но ведь это несложно и проверить на деле.
Нет, не выставляется, ведь ничего не было принято, поскольку старт-бит и стоп-бит не были обнаружены, и запуска сдвигового регистра приема не было.
Во время приема флаг RXNE выставляется в конце приема байта, а флаг IDLE будет выставлен после того, как линия RX будет оставаться свободной в течение времени, равного длительности кадра (обычно 10 бит).
Флаг ORE (overrun) будет выставляться тогда, когда был принят новый байт, а предыдущий не был прочитан.


Код:
oid USART2_IRQHandler(void)
{
   /* Линия свободна (idle frame) */
   if((USART2->ISR & USART_ISR_IDLE)&&(USART2->CR1 & USART_CR1_IDLEIE))
   {
      Start_RTOTimer();
      USART2->ICR = USART_ICR_IDLECF;
   }

   /* Предыдущий принятый символ не был прочитан */
   if(USART2->ISR & USART_ISR_ORE)
   {
      ToRXBuff(USART2->RDR);
      USART2->ICR = USART_ICR_ORECF;
   }

   /* Символ был принят */
   if((USART2->ISR & USART_ISR_RXNE)&&(USART2->CR1 & USART_CR1_RXNEIE))
   {
      Stop_RTOTimer();
      ToRXBuff(USART2->RDR);
   }

   /* Готов к передаче символа */
   if((USART2->ISR & USART_ISR_TXE)&&(USART2->CR1 & USART_CR1_TXEIE))
   {
      uint8_t ch;
      if(FromTXBuff(&ch))
         USART2->TDR = ch;
      else
         USART2->CR1 &= ~USART_CR1_TXEIE;
   }

   /* Передача символа была завершена и передающий буфер пуст */
   if((USART2->ISR & USART_ISR_TC)&&(USART2->CR1 & USART_CR1_TCIE))
   {

   }

   /* Ошибка кадра в приемнике */
   if(USART2->ISR & USART_ISR_FE)
   {
      USART2->ICR = USART_ICR_FECF;
   }
}

причем, запуск RTO-таймера можно делать или в IDLE, или в RXNE. В последнем случае таймер не останавливается, а перезапускается с начала.
Так же, я настоятельно рекомендую использовать проверку не только флага источника прерывания, но и бита разрешения этого источника. Особенно это необходимо при передаче по TXE-флагу. Этот флаг устанавливается независимо от того, включен передатчик (TE) или выключен. И попадая в прерывание по другому источнику, будет лишняя загрузка передающего регистра. Именно с помощью запрета прерывания TXEIE прекращается передача (в варианте передачи по прерываниям).
Флаг TC устанавливается по завершению передачи символа, если в передающем буфере нет загруженных байтов (TXE = 1).

Ну и не надо писать if((USART1->SR & USART_SR_RXNE) >> USART_SR_RXNE_Pos) == 1), поскольку это излишние действия. Нужно отталкиваться от того, что по правилам языка Си, выражение в if() будет истинно при любом ненулевом значении. А запись USART1->SR & USART_SR_RXNE представляет собой логическую побитовую операцию AND с содержимым регистра и значением битовой маски. То есть, например 0110 AND 0100 = 0100, это есть ненулевое значение и условие if будет истинно и выполнится. Если же 0010 AND 0100 = 0000, то условие if будет ложно и не выполнится.

& - означает побитовую операцию AND двух чисел.
&& - означает логическое AND выражений: "если (ВЫРАЖЕНИЕ_1 = истина) И (ВЫРАЖЕНИЕ_2 = истина)"

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 07:19:06

НовыйДень писал(а):Но ведь это несложно и проверить на деле.
Нет, не выставляется, ведь ничего не было принято, поскольку старт-бит и стоп-бит не были обнаружены, и запуска сдвигового регистра приема не было.
Во время приема флаг RXNE выставляется в конце приема байта, а флаг IDLE будет выставлен после того, как линия RX будет оставаться свободной в течение времени, равного длительности кадра (обычно 10 бит).
Флаг ORE (overrun) будет выставляться тогда, когда был принят новый байт, а предыдущий не был прочитан.


"


Спасибо, ну прямо очень подробно! Сохранил себе в текстовый документ. Попробую!
Последний раз редактировалось Lum1noFor Пт май 27, 2022 09:20:08, всего редактировалось 2 раз(а).

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 07:41:12

Eddy_Em писал(а):У меня UART работает через DMA: где-то только передача, где-то - и передача, и прием. И я ни разу в жизни ни IDLE, ни RTO не использовал. ЧЯДНТ?

Расскажи, как ты определяешь конец сообщения, при приёме с использованием DMA?
Возможны всего два варианта: по паузе между байтами или по коду символа.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 09:22:31

Возможны всего два варианта: по паузе между байтами или по коду символа.

Не только.
Есть еще весьма широко распространенный вариант с ФИКСИРОВАННОЙ ДЛИНОЙ пакета.
Скажем, лично я использую во всех своих проектах именно такой вариант. Он происходит из простого факта применения в коммуникациях проекта, в том числе, кастомного HID USB с пакетом в 64 байта. Вот эти пакеты у меня везде и гуляют через DMA<->RS485/RS422.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 09:47:00

Расскажи, как ты определяешь конец сообщения, при приёме с использованием DMA?

Элементарно: в STM32F0x2 есть прерывание по символу. Вот я по '\n' и вызываю прерывание, выключаю в нем DMA, меняю местами буферы и выставляю флаг готовности принятой строки. А DMA тем временем во второй буфер поступающие данные копит.
Там, где нет такого прерывания, я обычно прием без DMA делаю. Потому как пользователь не обязан отправлять блоки строго по одной строке: может и несколько строк отправить, а у меня логическая единица - одна строчка. Вот, чтобы не париться с промежуточным буфером, который будет на токены принятое разделять, я и заканчиваю прием строго на '\n', меняю буферы и выставляю флаг готовности.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 09:52:21

Возможны всего два варианта: по паузе между байтами или по коду символа.

Не только.
Есть еще весьма широко распространенный вариант с ФИКСИРОВАННОЙ ДЛИНОЙ пакета.
Скажем, лично я использую во всех своих проектах именно такой вариант. Он происходит из простого факта применения в коммуникациях проекта, в том числе, кастомного HID USB с пакетом в 64 байта. Вот эти пакеты у меня везде и гуляют через DMA<->RS485/RS422.

Ага, а если последний байт пакета не потеряется, например, с передатчика сняли питание? Тогда как? Опять звать на помощь таймер для измерения длительности паузы при приёме? Или тупо ждать следующего пакета, чтоб не заводить таймер? В итоге всё равно не получается третий вариант, однако.

Добавлено after 2 minutes 23 seconds:
Расскажи, как ты определяешь конец сообщения, при приёме с использованием DMA?

Элементарно: в STM32F0x2 есть прерывание по символу. Вот я по '\n' и вызываю прерывание, выключаю в нем DMA, меняю местами буферы и выставляю флаг готовности принятой строки. А DMA тем временем во второй буфер поступающие данные копит.
Там, где нет такого прерывания, я обычно прием без DMA делаю. Потому как пользователь не обязан отправлять блоки строго по одной строке: может и несколько строк отправить, а у меня логическая единица - одна строчка. Вот, чтобы не париться с промежуточным буфером, который будет на токены принятое разделять, я и заканчиваю прием строго на '\n', меняю буферы и выставляю флаг готовности.

Так ведь я тебя и спрашивал, по паузе или коду символа? То есть по коду символа, как и ожидалось. Ибо по-другому никак.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 09:59:00

а если последний байт пакета не потеряется, например, с передатчика сняли питание? Тогда как?

Ну сняли и сняли. Пропадет последний незавершенный и первый пакет после включения. Первый после включения завершит сессию DMA и перезапустит ожидание адресного байта.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 10:02:08

а если последний байт пакета не потеряется, например, с передатчика сняли питание? Тогда как?

Ну сняли и сняли. Пропадет последний незавершенный и первый пакет после включения. Первый после включения завершит сессию DMA и перезапустит ожидание адресного байта.

Хм, то есть факт потери связи зафиксирован не будет.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 10:04:27

tonyk, почему же по-другому - никак? Можно и по таймауту. Только придется городить промежуточную буферизацию (кольцевой буфер) с построчной выдачей.
Я вот баловался с передачей по USB, используя кольцевой буфер — чтобы максимально увеличить скорость выдачи данных и избавиться от блокирующих операций.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 10:21:12

Хм, то есть факт потери связи зафиксирован не будет.

Почему не будет? Будет. Это делает хост (сиречь программа в винде). А девайсу болт положить на связь. Его функционирование никак с наличием обмена не связано. Через обмен идет управление и мониторинг. Все это не обязательно.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 10:47:53

Eddy_Em писал(а):Элементарно: в STM32F0x2 есть прерывание по символу. Вот я по '\n' и вызываю прерывание, выключаю в нем DMA, меняю местами буферы и выставляю флаг готовности принятой строки.
а контроль переполнения буфера как реализован? а то ведь это классическая дыра...

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 11:02:36

контроль переполнения буфера как реализован?

Очевидно, что по прерыванию от ДМА. Только не переполнение, а заполненный буфер.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 11:31:28

Eddy_Em писал(а):Можно и по таймауту. Только придется городить промежуточную буферизацию (кольцевой буфер) с построчной выдачей.

А можно ничего не городить, а использовать уже имеющийся во всех STM32 IDLE или, что лучше, RTO. :)))

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 11:40:03

использовать уже имеющийся во всех STM32 IDLE или, что лучше, RTO. :)))

А кто сказал, что байты должны идти "ноздря в ноздрю"? Может, между ними по 2-4 свободных фрейма? И окончанием передачи считать, скажем, паузу дольше 100мс после последнего байта…
Я таймауты вообще на терминале тестировал, у меня был выставлен таймаут в 3 секунды (уж за три-то секунды я успею следующий символ набрать =D)

Что до переполнения буфера: а как он переполнится, когда прием идет посредством DMA? По заполнению буфера идет прерывание, и коль не было '\n' в процессе, считаем строку бажной и сбрасываем нафиг с выставлением флага ошибки (т.е. следующий пакет тоже нужно будет выбросить).

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 12:29:40


ухты как классно сделано! взял себе

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 12:32:30

Eddy_Em писал(а):А кто сказал, что байты должны идти "ноздря в ноздрю"? Может, между ними по 2-4 свободных фрейма?

А ты поставь в настройках терминала, чтоб он отправлял сразу всю строку по нажатию "Enter", вот твои байты и пойдут ноздря-в-ноздрю.

Re: STM32 новичку в ARM что к чему

Пт май 27, 2022 17:05:58

Одного универсального способа нет, всегда пишется под конкретную задачу. Где-то пакеты все одинаковой длины, где-то разной длины, но начинаются/заканчиваются определенными символами, где-то инфа в нетекстовом виде и нет определенного завершающего символа, где-то разрозненные символы с произвольными промежутками, где-то минимальные промежутки между пакетами регламентированы, а где-то есть контроль четности. Где-то очень высокая скорость порта и нужен DMA на прием/отправку, а где-то скорость низкая по отношению к частоте МК, да еще и занят нужный канал DMA.
Вобщем, ты владеешь несколькими методами работы и выбираешь в конкретном случае наиболее подходящий. Так и везде, в принципе то. Поэтому спорить, что дескать только DMA форева или стопудово только прерывания - не имеет смысла.

Re: STM32 новичку в ARM что к чему

Вт июн 14, 2022 10:01:26

Уважаемые знатоки, подскажите в решении проблемы. Использовал STM32F051 совместно с отладчиком BlackMagik. Сначала всё работало как часы, прошивало, отлаживало. Но в один момент чип перестал видиться отладчиком. Достал ST-Link. С ним теперь возможна только запись прошивки из-под ресета через родную прогу, без отладки. Пин BOOT0 сидит на земле, то есть используется запуск из прошивки флеш, пины SWD в проекте вообще не заняты и нигде не переназначаются. Куда копать для восстановления нормальной работы SWD?

Re: STM32 новичку в ARM что к чему

Вт июн 14, 2022 10:21:40

наверно отключили swd в настройках cubeide
Ответить