Главная > STM32 > Грабли STM32L: тактирование.

Грабли STM32L: тактирование.

Сходил тут на семинар КОМПЭЛ по STM32L, и, добыв там платку STM32L-DISCOVERY, начал ее мучить.

Сразу предупреждаю, речь пойдет о работе с PLL через регистры, так что любители библиотек на все случаи жизни могут покурить в сторонке.

Итак, я решил начать с изучения системы тактирования. Накидал простую программу, мигающую светодиодами, и начал ковырять PLL. Моей целью было завести МК от HSI через PLL на 32МГц (максимум).

Для этого надо сделать следующее:

1. Включить HSI и подождать, пока он стабилизируется:

//Turn ON HSI
  RCC->CR|=RCC_CR_HSION;

  //Wait until it's stable 
  while (!(RCC->CR & RCC_CR_HSIRDY));

2. Установить множитель PLL равным четырем, а делитель — двум, что даст результирующее умножение на два:

//PLL input = HSI
  //PLL division factor = 2
  //PLL multiplication factor = 4
  RCC->CFGR|=RCC_CFGR_PLLDIV_0 | RCC_CFGR_PLLMUL_0;

3. Включить PLL и подождать, пока она стабилизируется:

//Turn PLL on
  RCC->CR|=RCC_CR_PLLON;

  //Wait PLL to stabilize
  while (!(RCC->CR & RCC_CR_PLLRDY));

4. Перейти на тактирование от PLL:

//Set PLL as SYSCLK
  RCC->CFGR|=RCC_CFGR_SW_1 | RCC_CFGR_SW_0;

  //Turn off MSI
  RCC->CR&=~RCC_CR_MSION;

Да, если чего, начальный код инициализации RCC в SystemInit() я потер ввиду его неадекватности (настраивает контроллер на тактирование от кварца, которого нет), т.о. контроллер стартует точно от MSI, как написано в ДШ.

Однако, если сделать все в точности, как я описал, МК повиснет. Почему? Все дело в том, что настроенная по-умолчанию FLASH-память работает на частотах не выше 16 МГц (стр. 37 Reference manual):

Потому перед тем, как повышать частоту тактирования выше 16МГц, необходимо переконфигурировать FLASH (включить упреждающее чтение и поменять тайминги):

//Setting up flash for high speed
  FLASH->ACR=FLASH_ACR_ACC64;
  FLASH->ACR|=FLASH_ACR_LATENCY;
  FLASH->ACR|=FLASH_ACR_PRFTEN;

Вся программа:

#include "stm32l1xx.h"
#include <stdint.h>

#define LED_BLUE (1<<6)
#define LED_GREEN (1<<7)

void main(void)
{
  uint32_t i;

  //Turn ON HSI
  RCC->CR|=RCC_CR_HSION;

  //Wait until it's stable 
  while (!(RCC->CR & RCC_CR_HSIRDY));

  //Switch to HSI as SYSCLK
  //PLL input = HSI
  //PLL division factor = 2
  //PLL multiplication factor = 4
  RCC->CFGR|=RCC_CFGR_PLLDIV_0 | RCC_CFGR_PLLMUL_0;

  //Turn PLL on
  RCC->CR|=RCC_CR_PLLON;

  //Wait PLL to stabilize
  while (!(RCC->CR & RCC_CR_PLLRDY));

  //Setting up flash for high speed
  FLASH->ACR=FLASH_ACR_ACC64;
  FLASH->ACR|=FLASH_ACR_LATENCY;
  FLASH->ACR|=FLASH_ACR_PRFTEN;

  //Set PLL as SYSCLK
  RCC->CFGR|=RCC_CFGR_SW_1 | RCC_CFGR_SW_0;

  //Turn off MSI
  RCC->CR&=~RCC_CR_MSION;

  //******

  RCC->AHBENR=RCC_AHBENR_GPIOBEN;

  GPIOB->MODER=GPIO_MODER_MODER6_0 | GPIO_MODER_MODER7_0;

  GPIOB->ODR=0;

  while (1)
  {
    if (!(GPIOB->ODR & LED_BLUE))
    {
      GPIOB->ODR&=~LED_GREEN;
      GPIOB->ODR|=LED_BLUE;
    }
    else
    {
      GPIOB->ODR|=LED_GREEN;
      GPIOB->ODR&=~LED_BLUE;
    }

    for (i=0; i<400000UL; ++i);
  }
}

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

Рубрики:STM32
  1. Комментариев нет.
  1. No trackbacks yet.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s