sexta-feira, 16 de junho de 2017

Desenvolvendo para a placa STM32F4 - Parte I

Iniciaremos uma série de posts para guiar os leitores deste blog no desenvolvimento de aplicações com a placa STM32F4Discovery, da ST. Trata-se de uma placa com um microcontrolador STM32F407VG, que é um ARM Cortex-M4 de 32 bits com unidade de ponto flutuante, mais:

  • 1 MB de memória flash;
  • 192 kB de RAM;
  • clock de 168 MHz;
  • acelerômetro de 3 eixos;
  • microfone omnidirecional;
  • conversor D/A com interface serial e amplificador classe D;
  • 8 LEDs e 2 botões push-button;
  • conector mini e micro USB.





Para desenvolver aplicações, é necessário uma tool chain, que é a família de ferramentas onde o software que implementa a aplicação  é escrito em um computador host para posteriormente ser transferido para a flash do microcontrolador. Para tanto necessitaremos de:


  • um compilador GCC para ARM embedded, que pode ser baixado aqui;
  • o driver USB para comunicação com a placa ST-Link, baixado daqui;
  • Um ambiente integrado de desenvolvimento, no qual optamos pelo CoIDE, dentre outros disponíveis para esta plataforma. Uso a versão 1.7.7, embora já tenhamos versões mais recentes.
Uma vez instalados estes programas no computador host, deve ser realizada a configuração do CoIDE para que ele aponte para o diretório do compilador gcc a ser utilizado, na forma como segue:








A partir desta configuração, criamos um novo projeto:




Após o qual selecionamos Chip:




E depois procuramos por ST > STM32F4x > STM32F407VG







Pronto. Antes de prosseguirmos, devemos fazer com que o debugger aponte para o ST-Link, da forma como segue:







 Para um primeiro projeto, selecionaremos do repositório apenas uma biblioteca imprescindível para o desenvolvimento de uma aplicação mínima para a placa, que é a biblioteca CMSIS-Core:



 Observe que na estrutura do projeto serão acrescentados dois subdiretórios, o cmsis, necessário para processadores ARM, e o cmsis-boot/startup, para a inicialização da placa e gestão básica dos periféricos.

Abra então o arquivo main.c e substitua pelo fonte abaixo:


1:  #include <stm32f4xx.h>  
2:  int main(void)  
3:  {  
4:       int index;  
5:       /* Seta pinos 12 do GPIOD (LED verde) como saída */  
6:       /* Ver manual de referência do STM32F4 */  
7:       RCC->AHB1ENR |= ((1UL << 3));  
8:       GPIOD->MODER &= ~((3UL << 2*12));  
9:       GPIOD->MODER |= ((1UL << 2*12));  
10:       GPIOD->OTYPER &= ~((1UL << 12));  
11:       GPIOD->OSPEEDR &= ~((3UL << 2*12));  
12:       GPIOD->OSPEEDR |= ((2UL << 2*12));  
13:       GPIOD->PUPDR &= ~((3UL << 2*12));  
14:       GPIOD->PUPDR |= ((1UL << 2*12));  
15:       while(1)  
16:    {  
17:            GPIOD->BSRRL = (1 << 12);  
18:            for (index = 0; index < 100000; index++);  
19:            GPIOD->BSRRH = (1 << 12);  
20:            for (index = 0; index < 100000; index++);  
21:    }  
22:  }  

De forma que visualizará como:






Vá então em Project > Build ou pressione F7 e inicie a compilação. Se tudo der certo, teremos no console:





Por fim, conecte a placa em uma porta USB do computador host e vá em Flash > Program Download para carregar o firmware na flash da placa. Neste processo, o LED LD1 próximo a interface Mini USB da placa (CN1) comutará entre verde e vermelho durante a transferência, voltando ao estado vermelho contínuo após esta. Assim, se tudo der certo, o resultado será o LED da placa (LD4) piscando.



Observe que também ligamos um LED Verde externo à placa no pino PD12, mostrando esta possibilidade.

Passamos assim a explicação do código.

Na linha 1 incluímos o arquivo de cabeçalho stm32f4xx.h, que contém os rótulos para os endereços dos periféricos da placa, além de permitir acesso a este através de registros, que são acessados por campos de estruturas (structs) em linguagem C.





Dentro do main, após a declaração da variável inteira index (usada nos laços for das linhas 18 e 20), segue um conjunto de linhas (de 7 a 14) para configuração da porta de entrada e saída GPIO que dá acesso ao Led verde (LD4) da placa. Para um entendimento pleno desta configuração, é importante ter em mãos o manual de referência do microcontrolador.

Na linha 7 se habilita o clock do periférico em questão, a GPIOD, como segue:





Nas linhas 8 e 9 se define o modo da pino 12 da porta GPIOD, o qual está conectado o LED verde, como de saída:




Na linha 10 se define o respectivo pino como saída do tipo push-pull:




Nas linhas 11 e 12 se define a velocidade do pino da porta como High Speed:





Terminando a configuração da Porta D/Pino 12, define-se como operação pull-up:





Concluída esta parte do código, passamos ao que é executado infinitamente, que é o fragmento dentro do laço while(1), a partir da linha 15. Ali, na linha 17 é setado o bit 12 da parte baixa do campo BSRR, o que "liga" o pino 12 da porta GPIOD. Após, é executado um laço for cem mil vezes, apenas para segurar este pino ligado (e consequentemente seu LED) por um certo tempo. Enfim, na linha 19 é setado o bit 12 da parte alta do campo BSRR, o que "desliga" o pino 12 da porta GPIOD, apagando o LED e o deixando assim neste estado pelo tempo da execução do laço for seguinte.

Maiores detalhes:





Foi possível compreender a aplicação e seu código correspondente? Dê um feedback comentando o post abaixo.

No próximo post, apresentaremos uma outra versão para esta mesma aplicação, só que usando a biblioteca específica de cada periférico constituinte da Standard Peripheral Library da placa. Nesse ínterim, aproveite para verificar o entendimento deste código, através das seguintes modificações:


  1. Use valores em hexadecimal para configurar os campos da porta GPIOD, ao invés da notação apresentada;
  2. Altere o código para piscar o LED vermelho (LD5), que está conectado ao pino 14 da porta GPIOD;
  3. Faça o LED piscar mais lentamente/ rapidamente;
  4. Faça dois ou mais LEDs piscarem conjuntamente.

Um comentário: