Shape The World - Capítulos 1 a 3

Embedded Systems Shape The World - Capítulos 1 a 3
Este post faz parte da série Shape The World. Leia também os outros posts da série:

Caros leitores, daremos sequência à nossa série que corre em paralelo ao curso Embedded Systems - Shape the World, oferecido pela UTAustinX - University of Texas at Austin através do sistema EDX.

 

Com os artigos anteriores fizemos uma breve introdução sobre este curso oferecido pelo EDX, abordamos mais a fundo as particularidades do hardware presente na Launchpad Tiva/Stellaris, e também apresentamos algumas IDEs e ferramentas muito interessantes para o desenvolvimento dos nossos projetos. Lembrando que a IDE utilizada no curso é o Keil.

 

Em virtude da relativa simplicidade dos primeiros capítulos e dos laboratórios relacionados achamos interessante condensar os principais pontos em apenas um artigo. Iremos seguir através destes capítulos destacando alguns pontos importantes além de comentar sobre os exercícios propostos e dúvidas comuns no fórum do curso.

 

Como no primeiro capítulo é abordada apenas uma introdução sobre o que são os sistemas embarcados, pularemos para o capítulo seguinte.

 

 

Segundo capítulo

 

No segundo capítulo abordou-se sobre as bases numéricas comumente utilizadas em sistemas eletrônicos, em especial a base binária e a base hexadecimal que utilizamos constantemente em nossos projetos. Abordou-se também sobre a arquitetura básica do microcontrolador, o conceito de barramentos, tipos de memórias, I/O’s, além de apresentar os registradores presentes nos ARM Cortex-M4 e um pouco sobre a linguagem Assembly nativa desse dispositivo.

 

O primeiro laboratório é bastante simples, um blink led onde uma chave controla quais dos leds da launchpad irão piscar, mas traz alguns conceitos importantes, em especial para quem está começando neste mundo dos embarcados. Logo no começo do código fornecido existe uma sequência de definições que pode assustar o aluno:

 

 

Ok, mas o que são essas declarações? Primeiramente devemos lembrar que cada periférico do microcontrolador é mapeado como um endereço no mapa de memória e que para configurar ou mesmo acessar algum dos periféricos, por exemplo para escrever ou ler o estado de um I/O, devemos recorrer ao seu endereço. Neste ponto, consultar o datasheet do componente nos auxilia a descobrir o endereço dos registradores desejados.

 

Para acessar estes registradores utilizamos os chamados ponteiros. Neste ponto indico a leitura da série sobre ponteiros escrita pelo Fernando Deluno Garcia. De uma maneira bastante resumida, o ponteiro é uma variável que contém um endereço dentro do mapa de memória. Quando dentro do código atribuímos um valor a uma dessas definições, por exemplo, GPIO_PORTF_DATA_R = 0x01; , na verdade estamos atribuindo o valor hexadecimal "0x01" ao endereço apontado por GPIO_PORTF_DATA_R.

 

Uma dúvida que frequentemente aparece no fórum tem relação com o entendimento da declaração acima citada, em especial pela quantidade de modificadores e pelos * (asteriscos) que surgem. Tomemos como base o registrador GPIO_PORTF_DATA_R  e vamos explicá-la em duas etapas:

  • (volatile unsigned long *)0x400253FC  - Realiza um typecast explícito para um ponteiro. O modificador volatile indica que a variável não deve ser otimizada e que pode sofrer modificações alheias ao código, por exemplo, o valor de um pino pode mudar por um fator externo, como através de uma chave. O valor hexadecimal por sua vez é o endereço referenciado pelo ponteiro;
  • (*((volatile unsigned long *)0x400253FC))  - A declaração completa adiciona um asterisco antes dos parênteses. Isso indica ao compilador que estamos interessados no valor que está contido dentro daquele endereço referenciado, e não no próprio endereço em si.

 

Além destas declarações, outro trecho interessante para comentarmos tem relação à sequência necessária para configurar um GPIO como entrada/saída, para com isso utilizarmos nossa chave (entrada) para controlar os led’s (saída). A sequência completa é apresentada a seguir:

 

 

Para facilitar o entendimento tenha em mãos o datasheet do componente. O primeiro passo antes de configurar um GPIO é habilitar seu clock através do respectivo bit do registrador SYSCTL_RCGC2_R . Procure no datasheet por “Register 136: Run Mode Clock Gating Control Register 2 (RCGC2)”, dentro da sessão 5.6. Com auxílio do gráfico fica mais simples de entender porque atribuímos o valor “0x20” a este registrador. Este valor é referente ao bit relacionado ao GPIOF. Note que utilizou-se da operação lógica “OR” permitindo que o bit específico fosse setado sem que o estado dos outros bits fosse alterado, não desconfigurando assim outros periféricos. Note que próximo ao gráfico encontram-se informações referentes ao endereço base do registrador e seu offset. Se somarmos os dois valores encontraremos o endereço atribuído anteriormente nas definições.

 

Na sequência existe uma linha que causa bastante confusão em função da nomenclatura “delay” adotada para a variável. Dentro das explicações sobre o RCGC2 existe um aviso, indicando que após a ativação do clock devemos esperar 3 ciclos de clock do sistema para só então acessarmos os registradores. Esta linha tem apenas esta função: “gastar” alguns ciclos de máquina permitindo que o GPIOF possa ser acessado.

 

Na próxima linha, ao atribuirmos o valor “0x4C4F434B” ao registrador  GPIO_PORTF_LOCK_R  liberamos o acesso ao PortF, ou melhor, liberamos acesso ao registrador GPIO_PORTF_CR_R . Esse, por sua vez, tem como objetivo proteger alguns pinos relacionados a NMI e JTAG/SWI contra modificações acidentais (neste modelo os pinos protegidos são PD7, PF0, e PC[3:0]). Ao setarmos um bit neste registrador estamos habilitando modificações em outros registradores associados. A título de curiosidade, você deve estar pensando, de onde surgiu este número mágico (magic numbers everywhere) “0x4C4F434B”. Se dividirmos o número em 4 bytes e convertemos eles para os respectivos caracteres da tabela ASCII obteremos a palavra “LOCK”.

 

O registrador  GPIO_PORTF_AMSEL_R  controla a conexão de um pad com sua respectiva etapa analógica. Vale ressaltar que esta função é valida apenas em pinos compartilhados com o conversor analógico digital (ADC).

 

Já o registrador  GPIO_PORTF_PCTL_R  juntamente com o registrador  GPIO_PORTF_AFSEL_R  controlam as funções alternativas de um determinado pino de uma porta. Lembre-se que um mesmo pino pode ter diversas funções compartilhadas e estes registradores serão responsáveis por selecioná-las. Neste ponto os valores são mantidos zerados pois estamos selecionando a função principal de GPIO.

 

Nos próximos passos configuramos a direção de operação da porta através de GPIO_PORTF_DIR_R. Atribuindo “0” a um bit o deixa configurado como entrada, já o valor “1” o configura como saída. O registrador  GPIO_PORTF_PUR_R  habilita os resistores internos de pullup necessários para estabelecer um nível conhecido às chaves utilizadas como entrada. Por fim,  GPIO_PORTF_DEN_R  habilita a função como pino digital. Caso não seja habilitada tal função, o pino permanecerá em modo tristate.

 

Além da rotina de configuração da porta utilizada existe a função “ void Delay(void); ” que gera um atraso, permitindo criar espaços entre as ações. Para isto a função consome toda a CPU dentro de um loop desejado. Veja que esta não é a técnica mais eficiente computacionalmente e energeticamente, visto que você prende a CPU durante um tempo sem realizar nada de útil, ela está literalmente gastando tempo. A técnica mais interessante tem relação à utilização de timers ou do systick, mas este assunto será abordado mais à frente.

 

Por fim ficou faltando apenas o código que realmente avalia o estado da chave e realiza a ação necessária. Para simplesmente não darmos a resposta do exercício irei propor um exercício semelhante, mas utilizando a driverlib. Assim podemos explorar um pouco mais suas funções. Fica a dica de lerem o artigo anterior onde explico como criar um projeto com essa ferramenta no compilador CCS e também a apostila feita pelo Stéfano de Souza.

 

Neste exercício utilizaremos as duas chaves para controlar os led’s da launchpad. Assim como no original, a chave SW1 fará alternar entre os led’s verde e azul, enquanto SW2 alternará entre branco (os três led’s juntos) e azul. Ambas as chaves pressionadas não modificam o estado. Note que seguimos basicamente a mesma sequência de configuração dos periféricos, entretanto utilizando as funções da driverlib. Até para verificarmos o estado de uma entrada existe uma função.

 

O projeto completo está disponível no meu GitHub (dê uma olhada no cabeçalho main.c do projeto “Embarcados_00_tivaware”, criei uma orientação de como atualizar o projeto para que compile em outro computador onde o caminho das pastas seja diferente, a mesma orientação também está presente no arquivo Readme da pasta de projetos). Em “Embarcados_04_lab_02” está a solução mais próxima do exercício original, em “Embarcados_04_lab_02_mod” a modificação que propomos para o exercício.

 

 

Veja que precisamos desbloquear diretamente o acesso ao PF0. Como exercício adicional tente comentar as linhas relacionadas ao desbloqueio e verifique o comportamento após a compilação.

 

tiva-lab2-mod

 

Note que quando utilizamos a driverlib grande parte do trabalho de configuração (quase todo) é realizado de uma maneira discreta ao desenvolvedor, entretanto, é importante sabermos como isso funciona “por trás dos panos”, como é abordado no curso.

 

 

Terceiro Capítulo

 

Neste capítulo abordou-se um pouco sobre eletricidade básica, os conceitos de tensão, corrente, divisores resistivos, etc. O artigo Domine o divisor de tensão será uma boa referência para o leitor que está iniciando no mundo da eletrônica e busca entender melhor os conceitos base. Este capítulo é um pouco mais curto, não contando com laboratório a ser desenvolvido.

 

No próximo artigo abordaremos alguns dos próximos capítulos, até breve!

Outros artigos da série

<< Shape The World - IDE e ferramentas para Tiva C
Este post faz da série Shape The World. Leia também os outros posts da série:
NEWSLETTER

Receba os melhores conteúdos sobre sistemas eletrônicos embarcados, dicas, tutoriais e promoções.

Obrigado! Sua inscrição foi um sucesso.

Ops, algo deu errado. Por favor tente novamente.

Licença Creative Commons Esta obra está licenciada com uma Licença Creative Commons Atribuição-CompartilhaIgual 4.0 Internacional.

Haroldo Amaral
Doutorando em Eng. Elétrica pela Poli-USP, mestre em Eng. Elétrica pela UNESP-Bauru e graduado em Tecnologia em Sistemas Biomédicos pela FATEC-Bauru.Um apaixonado por eletrônica que adora passar seu tempo "queimando alguns componentes" e escovando alguns bits. Entre outras paixões estão a música, uma boa reunião com os amigos, papear sobre tecnologia e afins.

4
Deixe um comentário

avatar
 
2 Comment threads
2 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
João Paulo AndradeHaroldo AmaralFabio_Souza_Embarcados Recent comment authors
  Notificações  
recentes antigos mais votados
Notificar
João Paulo Andrade
Visitante
João Paulo Andrade

Haroldo muito bom os artigos! Eu estou trabalhando com a placa tm4C123Gxl e gostaria de saber se você vai continuar com os artigos ou parou nesses 3? Desde já agradeço a atenção.

Haroldo Amaral
Visitante
Haroldo Amaral

Olá João, obrigado pelo contato.

Tive que dar uma "pausa" em alguns artigos devido a alguns imprevistos e outros compromissos, mas daremos sequência sim. Em breve continuaremos dando continuação através dos outros exercícios propostos no curso

Fabio_Souza_Embarcados
Visitante
Fabio_Souza_Embarcados

Excelente artigo. Parabéns!

Haroldo Amaral
Visitante
Haroldo Amaral

Muito obriga Fabio!