Почему код на регистрах для STM32F103 не работает на STM32G4?
Обновлено Редакция GAW
STM32 — это не одна архитектура периферии, а несколько поколений. STM32F1 вышел первым, и его блоки GPIO, RCC, USART и I2C устроены иначе, чем у более новых семейств. Код, где адреса и биты записаны вручную, при переносе на STM32G4 ломается почти целиком.
GPIOA у трёх семейств
| STM32F103 | STM32F4 | STM32G4 | |
|---|---|---|---|
| Адрес GPIOA | 0x40010800 | 0x40020000 | 0x48000000 |
| Режим вывода | CRL, CRH — по 4 бита на вывод | MODER, OTYPER, OSPEEDR, PUPDR | MODER, OTYPER, OSPEEDR, PUPDR |
| Выходной регистр | ODR, смещение 0x0C | ODR, смещение 0x14 | ODR, смещение 0x14 |
| Включение такта | RCC_APB2ENR, IOPAEN | RCC_AHB1ENR, GPIOAEN | RCC_AHB2ENR, GPIOAEN |
Данные — заголовки CMSIS ST. Наш расчёт: запись в ODR порта A — это адрес 0x4001080C у F103 и 0x48000014 у G4.
Что переписать
- Тактирование. Включение портов и периферии — по регистрам RCC нового семейства; у G4 они на странице регистров RCC STM32G4.
- Выводы. Вместо 4-битных полей MODE и CNF в CRL и CRH — режим в MODER, тип выхода в OTYPER, подтяжка в PUPDR, альтернативная функция в AFR. Поля — на страницах GPIO STM32G4 и GPIO STM32F1.
- Периферия. 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 для каждого блока — в разделах семейств.
Источники
- 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
- STMicroelectronics. RM0008 Rev 21 (STM32F1) и RM0440 Rev 9 (STM32G4), reference manuals — описание регистров GPIO и RCC, значения после сброса — по ним построены страницы регистров атласа
Нашли ошибку?
Смотрите также
- STM32G4Cortex-M4 с FPU, до 170 МГц: G431/G441, G471–G484, G491/G4A1 — линейки и распиновки
- STM32F1Cortex-M3: F100, F101, F102, F103, F105/107 — линейки и распиновки
- HAL, LL или регистрыУровни STM32Cube, что делает HAL, правила совмещения, один код тремя способами
- Конструктор регистров AVRБиты регистра → hex, строка на C и ассемблере