Неверный регистр мигающего светодиода STM32?

#c #stm32 #microcontroller

#c #stm32 #микроконтроллер

Вопрос:

У кого-нибудь есть идеи, почему код не работает?

 RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
GPIOB->MODER amp;= ~(0x3u << 6u);
GPIOB->MODER |= (0x1u << 6u);
for (int i = 0; i < 1000; i  ) {
    GPIOB->ODR |= (0x1u << 0x3u);
}
  

Я использую плату STM (STM32L432KC), которая имеет встроенный светодиод, который называется выводом PB3 (порт 26), но после мигания ничего не происходит. На самом деле должен светиться светодиод. Правильно ли я использую регистр?

Комментарии:

1. вы не мигаете светодиодом с этим кодом, и у вас все равно нет задержки. в зависимости от конструкции вашей платы вам может потребоваться сделать вывод низким, чтобы включить светодиод. вы можете использовать регистр bsrr, а можете просто использовать GPIOB-> BSRR = 1<<3, а затем попробовать 1 << (3 16). и для мигания используйте эти два регистра с задержкой между ними

2. предполагая, что все магические числа, структура и определения верны в соответствии с руководством, тогда вы выполняете шаги, необходимые для правильной настройки порта, и это необходимый минимум.

3. Спасибо, но почему я должен выполнять вторую смену 1 << (3 16)?

4. один устанавливает бит 3, другой устанавливает бит 19, если вы посмотрите на регистр bsrr, вы увидите, что один бит делает этот вывод высоким, а другой — низким. один из двух высоких или низких значений включит светодиод, а другой выключит. итак, я полагаю, что вы хотите мигать, как в вашем вопросе заголовка, тогда вам нужно включаться и выключаться со скоростью человека.

5. если ваш код не включает светодиод, то, как уже упоминалось, попробуйте сделать вывод низким и посмотреть, загорится ли при этом светодиод. Вы смотрели на схему? Что это показывает?

Ответ №1:

Вы устанавливаете бит, ODR но никогда не очищаете его, поэтому он не будет мигать, вам потребуется задержка между переходами включения / выключения, чтобы можно было видеть, как он мигает.

Рекомендуется записывать в BSRR регистр вместо ODR too, где это возможно, это позволяет избежать циклов чтения-изменения-записи.

Если этот код является вашим целым main() , то вы можете заменить for (int i = 0; i < 1000; i ) его на a while(1) , обычно вы не хотите возвращаться из main встроенного контекста.

Комментарии:

1. Большое вам спасибо! но светодиод все еще не мигает. На самом деле он даже не светится. Правильно ли я использую адреса регистров? Светодиод соответствует указанному PB3. Может быть, светодиод только поврежден?

2. Это коммерчески доступная плата, что это за плата?

3. Это STM32 от ST NUCLEO-плата разработки Nucleo L432KC. На схеме PB3 показан как зеленый светодиод.

Ответ №2:

Эта последовательность неверна (я не проверял, используете ли вы правильный регистр RCC)

 RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
GPIOB->MODER amp;= ~(0x3u << 6u);
  

Когда вы включаете периферийные часы, вам нужно прочитать значение или добавить некоторую задержку для распространения изменений по шине. Обычно я использую для этого инструкцию barrier .

 RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
__DMB();
GPIOB->MODER amp;= ~(0x3u << 6u);
  

Если вы не добавите эту задержку (или обратное чтение), первая операция завершится неудачно, поскольку она будет выполняться на не синхронизированном GPIO periperal.

введите описание изображения здесь

Комментарии:

1. Спасибо, имеет смысл! Я добавил эту строку, но все равно ничего не происходит (я уже проверил PIN-код).

2. Я обнаружил проблему, из-за которой программа выполняется только один раз (я нажимаю на эту проблему в другом потоке, потому что проблема с заголовком решена).

3. Никогда не было такой проблемы ни с одной из этих частей, это код на C, много задержек. Технически возможно с некоторыми конструкциями, но не с STM32s.

4. согласно этому документу, этот код записан в C…so больше двух часов, готово, не нужно ничего читать.

5. @old_timer это хорошо известная проблема с использованием STM32s. Я удивлен, что вы об этом не слышали. Если вы обращаетесь к периферийному устройству до установки синхронизации, следующие обращения к регистрам также могут быть неправильными. Например, STM в драйвере низкого уровня выполняет обратную считку