STM32 новичку в ARM что к чему
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
В F103 нет прерывания по Idle. Так что, работа с таймером из прерываний.
- Реклама
- Сообщения: 65
- Зарегистрирован: Ср сен 24, 2014 12:30:09
8 бит команду я привел только для примера в описании принципа работы. В реальном варианте команда состоит из 10 бит. С DMA я работать не умею, на разбирательство уйдет много времени, так как я пишу полностью на регистрах, без HAL или чего-то подобного. Поэтому DMA пока отпадает. Единственное, что я ещё не попробовал - это насильно сбросить флаг прерывания USART1 сразу же после входа в него. В обычном режиме этот флаг сбрасывается сам после чтения из регистра USART1->DR. Есть шанс, что контроллер увидит, что прерывание уже "отработало" и не нужно в него возвращаться по стеку. Доберусь до компьютера в понедельник - проверю.
- Сообщения: 362
- Зарегистрирован: Вс апр 03, 2022 07:01:29
DMA тут особо то и нафик не нужен. Хотя конечно вам надобно его изучить, там не сложно. Но в конкретно этом примере он как бы что он есть, что его нет, не важно.

Idle character
When an idle frame is detected, there is the same procedure as a data received character
plus an interrupt if the IDLEIE bit is set.
(При обнаружении состояния Idle выполняется такая же процедура, как и при нормальном приеме, плюс прерывание IDLEIE, если оное разрешено).
Bit 4 IDLE: IDLE line detected
This bit is set by hardware when an Idle Line is detected. An interrupt is generated if the
IDLEIE=1 in the USART_CR1 register. It is cleared by a software sequence (an read to the
USART_SR register followed by a read to the USART_DR register).
0: No Idle Line is detected
1: Idle Line is detected
Note: The IDLE bit will not be set again until the RXNE bit has been set itself (i.e. a new idle
line occurs).
(Этот бит устанавливается аппаратно при обнаружении состояния Idle (свободная линия). Прерывание генерируется если бит IDLEIE=1 в регистре USART_CR1.
Сброс бита IDLE методом чтения регистра состояния SR и регистра данных DR)
Вначале после запуска UART и разрешения приема через интервал полного байта будет обнаружено состояние Idle и сгенериурется прерывание по этому событию. В этом прерывании нужно сбросить счетчик принятых байт на 0 (или запустить канал DMA на ожидание приема нужного числа байт). Сбросить бит состояния Idle как выше написано. Затем принимать байты в прерывании или по DMA. Когда внешнее устройство прекратит передачу, оно освободит линию и будет детектировано состояние Idle снова. Снова произойдет прерывание, и в нем проверяем, сколько байт принято - либо через программный счетчик, либо через счетчик CNTR в DMA (он считает назад до 0).
Если приняты не все байты, можно считать, что произошел разрыв передачи пакета. Дальше уже как хотите - либо целиком отбросить пакет, как неполный, либо запустить таймер и ждать какое-то время (тайм-аут).
Но обычно в пакете все байты передаются неразрывно. Тут уж надо знать конкретную ситуацию, как конкретно ведет себя передающее устройство.
Так же, коммуникация через UART обычно подразумевает некоторые специальные символы (из набора ANSI) для обозначения начала и конца пакета.
[uquote="Lum1noFor",url="/forum/viewtopic.php?p=4235239#p4235239"]. В обычном режиме этот флаг сбрасывается сам после чтения из регистра USART1->DR. Есть шанс, что контроллер увидит, что прерывание уже "отработало" и не нужно в него возвращаться по стеку. .[/uquote]
Эммм. чота я не понял момента. В мануале сказано:
In single buffer mode, clearing the RXNE bit is performed by a software read to the
USART_DR register. The RXNE flag can also be cleared by writing a zero to it. The
RXNE bit must be cleared before the end of the reception of the next character to avoid
an overrun error.
(Сброс бита RXNE выполняется программным чтением регистра DR, либо записью 0 в этот бит.
Бит RXNE должен быть сброшен до момента окончания приема следующего байта, чтобы не произошла ошибка переполнения приемного буфера)
Чой-то нет? Есть! RM0008:В F103 нет прерывания по Idle.
Idle character
When an idle frame is detected, there is the same procedure as a data received character
plus an interrupt if the IDLEIE bit is set.
(При обнаружении состояния Idle выполняется такая же процедура, как и при нормальном приеме, плюс прерывание IDLEIE, если оное разрешено).
Bit 4 IDLE: IDLE line detected
This bit is set by hardware when an Idle Line is detected. An interrupt is generated if the
IDLEIE=1 in the USART_CR1 register. It is cleared by a software sequence (an read to the
USART_SR register followed by a read to the USART_DR register).
0: No Idle Line is detected
1: Idle Line is detected
Note: The IDLE bit will not be set again until the RXNE bit has been set itself (i.e. a new idle
line occurs).
(Этот бит устанавливается аппаратно при обнаружении состояния Idle (свободная линия). Прерывание генерируется если бит IDLEIE=1 в регистре USART_CR1.
Сброс бита IDLE методом чтения регистра состояния SR и регистра данных DR)
Вначале после запуска UART и разрешения приема через интервал полного байта будет обнаружено состояние Idle и сгенериурется прерывание по этому событию. В этом прерывании нужно сбросить счетчик принятых байт на 0 (или запустить канал DMA на ожидание приема нужного числа байт). Сбросить бит состояния Idle как выше написано. Затем принимать байты в прерывании или по DMA. Когда внешнее устройство прекратит передачу, оно освободит линию и будет детектировано состояние Idle снова. Снова произойдет прерывание, и в нем проверяем, сколько байт принято - либо через программный счетчик, либо через счетчик CNTR в DMA (он считает назад до 0).
Если приняты не все байты, можно считать, что произошел разрыв передачи пакета. Дальше уже как хотите - либо целиком отбросить пакет, как неполный, либо запустить таймер и ждать какое-то время (тайм-аут).
Но обычно в пакете все байты передаются неразрывно. Тут уж надо знать конкретную ситуацию, как конкретно ведет себя передающее устройство.
Так же, коммуникация через UART обычно подразумевает некоторые специальные символы (из набора ANSI) для обозначения начала и конца пакета.
[uquote="Lum1noFor",url="/forum/viewtopic.php?p=4235239#p4235239"]. В обычном режиме этот флаг сбрасывается сам после чтения из регистра USART1->DR. Есть шанс, что контроллер увидит, что прерывание уже "отработало" и не нужно в него возвращаться по стеку. .[/uquote]
Эммм. чота я не понял момента. В мануале сказано:
In single buffer mode, clearing the RXNE bit is performed by a software read to the
USART_DR register. The RXNE flag can also be cleared by writing a zero to it. The
RXNE bit must be cleared before the end of the reception of the next character to avoid
an overrun error.
(Сброс бита RXNE выполняется программным чтением регистра DR, либо записью 0 в этот бит.
Бит RXNE должен быть сброшен до момента окончания приема следующего байта, чтобы не произошла ошибка переполнения приемного буфера)
если я правильно понял расклад,
запускайте таймер при приеме первого байта, а при приеме последующих обнуляйте таймер;
пока байты приходят с приемлемой паузой - прерывания от таймера не будет.
запускайте таймер при приеме первого байта, а при приеме последующих обнуляйте таймер;
пока байты приходят с приемлемой паузой - прерывания от таймера не будет.
- Сообщения: 1379
- Зарегистрирован: Вт ноя 19, 2019 06:10:18
IDLE- это обрубок, то, что остаётся у несчастного после кастрации.
За неимением лучшего, использовал его при реализации Модбас, работающем с использованием DMA. По-идее, IDLE задуман как детектор ошибок для Модбас, а нормальный UART, помимо IDLE, содержит ещё RTO. Если предполагается активное использование UART для коммуникаций, то я бы взял МК с полноценным UART. В F1 и F4 таких нет. В остальных надо внимательно смотреть. Как правило, это старшие МК в линейках. Кстати, RTO, если не ошибаюсь, идёт в комплекте с блоком автоуправления сигналом DE трансивера для RS-485.
За неимением лучшего, использовал его при реализации Модбас, работающем с использованием DMA. По-идее, IDLE задуман как детектор ошибок для Модбас, а нормальный UART, помимо IDLE, содержит ещё RTO. Если предполагается активное использование UART для коммуникаций, то я бы взял МК с полноценным UART. В F1 и F4 таких нет. В остальных надо внимательно смотреть. Как правило, это старшие МК в линейках. Кстати, RTO, если не ошибаюсь, идёт в комплекте с блоком автоуправления сигналом DE трансивера для RS-485.
- Реклама
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
[uquote="НовыйДень",url="/forum/viewtopic.php?p=4235268#p4235268"]Чой-то нет? Есть![/uquote]Это не тот idle, что нужен. В F103 только таймер.
- Сообщения: 362
- Зарегистрирован: Вс апр 03, 2022 07:01:29
Тююю, а який Idle нужон тады? В каком-нить F746 точно такой же Idle, как и в F103, потому как Idle - это состояние неактивности более величины кадра. Таймаут, принятый в модбасе, тут не рассматривается, это другое. А Idle frame у уарта - это свободная линия более длины одного кадра.Это не тот idle
Последний раз редактировалось НовыйДень Сб май 21, 2022 18:54:11, всего редактировалось 2 раза.
Lum1noFor,
да даже в Вашем алгоритме можно,
зачем же Вы обнуляете счетчик, ставьте -1 что ли.
зачем использовать признак другого статуса.
да даже в Вашем алгоритме можно,
зачем же Вы обнуляете счетчик, ставьте -1 что ли.
зачем использовать признак другого статуса.
- Сообщения: 65
- Зарегистрирован: Ср сен 24, 2014 12:30:09
Идею понял, благодарю. Один знакомый также подкинул интересную идею обнулять таймер по прерыванию EXTI от ноги RX. То есть любую другую ногу спаивать с RX, и вншать на нее EXTI. Если RX дергается - обнулять таймер. Попробую все, что советовали - и Idle, и таймер. Всем спасибо.
- Сообщения: 362
- Зарегистрирован: Вс апр 03, 2022 07:01:29
EXTI не обязательно. Ровно то же действие будет иметь любое прерывание от UART.
Знакомый прикололся?
Это сколько прерываний на один байт будет?
Выключать/включать будете? - плюсом еще одна задача.
Это сколько прерываний на один байт будет?
Выключать/включать будете? - плюсом еще одна задача.
- Сообщения: 65
- Зарегистрирован: Ср сен 24, 2014 12:30:09
Прошу прощения, он не говорил именно про EXTI - у меня уже бошка не работает под вечер, чушь сказал. Он советовал обнулять таймер через ногу RX и все. А вот как - не сказал. Это я уже сам по перегрузу мозгов напридумывал.
извратится на аппаратный сброс таймера можно, только не у всякого таймера вход, на который можноб было повесить эту функцию, выведен наружу.
да и зачем, неужели с уартом не хватает времени.
да и зачем, неужели с уартом не хватает времени.
- Сообщения: 2516
- Зарегистрирован: Пт июл 12, 2019 22:52:01
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Вы что, прикалываетесь? Запускаете любой самый простой свободный таймер на переполнение. В каждом прерывании по приходу байта обнуляете его. В прерывании переполнения таймера получаете ваш таймаут.
Добавлено after 1 minute 39 seconds:
Eddy_Em, ты через сообщение как рецепт от всех бед "конченые автоматы" рекомендуешь. Можешь пример их применения/реализации показать?
Добавлено after 1 minute 39 seconds:
Eddy_Em, ты через сообщение как рецепт от всех бед "конченые автоматы" рекомендуешь. Можешь пример их применения/реализации показать?
спад на PA6 сбросит TIM3 (см. rm0008 15.3.14 Timers and external trigger synchronization )
TIM3->SMCR = (TIM_SMCR_TS_0 |TIM_SMCR_TS_2 |TIM_SMCR_SMS_2); // TS=101 (PA6) SMS=100 (reset)
TIM3->CCMR1 = 0;
TIM3->CCER = TIM_CCER_CC1P;
но в данном случае потребности в таком замуте нет никакой.
И да, прерывания дополнительно еще придется разруливать.
TIM3->SMCR = (TIM_SMCR_TS_0 |TIM_SMCR_TS_2 |TIM_SMCR_SMS_2); // TS=101 (PA6) SMS=100 (reset)
TIM3->CCMR1 = 0;
TIM3->CCER = TIM_CCER_CC1P;
но в данном случае потребности в таком замуте нет никакой.
И да, прерывания дополнительно еще придется разруливать.
- Сообщения: 1379
- Зарегистрирован: Вт ноя 19, 2019 06:10:18
[uquote="Lum1noFor",url="/forum/viewtopic.php?p=4235432#p4235432"]Идею понял, благодарю. Один знакомый также подкинул интересную идею обнулять таймер по прерыванию EXTI от ноги RX. То есть любую другую ногу спаивать с RX, и вншать на нее EXTI. Если RX дергается - обнулять таймер. Попробую все, что советовали - и Idle, и таймер. Всем спасибо.[/uquote]
Люди, вы читать не умеете? В F1 есть IDLE и он нормально функционирует. У меня на нём Модбас работает. Щас поищу ту давнишнюю прогу.
Люди, вы читать не умеете? В F1 есть IDLE и он нормально функционирует. У меня на нём Модбас работает. Щас поищу ту давнишнюю прогу.
- Сообщения: 362
- Зарегистрирован: Вс апр 03, 2022 07:01:29
Вот именно. А то кое-кто тут (не будем показывать пальцем на этого "героя", он просто перепутал слова по незнанию) говаривал, дескать нету в F103 Idle. Хе, кудаж без него то! В F103 нету Receive TimeOut Flag(RTOF), который есть в F0, F3, F7. Но это как бы не шибко большая беда.
- Сообщения: 2567
- Зарегистрирован: Вт май 01, 2018 19:44:47
Только и можете что к словам цепляться и зубоскалить. Lum1noFor нужен именно таймаут. Зачем вы ему Idle втюхиваете?
- Сообщения: 362
- Зарегистрирован: Вс апр 03, 2022 07:01:29
Так вначале думай, потом пиши. А коль уж ошибся, то скажи, что дескать погорячился, бывает. Все поймут и без зубоскальства.
А прерывание то одно, что для Idle, что для приема, что для ошибки кадра. Но Idle Flag является средством разграничения пакетов в посылке. В нормальном режиме именно по обнаружению Idle производится запуск и останов DMA-приема. И если стоит задача реализовать таймаут без RTOF, то после обнаружения Idle в фазе приема пакета нужно запустить таймер на выбранный интервал, но не сбрасывать счетчик DMA. Как только сработает прерывание таймера, только тогда можно считать пакет полностью принятым и перезапустить счетчик DMA, а пакет отдать на разбор.
А прерывание то одно, что для Idle, что для приема, что для ошибки кадра. Но Idle Flag является средством разграничения пакетов в посылке. В нормальном режиме именно по обнаружению Idle производится запуск и останов DMA-приема. И если стоит задача реализовать таймаут без RTOF, то после обнаружения Idle в фазе приема пакета нужно запустить таймер на выбранный интервал, но не сбрасывать счетчик DMA. Как только сработает прерывание таймера, только тогда можно считать пакет полностью принятым и перезапустить счетчик DMA, а пакет отдать на разбор.
Последний раз редактировалось НовыйДень Вс май 22, 2022 11:55:10, всего редактировалось 1 раз.


