Перейти к содержанию

Почему код на регистрах для STM32F103 не работает на STM32G4?

Обновлено Редакция GAW

STM32 — это не одна архитектура периферии, а несколько поколений. STM32F1 вышел первым, и его блоки GPIO, RCC, USART и I2C устроены иначе, чем у более новых семейств. Код, где адреса и биты записаны вручную, при переносе на STM32G4 ломается почти целиком.

GPIOA у трёх семейств

STM32F103STM32F4STM32G4
Адрес GPIOA0x400108000x400200000x48000000
Режим выводаCRL, CRH — по 4 бита на выводMODER, OTYPER, OSPEEDR, PUPDRMODER, OTYPER, OSPEEDR, PUPDR
Выходной регистрODR, смещение 0x0CODR, смещение 0x14ODR, смещение 0x14
Включение тактаRCC_APB2ENR, IOPAENRCC_AHB1ENR, GPIOAENRCC_AHB2ENR, GPIOAEN

Данные — заголовки CMSIS ST. Наш расчёт: запись в ODR порта A — это адрес 0x4001080C у F103 и 0x48000014 у G4.

Что переписать

  1. Тактирование. Включение портов и периферии — по регистрам RCC нового семейства; у G4 они на странице регистров RCC STM32G4.
  2. Выводы. Вместо 4-битных полей MODE и CNF в CRL и CRH — режим в MODER, тип выхода в OTYPER, подтяжка в PUPDR, альтернативная функция в AFR. Поля — на страницах GPIO STM32G4 и GPIO STM32F1.
  3. Периферия. USART, I2C и SPI у G4 тоже новых поколений; сверяйте каждый регистр.

Как не попадать в это снова

Пишите через имена CMSIS (GPIOA->MODER, RCC->AHB2ENR), а не через числовые адреса: тогда при переносе ошибка покажется на сборке, а не в работающем устройстве. Слой LL от ST прячет часть различий за функциями — сравнение подходов в статье «HAL, LL и регистры». Значение регистра по полям собирает конструктор регистров.

Похожие вопросы

Достаточно ли поменять заголовочный файл?

Нет. Заголовок CMSIS для STM32G4 даст правильные адреса, но в нём просто нет регистров CRL и CRH и битов IOPAEN: код STM32F1 не соберётся. Настройку выводов, тактирование и периферию с другим устройством — например USART и I2C — придётся переписать по справочному руководству RM0440.

Будет ли код для STM32F4 работать на STM32G4 без изменений?

Частично. Блок GPIO у них одного устройства — MODER, OTYPER, PUPDR, ODR по тем же смещениям, — но адреса портов и шина разные: у F4 GPIOA на 0x40020000 и такт в RCC_AHB1ENR, у G4 — 0x48000000 и RCC_AHB2ENR. С именами CMSIS (GPIOA->MODER) достаточно поправить включение такта; с числовыми адресами — и их тоже.

Где посмотреть регистры STM32F3 и STM32L4?

На страницах регистров атласа: у STM32F3 и STM32L4 блок GPIO того же устройства, что у G4, и GPIOA тоже начинается с 0x48000000. Такт порту A у L4 включает GPIOAEN в RCC_AHB2ENR, как у G4, а у F3 — бит 17 регистра RCC_AHBENR (данные CMSIS). Поля, значения после сброса и код на CMSIS для каждого блока — в разделах семейств.

Источники

  1. STMicroelectronics. CMSIS device headers: cmsis-device-f1 v4.3.5, cmsis-device-f4 v2.6.11, cmsis-device-g4 v1.2.6 (GitHub, Apache-2.0) — адреса GPIOA: F1 0x40010800, F4 0x40020000, G4 0x48000000; регистры GPIO F1: CRL 0x00, CRH 0x04, IDR 0x08, ODR 0x0C, BSRR 0x10; F4 и G4: MODER 0x00, OTYPER 0x04, OSPEEDR 0x08, PUPDR 0x0C, IDR 0x10, ODR 0x14; RCC: F1 APB2ENR 0x18 бит 2 IOPAEN, F4 AHB1ENR 0x30 бит 0 GPIOAEN, G4 AHB2ENR 0x4C бит 0 GPIOAEN; RCC с адреса 0x40021000 у F1 и G4
  2. STMicroelectronics. RM0008 Rev 21 (STM32F1) и RM0440 Rev 9 (STM32G4), reference manuals — описание регистров GPIO и RCC, значения после сброса — по ним построены страницы регистров атласа

Нашли ошибку?