veydlin
@veydlin
Мне никогда не жалко средств на свое любопытство

Как затактировать stm32 от внешнего кварца?

Копаясь по статьям и гуглу, написал такой код для проверки. Но светодиод даже не загорается, стоит внешний кварц на 8мгц, контроллер STM32F103VCT6.

CoIDE v2.0.2
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "misc.h"

void delay(void) {
	volatile uint32_t i;
	for(i = 1; i != 0xFFFFF; i++);
}


int main(void) {
	RCC->CR |= RCC_CR_HSEON; // Запустить HSE
	while((RCC->CR & RCC_CR_HSERDY) == 0); // Ожидание готовности HSE
	RCC->CFGR |= RCC_CFGR_HPRE_DIV1 | RCC_CFGR_PPRE2_DIV1 | RCC_CFGR_PPRE1_DIV1; // HCLK = SYSCLK ;  PCLK2 = HCLK ; PCLK1 = HCLK
	RCC->CFGR &= ~((RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); // Предочистка
	RCC->CFGR |= RCC_CFGR_PLLSRC_HSE; // Тактировать PLL от HSE (8 MHz)
	RCC->CFGR |= RCC_CFGR_PLLMULL9; // Умножать частоту на 9 (8*9=72 MHz)
	RCC->CR |= RCC_CR_PLLON; // Запустить PLL
	while((RCC->CR & RCC_CR_PLLRDY) == 0); // Ожидание готовности PLL
	RCC->CFGR &= ~RCC_CFGR_SW; // Очистить биты SW0, SW1
	RCC->CFGR |= RCC_CFGR_SW_PLL; // Тактирование с выхода PLL
	while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); // Ожидание переключения на PLL

	FLASH->ACR |= FLASH_ACR_PRFTBE; // Включить Prefetch Buffer
	FLASH->ACR &= ~(FLASH_ACR_LATENCY); // Предочистка
	FLASH->ACR |= FLASH_ACR_LATENCY_2; // Пропускать 2 такта

	// Настраиваем порт С
	GPIO_InitTypeDef PORT_C;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	PORT_C.GPIO_Pin = (GPIO_Pin_9 | GPIO_Pin_8);
	PORT_C.GPIO_Mode = GPIO_Mode_Out_PP;
	PORT_C.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC, &PORT_C);


	while(1) {
		GPIOC->ODR |= (GPIO_Pin_8);
		delay();
		GPIOC->ODR &= ~(GPIO_Pin_8);
		delay();
	}
};
  • Вопрос задан
  • 3324 просмотра
Решения вопроса 1
AlanDrakes
@AlanDrakes
Странно. У меня запускался нормально.
Попробуйте перенести настройку Flash памяти ДО смены основного тактового генератора.
Помнится, на высокой рабочей частоте данные просто не смогут выбраться.
В остальном в коде, похоже, всё в порядке.

Если работаете в отладчике - можете прямо в процессе выполнения идти по инструкциям где-то после:
RCC->CR |= RCC_CR_PLLON; // Запустить PLL
И точно увидите, где возникает проблема.

Кстати, либо можете перенести строки
RCC->CFGR &= ~RCC_CFGR_SW; // Очистить биты SW0, SW1
RCC->CFGR |= RCC_CFGR_SW_PLL; // Тактирование с выхода PLL
while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_1); // Ожидание переключения на PLL
непосредственно после flash->acr
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы