Gerador de onda quadrada com Franzininho C0 (STM32C0)

Em alguns momentos os desenvolvedores de sistemas embarcados, ou mesmo os hobistas, necessitam gerar um sinal de baixa frequência ajustável, como, por exemplo, algo entre 1Hz e 100Hz (variável). Neste artigo, eu proponho exatamente isto, vamos gerar uma onda quadrada de frequência variável controlada por potenciômetro, que pode ser aplicada, por exemplo, para fazer um LED piscar.

Utilizaremos como hardware a placa Franzininho C0 (STM32C0) e como o STM32CubeIDE. 

Nossa referência será o livro “Programando STM32 na Prática com STM32CubeIDE” da Graziele Rodrigues, nos valendo do código da leitura analógica e também o do timer com interrupções.

Gerador de onda quadrada com Franzininho C0

Vamos precisar ainda de um gravador, para passar o firmware compilado do computador para a placa STM32C0. Eu utilizo o STLink V2, que você consegue comprar no Aliexpress (e em alguns sites Brasileiros também). Caso não tenha o gravador, poderá fazer o upload do binário através do bootloader: Como gravar a Franzininho C0 via USB/Serial usando o STM32CubeProgrammer

A forma de conexão do gravador com a placa é vista abaixo, são apenas quatro fios: SWCLK, SWIO, 3V3 e GND. Ao conectar o gravador pela primeira vez no seu computador (eu uso Windows) os drivers são instalados automaticamente.

Fonte: https://www.easytronics.com.br/st-link-v2

Gerador de onda quadrada com Franzininho C0
Fonte: o autor

Hardware

Nosso experimento consiste em variar um potenciômetro e acionar um LED (uma saída digital) com frequência variável. Portanto, temos como entrada analógica um potenciômetro e como saída digital um LED em série com um resistor.

A placa Franzininho C0 possui dois LEDs onboard, montados sobre a placa. Vamos utilizar o LED2 que está conectado ao pino PB6. Em uma aplicação onde você vai utilizar a frequência para outro objetivo, basta trocar de PB6 para qualquer outro pino digital da Franzininho C0.

O potenciômetro vai conectado ao pino PA7 (entrada analógica 7) da placa, de acordo com o diagrama de pinos disponível aqui. Seu valor pode ser variado, eu utilizo entre 1k Ohm e 10k Ohm, tanto faz. Estas pinagens (tanto do LED como do potenciômetro) respeitam o descrito nos exemplos do livro referência, que é de onde tiraremos os códigos de exemplo para criar nosso código final. 

Gerador de onda quadrada com Franzininho C0
Fonte: o autor

Firmware para o Gerador de onda quadrada

Conforme comentado no início do artigo, criaremos código no software STM32CubeIDE, cuja configuração inicial pode ser vista aqui. Eu comecei este artigo baixando um exemplo pronto, que é de oscilador pisca-pisca com interrupção de timer: https://github.com/Franzininho/franzininho-c0-exemplos-stm32cubeide (arquivos “02-exemplo-blinky-int). 

Trabalhamos sobre este exemplo pronto e adicionaremos a parte de conversor analógico-digital (AD) sobre ele. Para abrir o exemplo no STM32CubeIDE, procure pelo arquivo com extensão “.ioc” (02-exemplo-blinky-int.ioc). Se quiser rodar o exemplo apenas para ver o LED piscando (e ver que o exemplo funciona), faça o seguinte:

  • Faça o “Build” (compilação) no menu superior em “Project > Build”,
  • Conecte o gravador STLink V2 ao computador, já cabeado à placa Franzininho C0,
  • Clique no menu superior em “Run > Run”

Se algum dos passos acima falhar, verifique sua ligação elétrica e também se não alterou nada no programa que acabou de baixar do Github. O exemplo vem pronto para compilar e funcionar. Seguiremos então para a parte de adicionar o código do conversor analógico-digital, que também pode ser encontrado no livro referência deste artigo.

Como o código funciona?

Utilizando o método de leitura analógica por polling exemplificado no livro, ganhamos tempo e ficamos dentro do menor esforço de código necessário. Faz-se uma leitura analógica por polling a cada interrupção de timer, portanto a cada 10ms (dez milissegundos). A função de leitura “bloqueia” o código momentaneamente, até que uma conversão seja completada.

O cálculo da interrupção de timer está abaixo, conforme explanado no livro referência página 56.

  • Para um tempo de interrupção de 10ms, clock do sistema sendo 48MHz e prescaler 48000-1:
  • sysclk= clk / prescaler = 48000000 / 18000 = 1000
  • contador= (delay * sysclk) – 1 :: contador= (0,01 * 1000) -1 :: 10 – 1

Então, lá no arquivo tim.c teremos:

 htim17.Instance = TIM17;
 htim17.Init.Prescaler = (48000 - 1);
 htim17.Init.CounterMode = TIM_COUNTERMODE_UP;
 htim17.Init.Period = (10 - 1);
 htim17.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
 htim17.Init.RepetitionCounter = 0;
 htim17.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

Já no arquivo main.c nosso codigo vai ficar em “int main(void) {  }” e “void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim){  }”, o primeiro sendo a função principal, o segundo a função da interrupção. A função main completa está abaixo e também no Github https://github.com/FritzenLab/analog-to-frequency-stm32c0-franzininho .

int main(void)
{
	/* USER CODE BEGIN 1 */
	  /* USER CODE END 1 */
	  /* MCU Configuration--------------------------------------------------------*/
	  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	  HAL_Init();
	  /* USER CODE BEGIN Init */
	  /* USER CODE END Init */
	  /* Configure the system clock */
	  SystemClock_Config();
	  /* USER CODE BEGIN SysInit */
	  /* USER CODE END SysInit */
	  /* Initialize all configured peripherals */
	  MX_GPIO_Init();
	  MX_TIM17_Init();
	  MX_ADC1_Init();
	  /* USER CODE BEGIN 2 */
	  HAL_TIM_Base_Start_IT(&htim17);
	  HAL_ADCEx_Calibration_Start(&hadc1);
	  /* USER CODE END 2 */
	  /* Infinite loop */
	  /* USER CODE BEGIN WHILE */
	  while (1)
	  {
	    /* USER CODE END WHILE */
	    /* USER CODE BEGIN 3 */
	  }
	  /* USER CODE END 3 */
}

A função do da interrupção do timer completa está abaixo:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	HAL_ADC_Start(&hadc1);
	HAL_ADC_PollForConversion(&hadc1, 10);
	uint32_t leituraPotenciometro= HAL_ADC_GetValue(&hadc1);
	HAL_ADC_Stop(&hadc1);
	timing= leituraPotenciometro / 10.23;
	counter++;
	if(counter > timing){
		HAL_GPIO_TogglePin(GPIOB, LED1_Pin);
		counter= 0;
	}
}

O truque para gerar a frequência variável está aqui: eu configurei o ADC (no code configurator, passo prévio durante a inicialização do projeto – no arquivo do Github está pronto) para valores entre 0 e 1023 (10 bit), então eu divido o valor analógico por 10.23. Neste caso vou obter um valor na variável “timing” entre 0 e 100.

Aí eu faço um IF com “counter” e “timing”, sendo que counter vai subindo de 1 em 1 a cada interrupção (a cada 10ms) e timing é um valor de 0 a 100 dependendo do potenciômetro. Portanto com o potenciômetro no máximo eu vou obter  10 * 100 que é 1000 milissegundos. Já com o potenciômetro no mínimo eu obteria valores tendendo a 10 milissegundos e eventualmmente 0 milissegundos. 

Então, dentro do IF eu faço o toggle (mudança de estado) do pino de saída com tempos entre 10ms e 1000ms, obtendo frequências entre 1Hz e 100Hz. O código completo para o STM32CubeIDE está neste link.

Testes

Compilando e gravando o projeto do link acima na nossa Franzininho C0, veremos o LED do pino PB6 piscar com frequência variável. Esta frequência depende da posição do potenciômetro conectado ao pino PA7.

Gerador de onda quadrada com Franzininho C0

Fiz um vídeo para ilustrar o funcionamento do código e do circuito: 

Código similar a este poderia ser utilizado para controlar um servo motor, porém a frequência seria fixa e o período variável. Poderíamos ainda implementar um gerador de efeitos sonoros, obviamente adaptando a frequência da interrupção do timer 17 para aquela desejada. Saber controlar os timers e canais analógicos de um microcontrolador é essencial para o desenvolvedor de sistemas embarcados.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.
Comentários:
Notificações
Notificar
0 Comentários
recentes
antigos mais votados
Inline Feedbacks
View all comments
Home » Hardware » Gerador de onda quadrada com Franzininho C0 (STM32C0)

EM DESTAQUE

WEBINARS

VEJA TAMBÉM

JUNTE-SE HOJE À COMUNIDADE EMBARCADOS

Talvez você goste: