Почему STM32L1 зависает при переходе на 32 МГц?
Обновлено Редакция GAW
У STM32L1 переход на максимальные 32 МГц устроен строже, чем у STM32F1 или STM32F4: флеш-память читается 32 или 64 битами, напряжение ядра выбирается из трёх диапазонов, а скорость изменения частоты ограничена. Если пропустить любой шаг, программа повисает или уходит в HardFault сразу после смены SW.
Три условия
| Условие | Где в RM0038 | Типичная ошибка |
|---|---|---|
| VOS = 01, Range 1 (1,8 В) | разд. 5.1.5, 5.4.1 | после сброса стоит Range 2 — предел 16 МГц |
| ACC64 = 1, затем LATENCY = 1 | разд. 3.3.1, 3.9.1 | обе записи одной командой — LATENCY не ставится |
| Рост частоты меньше чем в 4 раза за шаг | разд. 6.2.7 | прыжок с MSI 2,097 МГц сразу на HSI 16 МГц или PLL 32 МГц |
Бит ACC64 по RM0038 нельзя записывать одновременно с LATENCY и PRFTEN, а LATENCY меняется только при уже установленном ACC64. Поэтому запись FLASH->ACR = ACC64 | LATENCY оставляет ноль тактов ожидания, и на 32 МГц флеш-память не успевает.
// STM32L1: Range 1, 64-bit access, 1 WS, then 32 MHz (RM0038, 3.3.1, 5.1.6)
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
while (PWR->CSR & PWR_CSR_VOSF) { }
PWR->CR = (PWR->CR & ~PWR_CR_VOS) | PWR_CR_VOS_0; // Range 1
while (PWR->CSR & PWR_CSR_VOSF) { }
FLASH->ACR |= FLASH_ACR_ACC64; // separate write
while (!(FLASH->ACR & FLASH_ACR_ACC64)) { }
FLASH->ACR |= FLASH_ACR_LATENCY | FLASH_ACR_PRFTEN;
while (!(FLASH->ACR & FLASH_ACR_LATENCY)) { }
// now switch SYSCLK in steps, 5 us apart (RM0038, 6.2.7):
// MSI 2.097 MHz -> MSI 4.194 MHz (MSIRANGE = 110) -> HSI 16 MHz -> PLL 32 MHz
PLL при этом настраивают так, чтобы VCO не превышал 96 МГц (в Range 1), например HSI 16 МГц × 6 = 96 МГц и деление на 3. Такты ожидания для разных серий STM32 подбирает калькулятор тактов ожидания STM32, а смысл самих тактов объясняет термин «Такт ожидания». Про диапазоны напряжения ядра — термин «Масштабирование напряжения», про предвыборку — «Буфер предвыборки». Линейки и корпуса — на странице STM32L1.
Похожие вопросы
Почему нельзя сразу переключиться с MSI на PLL 32 МГц?
RM0038 ограничивает скачок частоты: новая частота SYSCLK должна быть меньше учетверённой старой, а между двумя изменениями нужна пауза 5 мкс — так ограничивается просадка напряжения ядра от броска тока. С 2,097 МГц сразу на 16 МГц — уже в 7,6 раза, поэтому переходят ступенями: MSI 2,097 МГц → MSI 4,194 МГц (поле MSIRANGE) → HSI 16 МГц → PLL 32 МГц, с паузой 5 мкс между шагами; в примере RM0038 — 4,2 → 16 → 32 МГц.
Можно ли работать на 32 МГц от батарейки 1,8 В?
По RM0038 Range 1 требует VDD от 1,71 до 3,6 В, но у части исполнений нижняя граница — 2,0 В, это указано в даташите. Если напряжение может опуститься ниже 2,0 В, RM0038 описывает переход с Range 1 на меньшую частоту по сигналу PVD.
Нужна ли предвыборка на 32 МГц?
Желательна: при одном такте ожидания предвыборка PRFTEN позволяет читать следующую строку флеш-памяти, пока ядро исполняет текущую. Включить её тоже можно только при ACC64 = 1 — подробнее в термине «Буфер предвыборки».
Источники
- STMicroelectronics. RM0038: STM32L100xx, STM32L151xx, STM32L152xx and STM32L162xx advanced Arm-based 32-bit MCUs. Reference manual, Rev 18 — разд. 3.3.1, табл. 13: 0 WS — до 16 МГц в Range 1, до 8 МГц в Range 2, до 4,2 МГц в Range 3 (2,1 МГц у категории 1); 1 WS — до 32, 16 и 8 МГц; после сброса MSI около 2 МГц, 0 WS, 32-битный доступ; порядок повышения частоты: ACC64, проверка, LATENCY, проверка, смена SW; табл. 14: LATENCY = 1 допустим только при ACC64 = 1; разд. 3.9.1: ACC64 нельзя писать одновременно с LATENCY и PRFTEN, LATENCY и PRFTEN меняются только при ACC64 = 1; разд. 5.1.5, табл. 26: Range 1 — 1,8 В, 32 МГц с 1 WS при VDD 1,71–3,6 В (у части исполнений 2,0–3,6 В); Range 2 — 1,5 В, 16 МГц; Range 3 — 1,2 В, 4,2 МГц; разд. 5.1.6: перед сменой VOS и после неё ждать VOSF = 0; разд. 5.4.1: PWR_CR после сброса 0x0000 1000 — VOS = 10 (Range 2); разд. 6.2.7: новая частота SYSCLK меньше учетверённой старой, между шагами 5 мкс, пример — 4,2 → 16 → 32 МГц; разд. 6.3.2: MSIRANGE 101 — 2,097 МГц (после сброса), 110 — 4,194 МГц; табл. 35: PLLVCO не выше 96 МГц в Range 1 и 48 МГц в Range 2; RCC_CFGR: PLLMUL 0010 — ×6, PLLDIV 10 — деление на 3
- STMicroelectronics. cmsis-device-l1, Include/stm32l152xe.h (commit a23ade4) — FLASH_ACR: LATENCY — бит 0, PRFTEN — бит 1, ACC64 — бит 2; PWR_CR_VOS — биты 12:11, PWR_CR_VOS_0 = 0x0800 (Range 1); PWR_CSR_VOSF — бит 4
Нашли ошибку?
Смотрите также
- STM32L1Cortex-M3, до 32 МГц, малое потребление: L100, L151, L152 и L162 с ЖКИ и AES — линейки и распиновки
- Буфер предвыборки флеш-памятиУпреждающее чтение следующей строки команд из флеш-памяти STM32
- Такт ожиданияЛишние такты при обращении к медленной памяти: частоты, настройка, кэш
- Такты ожидания флеш-памяти STM32LATENCY в FLASH_ACR по частоте и питанию, таблица и код
- Масштабирование напряжения ядра (VOS)Выбор напряжения ядра стабилизатором STM32 под нужную частоту