Доброго дня, форумчане! Кодю в keil(язык си), на stm32f401ccu6. Проблема такая: реализовал я 2 ШИМ сигнала для сервоприводов(TIM и TIM2), хочу реализовать третью ШИМку на TIM3, но почему то сигнала нет. Все делаю через CUBEMX. Почитал в инете люди пишут что у них тоже так было якобы CUBEMX тупит. После этого я решил реализовать ШИМку записями значений напрямую в регистр и тут возникает у меня основная проблема: значения в регистры тупо не записываются(смотрите фото).
На таймере два у меня уже реализована ШИМка через CubeMX и все работает норм, для теста я решил реализовать ШИМку на TIM2 через записями напрямую в регистры. реализовал, захожу под отладку и при записи значения в регистр ничего не изменяется(то есть значения не записываются), что самое интересное именно во все регистры таймера (TIM2->CR1; TIM2->ARR; и тд) ничего не записывается а во все регистры GPIO все записывается как надо.
из-за чего такое может быть? Пробовал подключать разные заголовочные файлы, а то есть где структуры этих регистров и тд, но все равно в эти регистры значения не записываются. Кто знает из-за чего это?
На будущее - вместо "магических цифр" общепринято использовать текстовые дефайны: RCC_APB1ENR_TIM2EN, TIM_CCER_CC3E и тд. TIM2->PSC = 1000 - 1; // предделитель = 1000. (потому что коэф.деления равен PSC+1) TIM2->ARR = 500 - 1; // максимальный счет до 499 (то же самое, значение ARR на 1 меньше коэф.деления) GPIOB->MODER |= (2 << (10 * 2)) или лучше GPIO_MODER_MODER10_1
Так вам самим понятнее будет, что там понаписано. Запомнить обозначения несложно, они состоят из трех частей, разделенных _ . Первая часть - имя модуля (вернее, структуры регистров), например GPIO или TIM (номер таймера или буква порта не указывается). Вторая часть - имя регистра - MODER, CCER. И в конце - имя бита или группы бит - TIM2EN, MODER10. В группе бит для обозначения отдельного бита после _ идет его номер в группе - MODER10_1. Потому что на память мало кто помнит именно позиции битов, а тут еще и переводить вначале в двоичный вид из хекс-вида.
Так же следует изучить, что такое операция |= в языке Си. А также, операция &= и ~. Эти операции применяются, когда нужно изменить только часть битов в регистре. Например, GPIOB->MODER |= GPIO_MODER_MODER10_1 | GPIO_MODER_MODER11_1; // установить только биты MODER10_1 и MODER11_1 RCC->APB1ENR &= ~(RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN); // сбросить только биты TIM2EN и TIM3EN
Приглашаем 3 декабря 2024 на вебинар, посвященный силовым модулям ведущего китайского производителя SUNCO - одного из мировых лидеров по производству дискретных полупроводниковых компонентов. На вебинаре вы узнаете о новинках, включая модули 17 класса в корпусе E3, и контроле качества на всех этапах производства. Вы также узнаете о новейших продуктах – IGBT-, SiC-, диодных и тиристорных модулях, погрузитесь в современные топологии, сравните характеристики IGBT-чипов разных поколений.
Так вам самим понятнее будет, что там понаписано. Запомнить обозначения несложно, они состоят из трех частей, разделенных _ . Первая часть - имя модуля (вернее, структуры регистров), например GPIO или TIM (номер таймера или буква порта не указывается). Вторая часть - имя регистра - MODER, CCER. И в конце - имя бита или группы бит - TIM2EN, MODER10. В группе бит для обозначения отдельного бита после _ идет его номер в группе - MODER10_1. Потому что на память мало кто помнит именно позиции битов, а тут еще и переводить вначале в двоичный вид из хекс-вида.
Более того, составные части имён этих дефайнов совпадают с таковыми в букваре и всегда можно там поискать через Ctrl+F.
Всплески перенапряжения являются серьезной угрозой надежности работы радиоэлектронных устройств. Причины их появления различны, это могут быть коммутационные переходные процессы в системе электропитания устройств, разряды молний, электростатические разряды. Для создания эффективной и современной системы защиты от ЭСР компания SUNCO разработала надежные и качественные супрессоры, представляющие собой TVS- и ESD-диоды, а также сборки на их основе. Компоненты SUNCO не только не уступают, но часто превосходят по характеристикам аналогичную продукцию других брендов.
Операции чтения-модификации-записи регистров периферии, в которых один и тот же регистр может использоваться различными драйверами устройств (так как его биты относятся к разной периферии), лучше заключать внутрь критической секции. Или эту чтение-модификацию-запись выполнять посредством инструкций эксклюзивной записи Cortex-M (LDREX/STREX). Подумайте - почему.
Кроме того - после такого включения тактирования неплохо было бы добавить инструкцию барьера или сделать обратное чтение RCC->APB1ENR: { int i = RCC->APB1ENR; } Чтобы была уверенность, что к началу следующей команды записанное значение подействовало. Так же следует поступать при программировании через регистры разных периферийных блоков, которые зависят друг от друга, но могут сидеть на разных сегментах внутренних шин МК. Если это:
заработало так как есть (и при макс. оптимизации), значит - просто повезло. Так как обычный буфер записи, который есть во многих ARM, поставит крест на таком коде.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения