Ir ao conteúdo
  • Cadastre-se

Setando o clock e piscando LED STM32F0


Posts recomendados

Finalmente consegui setar o clock para 48MHz usando o PLL e o clock interno de 8MHz e piscar um led.

 

Tive muito problema ao ativar o PLL (PLLON), ocorria que o bit que indica que o PLL está ativo (PLLRDY) não estava setando (ele é setado por hardware)... Depois de umas 3 horas descobri onde estava o erro... Esses microcontroladores possuem proteção contra iniciante :mellow: esse era o problema.

 

Vou colocar o código aqui, quem sabe um dia sirva para alguém não perder várias horas como eu perdi :(.

Usando o STM32CubeMX (gerador de código de inicialização) é muito simples, com 1 minuto dá para configurar o clock e fazer o led piscar.

#include "stm32f072xb.h"                
#include "stm32f0xx.h"  
#include "stdio.h"

void DelayNaoExato(uint32_t Valor){
	volatile uint32_t i, j;
	
	for(i=0; i<Valor; i++)
		j++;
}

int main (void) {
	
	/********************* ALTERANDO O CLOCK PARA HSI8 - PLL - 48MHZ *********************/
	// Seleciona como clock do sistema o HSI (8MHz) - CFGR > SW = 00 (no reset já fica no HSI)
	RCC->CFGR &= ~RCC_CFGR_SW;
	// Espera o clock ser mudado para o HSI interno
	while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) {
		// Rotina para indicação de falha na alteração da fonte do clock
	}	
	
	// Desabilitando o PLL para que ele aceite alterações nos registradores - CR > PLL_ON = 0
	RCC->CR &= ~RCC_CR_PLLON;
	// Espera o PLL ser efetivamente desligado, no if qualquer coisa diferente de zero é true
	while(RCC->CR & RCC_CR_PLLRDY) {
		// Rotina para indicação de falha na alteração da fonte do clock
	}	
	
	// Zera os bits da seleção de clock para o pll. CFGR > PLLSRC = 00
	RCC->CFGR &= ~RCC_CFGR_PLLSRC;
	// ** Seleciona o HSI (8MHz) como fonte de clock do PLL. CFGR > PLLSRC = 01
	RCC->CFGR |= RCC_CFGR_PLLSRC_HSI_PREDIV;		
	// Zera todos os bits do PREDiv. CFGR2 > PREDIV = 0000
	RCC->CFGR2 &= ~RCC_CFGR2_PREDIV;
	// ** PREDiv dividindo o HSI por 2 (8MHz / 2 = 4MHz). CFGR2 > PREDIV = 0010
	RCC->CFGR2 |= RCC_CFGR2_PREDIV_DIV2;
	// Zera todos os bits do PLLMUL. CFGR > PLLMUL = 0000
	RCC->CFGR &= ~RCC_CFGR_PLLMUL;
	// ** Multiplicador do PLL selecionado para 12 (4MHz * 12 = 48MHz). CFGR > PLLMUL = 1010
	RCC->CFGR |= RCC_CFGR_PLLMUL12;
	// ** Zera todos os bits do AHB prescaler (AHB = 48MHz). CFGR > HPRE = 0000
	RCC->CFGR &= ~RCC_CFGR_HPRE;
	// ** Zera todos os bits do APB1 prescaler (PCLK1 = 48MHz). CFGR > PPRE = 000
	RCC->CFGR &= ~RCC_CFGR_PPRE;
	
	// Seleciona a latencia para "one wait state" e habilita prefetch buffer (deveser usado parawait state 1).
	FLASH->ACR |= FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
	// Espera o prefetch ser efetivamente ativado
	while((FLASH->ACR & FLASH_ACR_PRFTBS) == 0){
		// Rotina para indicação de falha na ativação do prefetch
	}
	
	// Habilita novamente o PLL
	RCC->CR |= RCC_CR_PLLON;
	// Espera o PLL estabilizar
	while((RCC->CR & RCC_CR_PLLRDY) == 0){
		// Rotina para indicação não pode ser ativado
	}
	
	// Seleciona o PLL como clock para o microcontrolador. SW = 10
	RCC->CFGR |= RCC_CFGR_SW_PLL; 
	while((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL){
		// Rotina para indicação de falha na alteração da fonte do clock
	}
	/*************************************************************************************/
	
	/*************************** ALTERANDO O CLOCK PARA HSI48 ****************************/
	/*
	FLASH->ACR |= FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY;
	RCC->APB1ENR |= RCC_APB1ENR_PWREN;
	while((FLASH->ACR & FLASH_ACR_PRFTBS) == 0){
	}
	
	// Liga o oscilador interno HSI48
	RCC->CR2 |= RCC_CR2_HSI48ON;
	// Espera o oscilador interno HSI48 se estabilizar  
	while((RCC->CR2 & RCC_CR2_HSI48RDY) == 0){
		// Rotina para indicação não pode ser ativado
	}
	
	// Seleciona o oscilador interno HSI48 como clock do sistema
	RCC->CFGR |= RCC_CFGR_SW_HSI48;
	// Espera a mudanca de clock terminar
	while((RCC->CFGR & RCC_CFGR_SWS_HSI48) != RCC_CFGR_SWS_HSI48){
		// Rotina para indicação de falha na alteração da fonte do clock
	}
	*/
	/*************************************************************************************/
	
	/*************************** SETANDO O PINO A5 COMO SAÍDA ****************************/
	// Habilita o clock para os GPIO do port A
	RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
	// Zera os bits referentes ao pino A5 MODER5 = 00
	GPIOA->MODER &= ~GPIO_MODER_MODER5;
	// Seta o pino A5 para saida MODER5 = 01
	GPIOA->MODER |= GPIO_MODER_MODER5_0;
	// Seta o pino para saida push pull
	GPIOA->OTYPER &= ~GPIO_OTYPER_OT_5; 
	// Saída para altas velocidades, "this controls the rise time and fall time of the output signal"
	GPIOA->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR5;
	// Desabilita os resistores de pull up e pull down. PUPDR5 = 00
	GPIOA->PUPDR &= ~GPIO_PUPDR_PUPDR5;
	
	while(1) {
		// Liga o pino A5
		GPIOA->BSRR |= GPIO_BSRR_BS_5;
		// Espera por um tempo nao especifico
		DelayNaoExato(200000);
		// Desiga o pino A5
		GPIOA->BSRR |= GPIO_BSRR_BR_5;
		// Espera por um tempo nao especifico
		DelayNaoExato(200000);
	}

}

 

Link para o comentário
Compartilhar em outros sites

Para esse chip (e outros M0 da ST, STM32F0 e STM32L0) vou usar sempre o Keil por ser full free.

Já para o M4, se o código ultrapassar os 32k, estou pensando em usar o atollic truestudio free, por não possuir limitação de código, ou o Coocox.

 

Rapaz, nunca fiquei tão feliz por piscar um LED :)...

 

Migrar dos PIC/AVR para ARM foi meio tranqueira... Eu estava completamente perdido, depois de ler bastante a situação começou a clarear xD...  Acho que vou começar um tutorial (com vídeos) para ajudar a galera que quer migrar. Com R$25,00 dá para começar (programador, microcontrolador)

Link para o comentário
Compartilhar em outros sites

3 horas atrás, test man*~ disse:

Rapaz, nunca fiquei tão feliz por piscar um LED :)...

 

hahaha!

Acho que já tive esse mesmo sentimento..kk

Quando eu olhava um programa exemplo, pensava..."nunca vou conseguir aprender isso!".

Esses micros são demais, baratos pelo que eles são.

Pelo preço de um Arduino nano, não dá nem para comparar.

 

Uso o Coocox com um ST-Link, grava diretamente pelo CoIDE e debuga, bem prático.

 

Abç

 

Link para o comentário
Compartilhar em outros sites

  • 3 meses depois...
Em 29/08/2017 às 14:38, Fervolt disse:

hahaha!

Acho que já tive esse mesmo sentimento..kk

Quando eu olhava um programa exemplo, pensava..."nunca vou conseguir aprender isso!".

Esses micros são demais, baratos pelo que eles são.

Pelo preço de um Arduino nano, não dá nem para comparar.

 

Uso o Coocox com um ST-Link, grava diretamente pelo CoIDE e debuga, bem prático.

 

Abç

 

Voltani fizemos Senai juntos preciso entrar em contato com você.

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...