Эволюционирую проект из Bare Metal до RTOS использую CubIDE. В проекте АЦП работает по прерыванию от таймера, в прерывании цикл с остановом по тикам таймера - дергает ножками АЦП для её запуска. В RTOS сделать цикл с остановкой по таймеру не удаётся. Спойлер
for (volatile __IO uint32_t i = 0, f = 0; f <255 ;[b][u] f = htim->Instance->CNT[/u][/b]) { i = htim->Instance->CNT; if (i > 6) f = 255; if(htim->Instance->CNT != last) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); last = htim->Instance->CNT; } } } }
for (volatile __IO uint32_t i = 0, f = 0; f <255 ; [b][u]f ++[/u][/b]) { i = htim->Instance->CNT; if (i > 6) f = 255; if(htim->Instance->CNT != last) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); last = htim->Instance->CNT; } } } }
Работает и показывает ожидаемую картинку в 3 импульса. Помогите кто чем может. Отладчик в обоих случаях значения
Код:
htim->Instance->CNT
не показывает - всегда 0. Хочу понять что я не так делаю и как мне реализовать требуемый функционал - цикл в котором буду дергать ножки АЦП контролируя временные интервалы.
_________________ _____ Поделиться рецептом можно в ЛС
Вещества все забористые, иное уже не берет. Не могу никак запустить цикл по таймеру в прерываниях. Без подключения RTOS работает. АЦП внешний. Какой именно не суть важно, формулировка была неудачная в первом сообщении - проблема с таймерами, а не с АЦП. Просто нужно ткнуть носом, что не так с таймерами.
_________________ _____ Поделиться рецептом можно в ЛС
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
таймер - это не счётчик. Забудьте о существовании CNT Не удивлюсь, если то что Вы хотите таймер может выполнять сам. А чтоб это настроить читайте как устроены таймеры у stm32 (или у Вас другая платформа?)
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Суть важно. Есть подозрение, что ТС не с того бока подходит к вопросу. Глядя на обработчик прерывания, у меня тоже возник вопрос о веществах, принятых ТС перед его написанием.
Счас буду нести бред: Как позже выяснилось проблема не совсем с RTOS в новом проекте без ОС тоже повторяется. У меня работает в другом проекте на этой же отладочной плате из этого же STM32CubeIDE: один таймер вызывает прерывание каждые 100 мкс, другой используется для контроля времени выхода из прерывания и контроля тайминга дергания ножками внешней АЦП. В последующих проектах воспроизвести этот функционал не удаётся с одинаковыми настройками... Причём самый бред в том, что:Спойлер
Код:
for (uint32_t i = 0, f = 0;( (__HAL_TIM_GET_COUNTER(htim) < 6) ); f ++ ) //(f < 255) && - не работает for (uint32_t i = 0, f = 0;( (f < 255) &&(__HAL_TIM_GET_COUNTER(htim) < 6) ); f ++ ) // работает как и хотелось до 6 тиков
В чём магия? Отладчик ни в одном случае CNT регистр таймеров мне не показывает...
Суть важно. Есть подозрение, что ТС не с того бока подходит к вопросу. Глядя на обработчик прерывания, у меня тоже возник вопрос о веществах, принятых ТС перед его написанием.
В обработчике простой код для проверки - дергаю ножкой, которая поближе ко мне, чтобы в неё щупом тыкать поудобней было.
_________________ _____ Поделиться рецептом можно в ЛС
Как раз с этого всё и началось код в файле подготовленном для управления АЦП содержал:
Код:
while ((__HAL_TIM_GET_COUNTER(htim) < Start_Limit) && !flag_2)
И теперь оно не работает... почему я ника не пойму
Код:
for (uint32_t i = 0, f = 0;( (f < 255) && (__HAL_TIM_GET_COUNTER(htim) < 6) ); f ++ ) //
Это уже кривые потуги разобраться в чём дело, я ж не такой профи, чтобы ассемблер вызывать и вообще. Могу штатный дебаггер запустить, но он не помогает, CNT всегда пустой... Есть мысль, что какой-то системный счётчик срабатывает пока в конструкции "while(__HAL_TIM_GET_COUNTER(htim)<6)" счетчик CNT не меняется, система считает, что получился "бесконечный цикл". А если в условии добавляется "(f < 255) && (__HAL_TIM_GET_COUNTER(htim) < 6)" и в цикле " f ++ ", то такой ошибки не возникает. Но из меня специалист так себе... ткните носом пжлст.
_________________ _____ Поделиться рецептом можно в ЛС
Не надо мудрить. Если задача подождать пока счётчик станет равен 6, то так и надо писать "подождать пока счётчик меньше 6". Если не работает, то либо счётчик не тикает, либо читается не тот счётчик. Открываем отладчик, листинг и смотрим. Введение 100500 переменных-счётчиков цикла только усложняет отладку. Вот скажите, зачем в цикле переменная i ? Ну так, чисто поржать.
Грешно смеяться над больными людьми. Стыдно. Лучше подскажите почему в цикле условие по таймеру не хочет работать без дополнительных 100500 переменных счётчиков цикла...
_________________ _____ Поделиться рецептом можно в ЛС
/* USER CODE BEGIN 4 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { int f = 0; HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12); while ((__HAL_TIM_GET_COUNTER(htim) < 16) && (f < 65534) ) //&& (f < 65534) { f++;
if (__HAL_TIM_GET_COUNTER(htim) != last) { HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_13); last = __HAL_TIM_GET_COUNTER(htim); } } HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12|GPIO_PIN_13, GPIO_PIN_RESET); } /* USER CODE END 4 */
//F429ZI (Nucleo & Discovery) Спойлер
Код:
/* USER CODE BEGIN 4 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { int f = 0; HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); while ((__HAL_TIM_GET_COUNTER(htim) < 6) & (f < 200)) { f++;
if (__HAL_TIM_GET_COUNTER(htim) != last) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); last = __HAL_TIM_GET_COUNTER(htim); } } HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5|GPIO_PIN_9, GPIO_PIN_RESET); } /* USER CODE END 4 */
Нигде не работает условие вида "while (__HAL_TIM_GET_COUNTER(htim) < 6)" только если условие "while ((__HAL_TIM_GET_COUNTER(htim) < 16) && (f < 65534) )" и в коде "f++". СпойлерУ f103C6T6 медленно пины переключаются, на разницу "(__HAL_TIM_GET_COUNTER(htim) < 6)" и "(__HAL_TIM_GET_COUNTER(htim) < 16)" не стоит обращать внимания
Если не работает, то либо счётчик не тикает, либо читается не тот счётчик.
Эти два варианта, я так понимаю, вы уже проверили?
Проверил. Когда "работает" я вижу на осциллографе то количество фронтов которое и ожидал - 6 для F429 и 8 для F103 (код выше). У 103 медленно ноги дергает потому фронты 1 к 2 тикам таймера. Я так думаю.
_________________ _____ Поделиться рецептом можно в ЛС
Таймер же в этот момент начинает с 0 считать, верно? В это же суть прерываний и организации "Real Time" кода? Я и собираюсь первые несколько тиков взять на подёргать ножками. В чём прикол я не понял. Вещества тяжелые с юмором туго.
_________________ _____ Поделиться рецептом можно в ЛС
когда Вы включаете счетчик по f - зависаете в одном обработчике, и у таймера есть время по тикать; нет этого счетчика - Вы каждый раз в новом прерывании и cnt опять еще только =0
Последний раз редактировалось a797945 Вт мар 28, 2023 14:21:04, всего редактировалось 1 раз.
когда Вы включаете счетчик по f - зависаете в одном обработчике, нет этого счетчика - Вы каждый раз в новом прерывании и cnt опять еще только =0
А почему так-то? Я хотел, чтобы код вида: Спойлер
Код:
/* USER CODE BEGIN 4 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); while ((__HAL_TIM_GET_COUNTER(htim) < 6) ) { if (__HAL_TIM_GET_COUNTER(htim) != last) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); last = __HAL_TIM_GET_COUNTER(htim); } } HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5|GPIO_PIN_9, GPIO_PIN_RESET); } /* USER CODE END 4 */
дал мне 6 фронтов вот и всё, а почему без без "f" не получается я не понимаю, но вряд-ли дело в выходе из прерывания. Т.к. когда код имеет вид как в этом посте ничего не работает HardFault как я понимаю. Я выше писал Спойлер
Цитата:
Есть мысль, что какой-то системный счётчик срабатывает пока в конструкции "while(__HAL_TIM_GET_COUNTER(htim)<6)" счетчик CNT не меняется, система считает, что получился "бесконечный цикл". А если в условии добавляется "(f < 255) && (__HAL_TIM_GET_COUNTER(htim) < 6)" и в цикле " f ++ ", то такой ошибки не возникает. Но из меня специалист так себе...
Мысль в общем такая, но как это выявить я не знаю.
_________________ _____ Поделиться рецептом можно в ЛС
я не знаю Хал, первая ссылка гугля про HAL_TIM_PeriodElapsedCallback сказала - это обработчик по переполнению - т.е. таймер оттикал период и снова =0. с помощью Вашего f++ - Вы ЗАДЕРЖИВАЕТЕСЬ в обработчике и можете дождаться нужного тика таймера.
у таймера есть каналы и флаги, на необходимость пользоваться CNT я пока не натыкался.
Последний раз редактировалось a797945 Вт мар 28, 2023 14:35:23, всего редактировалось 1 раз.
я не знаю Хал, первая ссылка гугля про HAL_TIM_PeriodElapsedCallback сказала - это обработчик по переполнению - т.е. таймер оттикал период и снова =0. с помощью Вашего f++ - Вы ЗАДЕРЖИВАЕТЕСЬ в обработчике и можете дождаться нужного тика таймера.
Я думал, что while ((__HAL_TIM_GET_COUNTER(htim) < 6) ) в функции HAL_TIM_PeriodElapsedCallback обеспечит мне задержку в прерывании на 6 тиков таймера, но такой код вызывает системную ошибку. А как мне добиться выполнения кода вида Спойлер
Код:
/* USER CODE BEGIN 4 */ void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_9); while ((__HAL_TIM_GET_COUNTER(htim) < 6) ) { if (__HAL_TIM_GET_COUNTER(htim) != last) { HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5); last = __HAL_TIM_GET_COUNTER(htim); } } HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5|GPIO_PIN_9, GPIO_PIN_RESET); } /* USER CODE END 4 */
без костылей в виде "f++"?
_________________ _____ Поделиться рецептом можно в ЛС
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 28
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения