Welcome back Folks! Vamos continuar com nossa série de posts sobre o Tiva C Series, a placa de desenvolvimento da TI baseada em um microcontrolador com arquitetura Cortex-M4. No nosso último post apresentamos as características dessa placa que promete uma excelente relação custo-benefício.
Antes de começarmos, você precisa primeiro instalar os drivers para sua Tiva. Basta clicar em download no link: http://www.ti.com/tool/stellaris_icdi_drivers.
Em seguida você precisa baixar e instalar o Keil µVision. Após a instalação estar completa inicie o programa e conecte sua Tiva. Você deve estar vendo algo parecido com isso:
Na barra superior vá em PROJECT -> NEW µVision PROJECT. Selecione o diretório onde deseja salvar o projeto, dê um nome e clique em salvar. Em seguida você deverá selecionar o microcontrolador com o qual vai trabalhar, encontre (ou digite) TM4C123GH6PM. E aperte OK.
Irá aparecer uma janela perguntando se você quer fazer uma cópia do arquivo de startup_TM4C123.s (fornecido pela Keil) para seu diretório. Clique em Não, pois iremos utilizar o arquivo que você baixou aqui no blog.
Muito bem, você criou seu projeto! Agora vamos adicionar um arquivo main.c que conterá o código fonte de nossa primeira aplicação. No canto esquerdo, na janela de Project, vá em Source Group 1 e clique com o botão direito do mouse. Selecione a opção Add New Item...
Selecione C File(.c) e dê o nome de main.c, depois clique em Add.
Agora você tem um arquivo onde poderá escrever o código fonte, que será compilado e convertido em código de máquina para sua Tiva. Para que o Debug Mode funcione e consigamos testar nossos códigos, precisaremos adicionar o arquivo starup.s que você baixou aqui no blog. Novamente, clique com o botão direito do mouse em Source Group 1 e em seguida em Add Existing Files to... Localize o arquivo startup.s e adicione ao projeto. Seu diretório, na aba Project, deve ser algo parecido com isso agora:
Antes de começarmos a programar, vamos fazer alguns ajustes nas configurações de nosso projeto. No menu superior, vá em PROJECT -> Options for Target ‘Target 1'. Em seguida, certifique-se que as configurações estejam como na imagem abaixo (atente para não usar Floating Point Hardware e Cross-Module Optimization):
Nessa mesma tela selecione a aba Debug. Usaremos nossa placa para debugar o nosso código e vamos precisar dos drivers da TI que baixamos anteriormente. Certifique-se que sua tela de configuração esteja como a imagem abaixo:
Por fim, vá a aba Utilities e certifique-se que está usando o mesmo driver que o Debuger:
Pronto, aperte OK e vamos programar! Um bom programador estrutura seu código de forma que seja possível que outros colaboradores possam entendê-lo durante a fase de projeto de um sistema. Vou mostrar a forma como estruturo meus programas (aprendi com o pessoal da Universidade de Texas Austin).
O arquivo principal (main.c) é estruturado em 4 sessões: 0 – Documentação; 1 – Diretivas de Pré-processamento; 2 – Declarações; 3 – Subrotinas. Vamos começar com a sessão 0. Abra seu arquivo main.c e descreva como seu sistema irá funcionar, bem como o autor e data de concepção do projeto:
[code language="cpp"]
// 0.Documentation Section
// main.c
// HelloWorld, Input from PF4, output to PF3,PF2,PF1 (LED)
// Authors: Bruno Godoi Eilliar
// Date: March 15, 2015
// LaunchPad built-in hardware
// SW1 left switch is negative logic PF4 on the Launchpad
// SW2 right switch is negative logic PF0 on the Launchpad
// red LED connected to PF1 on the Launchpad
// blue LED connected to PF2 on the Launchpad
// green LED connected to PF3 on the Launchpad
[/code]
Em seguida, vamos para a sessão 1, onde iremos declarar os endereços dos registradores que iremos usar. Não se preocupe se não entender, vamos abordar com mais detalhes os registradores em posts futuros, no momento queremos dar vida à nossa Tiva e certificarmos de que nossa IDE está funcionando perfeitamente.
[code language="cpp"]
// 1. Pre-processor Directives Section
// Constant declarations to access port registers using
// symbolic names instead of addresses
#define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC))
#define GPIO_PORTF_DIR_R (*((volatile unsigned long *)0x40025400))
#define GPIO_PORTF_AFSEL_R (*((volatile unsigned long *)0x40025420))
#define GPIO_PORTF_PUR_R (*((volatile unsigned long *)0x40025510))
#define GPIO_PORTF_DEN_R (*((volatile unsigned long *)0x4002551C))
#define GPIO_PORTF_LOCK_R (*((volatile unsigned long *)0x40025520))
#define GPIO_PORTF_CR_R (*((volatile unsigned long *)0x40025524))
#define GPIO_PORTF_AMSEL_R (*((volatile unsigned long *)0x40025528))
#define GPIO_PORTF_PCTL_R (*((volatile unsigned long *)0x4002552C))
#define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108))
[/code]
Na sessão 2, declaramos as variáveis que iremos utilizar e os protótipos das funções que também serão necessárias para nosso programa.
[code language="cpp"]
// 2. Declarations Section
// Global Variables
unsigned long In; // input from PF4
unsigned long Out; // outputs to PF3,PF2,PF1 (multicolor LED)
// Function Prototypes
void PortF_Init(void);
void Delay(void);
void EnableInterrupts(void);
[/code]
Por fim, chegamos onde o interessante acontece. Na sessão 3 descrevemos o comportamento do nosso sistema, declarando a função principal (main) e as funções auxiliares, cujos protótipos foram declarados anteriormente. Nosso sistema funcionará da seguinte forma:
- Se o switch 1 (SW1) não estiver pressionado, o LED irá alternar entre Azul e Vermelho;
- Se o switch 2 (SW1) estiver pressionado, o LED irá alternar entre Azul e Verde.
Assim, para realizar esse comportamento podemos usar a seguinte lógica:
[code language="cpp"]
// 3. Subroutines Section
// MAIN: Mandatory for a C Program to be executable
int main(void){
PortF_Init(); // Call initialization of port PF4 PF2
while(1){
In = GPIO_PORTF_DATA_R&0x10; // read PF4 into In
if(In == 0x00){ // zero means SW1 is pressed
GPIO_PORTF_DATA_R = 0x08; // LED is green
}
else{ // 0x10 means SW1 is not pressed
GPIO_PORTF_DATA_R = 0x02; // LED is red
}
Delay(); // wait 0.1 sec
GPIO_PORTF_DATA_R = 0x04; // LED is blue
Delay(); // wait 0.1 sec
}
}
// Subroutine to initialize port F pins for input and output
void PortF_Init(void){
volatile unsigned long delay;
SYSCTL_RCGC2_R |= 0x00000020; // 1) F clock
delay = SYSCTL_RCGC2_R; // delay
GPIO_PORTF_LOCK_R = 0x4C4F434B; // 2) unlock PortF PF0
GPIO_PORTF_CR_R = 0x1F; // allow changes to PF4-0
GPIO_PORTF_AMSEL_R = 0x00; // 3) disable analog function
GPIO_PORTF_PCTL_R = 0x00000000; // 4) GPIO clear bit PCTL
GPIO_PORTF_DIR_R = 0x0E; // 5) PF4,PF0 input, PF3,PF2,PF1 output
GPIO_PORTF_AFSEL_R = 0x00; // 6) no alternate function
GPIO_PORTF_PUR_R = 0x11; // enable pullup resistors on PF4,PF0
GPIO_PORTF_DEN_R = 0x1F; // 7) enable digital pins PF4-PF0
}
// Subroutine to wait about 0.1 sec
void Delay(void){
unsigned long volatile time;
time = 727240*200/91; // 0.1sec
while(time){
time--;
}
}
[/code]
A função PortF_Init() é responsável por inicializar a Porta F de nossa Tiva, de forma que os pinos PF1, PF2 e PF3 sejam configurados como saídas digitais; e que PF4 seja configurado como uma entrada digital (SW1). A função Delay(), faz com que seja gerado um delay de aproximadamente 0.1 segundo. Essa não é a melhor forma para gerar um delay, mas para nossa aplicação inicial será suficiente. Futuramente iremos aprender a utilizar o SysTick Timer para gerar delays de forma mais precisa.
Pronto! Você acaba de escrever seu primeiro programa. Agora precisamos convertê-lo em código de máquina (compilar) e testá-lo em nossa Tiva. No menu superior, vá em PROJECT -> Build Target; ou simplesmente aperte F7. Se não houve problemas, você verá no terminal inferior a seguinte mensagem:
Vamos fazer o download de nossa aplicação para a placa. Conecte sua Tiva ao seu computador, vá ao menu superior em FLASH -> Download.
Tudo Ok, vamos ao Debug Mode. Na aba superior você encontrará o seguinte ícone: . Clique nele, ou aperte CTRL+F5 para iniciar o modo Debug.
Após entrar no modo Debug, sua tela deve ser algo parecido com isso:
Por enquanto você está com o software iniciado em sua placa esperando suas ordens para execução: note que estamos parados na instrução que “invoca” a função PortF_Init(). Para rodar o software continuamente e testarmos nosso sistema, clique no ícone RUN, localizado abaixo do botão de Save, ou aperte F5.
Parabéns! Você acaba de completar seu primeiro programa em sua Tiva LaunchPad. Note que sua placa já está piscando Azul-Vermelho. Se pressionar o SW1 ela muda para Azul-Verde.
Acompanhe o nosso blog e não perca as próximas aplicações que vamos desenvolver para a nossa Tiva. Se gostou, não deixe de espalhar a palavra e se tem alguma dúvida ou sugestão, deixe seu comentário!
Até o próximo post!