Baixe o app para aproveitar ainda mais
Prévia do material em texto
Microprocessadores Material Teórico Responsável pelo Conteúdo: Prof. Me. Massaki de Oliveira Igarashi Revisão Textual: Prof.ª Dr.ª Selma Aparecida Cesarin Programação em Linguagem Assembler e C++Arduino • Capítulo 1 – Introdução; • Capítulo 2 – Programação Assembler; • Capítulo 3 – Programação C/C++ para Arduino. · Introduzir os conceitos de programação de microcontroladores e microprocessadores. Para isso, são apresentados ao leitor conceitos fundamentais e também conceitos de programação Assembler e C/C++ para microcontroladores PIC® e Arduino. OBJETIVO DE APRENDIZADO Programação em Linguagem Assembler e C++Arduino Orientações de estudo Para que o conteúdo desta Disciplina seja bem aproveitado e haja maior aplicabilidade na sua formação acadêmica e atuação profissional, siga algumas recomendações básicas: Assim: Organize seus estudos de maneira que passem a fazer parte da sua rotina. Por exemplo, você poderá determinar um dia e horário fixos como seu “momento do estudo”; Procure se alimentar e se hidratar quando for estudar; lembre-se de que uma alimentação saudável pode proporcionar melhor aproveitamento do estudo; No material de cada Unidade, há leituras indicadas e, entre elas, artigos científicos, livros, vídeos e sites para aprofundar os conhecimentos adquiridos ao longo da Unidade. Além disso, você também encontrará sugestões de conteúdo extra no item Material Complementar, que ampliarão sua interpretação e auxiliarão no pleno entendimento dos temas abordados; Após o contato com o conteúdo proposto, participe dos debates mediados em fóruns de discus- são, pois irão auxiliar a verificar o quanto você absorveu de conhecimento, além de propiciar o contato com seus colegas e tutores, o que se apresenta como rico espaço de troca de ideias e de aprendizagem. Organize seus estudos de maneira que passem a fazer parte Mantenha o foco! Evite se distrair com as redes sociais. Mantenha o foco! Evite se distrair com as redes sociais. Determine um horário fixo para estudar. Aproveite as indicações de Material Complementar. Procure se alimentar e se hidratar quando for estudar; lembre-se de que uma Não se esqueça de se alimentar e de se manter hidratado. Aproveite as Conserve seu material e local de estudos sempre organizados. Procure manter contato com seus colegas e tutores para trocar ideias! Isso amplia a aprendizagem. Seja original! Nunca plagie trabalhos. UNIDADE Programação em Linguagem Assembler e C++Arduino Capítulo 1 – Introdução Neste Capítulo, serão apresentados conceitos básicos necessários ao aprendi- zado das Linguagens de Programação utilizadas para microcontroladores e micro- processadores. Nos fóruns de discussões sobre microcontroladores, são muito comuns comen- tários valorizando esta ou aquela linguagem de programação para microcontrola- dores e microprocessadores, ou ressaltando um ou outro fabricante. Mas, para escolher a Linguagem e o Fabricante a se trabalhar, é importante ficar atento às características técnicas do projeto e levar em consideração, principalmente: a arquitetura, o consumo (caso o Projeto demande baixo consumo, ou seja, móvel), os periféricos, a velocidade e a capacidade de processamento, o tamanho, o encapsulamento e a escalabilidade (ou possibilidade de expansão). Além do tempo de fornecimento do produto, sua disponibilidade, seu suporte e a documentação do fabricante, a experiência do time de desenvolvimento e as ferramentas para correção de bugs. Já quanto às Linguagens de Programação a se utilizar, percebe-se que as princi- pais linguagens utilizadas são Assembler (ou Assembly) e linguagem C/C++, que também serão abordadas nesta Unidade. Primeiramente, é preciso entender o porquê de se utilizar Assembler: é uma Linguagem eficiente (ou seja, permite ao programador desenvolver um Programa que rode mais rápido, que consuma pouco processamento ou que exija o mínimo de memória possível); também, permite acesso direto ao hardware. Além disso, um bom Programador Assembly pode prover segurança e controle que nenhum outro poderia ter; porém, ele também pode abrir brechas que outras Linguagens não abririam. Apesar de muitas vantagens, é importante ressaltar que, geralmente, é muito trabalhoso, demorado e entediante programar em Assembler. Ciclo de Máquina O ciclo de máquina é o período de tempo no qual um microcontrolador ou microprocessador lê e processa uma instrução da sua memória para executar cada instrução em Código de Máquina num Programa. Para calcular o tempo de duração de um Ciclo de Máquina (CM ou TCY), basta obter o inverso do valor do clock interno (CKINT) do microprocessador ou microcontrolador, conforme ilustra a equação I: T CKCY INT = 1 (I) 8 9 Já o valor do clock interno pode variar entre os fabricantes de microcontroladores e microprocessadores. No caso da maioria dos microcontroladores PIC®, o clock interno é equivalente ao clock externo (CKEXT ou FOSC) dividido por 4 (Equação II): CK CK INT EXT= 4 (II) Observa-se que o clock externo é obtido a partir de um cristal oscilador adqui- rido comercialmente em lojas ou sites de componentes eletrônicos; esses cristais têm frequência de oscilação que podem variar de alguns quilohertz (kHz), no caso dos cristais de baixa potência, até algumas dezenas de mega-hertz, no caso dos cristais de alta velocidade. Portanto, no caso de se utilizar um cristal comercial cuja Fosc = 4 MHz, o ciclo de máquina será de 1 microssegundo. A característica de buscar a informação num Ciclo de Máquina e executá-la no próximo Ciclo é denominada pipeline. Ela permite que as instruções sejam execu- tadas dentro de um ciclo, gastando, no caso do cristal de 4MHz, 1 microssegundo. São exceções os casos de instruções que geram saltos no Contador de Programa (PC), como chamadas de rotinas e retornos; ao executar as instruções, o pipeline deve ser previamente limpo para depois poder ser carregado, novamente, com o endereço correto, consumindo para isso dois Ciclos de Máquina. Glossário de Termos Utilizados Para facilitar o aprendizado sobre a construção dos nomes e das instruções, foi escolhido como exemplo o set de instruções dos microcontroladores PIC®. A seguir, são elencados os principais termos e explicações a seu respeito: • Work: registrador ou acumulador temporário para as operações da ULA. Na Linguagem Assembler dos microontroladores, PIC é conhecido como W; • File: referência a um registrador (posição de memória). Utiliza-se a letra F para a sua representação nos nomes de instruções e f nos argumentos delas; • Access: referência ao acesso da memória RAM via Access Bank ou via Banco por meio do registrador BSR. Utiliza-se a letra a nos argumentos das instruções; • Literal: um número qualquer, que pode ser escrito na forma decimal, hexa- decimal ou binária. Utiliza-se a letra L para sua representação nos nomes de instruções e k nos argumentos delas; • Destino: local onde deve ser armazenado o resultado da operação. Existem somente dois destinos possíveis: f, que guarda o resultado no próprio registra- dor passado como argumento ou w, que coloca o resultado em Work. Mais especificamente, na sintaxe das instruções, o destino deve ser expresso pelos números 0 (w) e 1 (f). Mas, observa-se que as letras f e w são definidas no in- clude para facilitar a programação; • Não (Not): operação ou estado oposto. Utiliza-se a letra N para a sua repre- sentação nos nomes das instruções; 9 UNIDADE Programação em Linguagem Assembler e C++Arduino • Borrow: refere-se ao STATUS do bit Borrow (ou “vem 1” de uma operação de subtração) do registrador. Utiliza-se a letra B para sua representação; • Overflow: refere-se ao STATUS do bit overflow do registrador. Utilizam-se as letras OV para sua representação nos nomes das instruções; • Bit: refere-se a um bit específico dentro de um byte. Utiliza-se a letra B para sua representação nos nomes das instruções e b nos argumentos delas;• Teste: quando se deseja testar o estado de um bit, serve para descobrir se ele é zero ou um. Utiliza-se a letra T para representá-lo nos nomes das instruções; • Skip: significa “pulo”; é utilizado para criar desvios, pulando para a próxima linha. Utiliza-se a letra S para representá-lo nos nomes das instruções; • Set: refere-se ao ato de setar um bit; ou seja, torná-lo com o valor 1. Utiliza-se a letra S para representá-lo nos nomes das instruções; • Clear: refere-se ao clear de um bit, ou seja, torná-lo com valor 0. Utiliza-se a letra C para representá-lo nos nomes das instruções; • Toggle: refere-se ao ato de inverter o estado de um bit. Utiliza-se a letra T para representá-lo nos nomes das instruções; • Zero: algumas instruções podem gerar desvios se o resultado da operação efetuada for zero. Neste caso utiliza-se a letra Z para indicar tal condição; • ADD: somatória; • AND: lógica “E”; • CLR: limpar, zerar (Clear); • COM: complemento; • CPF: comparar registrador; • DEC: decremento de uma unidade; • EQ: igual; • GT: maior que (>); • INC: incremento de uma unidade; • IOR: lógica “OU”; • LT: menor que (<); • MOV: mover, transferir para algum lugar; • MUL: multiplicar; • RD: leitura; • RL: rotacionar um bit para a esquerda (rotation left); • RR: rotacionar um bit para a direita (rotation right); • SET: setar todos os bits de um registrador, ou seja, tornar todos com o valor 1; 10 11 • SUB: subtração; • SWAP: inversão entre as partes alta e baixa de um registrador; • TST: teste; • TBL: tabela; • XOR: lógica “OU Exclusivo”; • WT: escrita. Conversor Analógico-Digital A natureza e a maioria das coisas ao nosso redor são analógicas, por isso, é importante destacar aqui os conceitos necessários para uma conversão de um Sinal Analógico para Digital. Tais conceitos podem ser úteis na conversão de sinal de sensores de temperatura, pressão, tensão e posicionamento, entre outros. Um microcontrolador e também os microprocessadores podem monitorar um ou mais sinais por meios de sua(s) entrada(s) Analógico-Digitais (AD ou A/D), cuja resolução em bits varia de 4 a 12 bits, mas a resolução de 10 bits é uma das mais utilizadas. O primeiro conceito a se entender numa conversão analógico-digital é o valor correspondente à variação de cada unidade de tensão (Equação III): V V V unidade ref ref n= − − + − 2 1 (III) No caso de um microcontrolador alimentado a 5 Volts, ou seja, VREF+ = +5V e Vref– = 0 V (Comum da fonte) e , e considerando, ainda, uma resolução de 10 bits para esse microcontrolador, o valor , aproximadamente, ou seja, 5 milivolts. Para ser mais específico, 4,887585 mV. Uma vez convertido, o valor do Sinal Analógico pode ser representado por uma variável interna pela equação IV: Valor V V V conversor sinal analogico n referencia sinal a= −( ) =_ _ * 2 1 nnalogico bitV1 (IV) Para testar a equação IV, no nosso exemplo hipotético, consideremos que o Valor Analógico a ser convertido, instantaneamente, seja 2,0 Volts e, considerando, ainda, que no microcontrolador de uma tensão de referência de 5,0 Volts, o valor a ser devolvido pelo conversor será aproximadamente 410 (você entenderá, por meio do exemplo 2 de programação Assembler, que basta uma Regra de Três para converter novamente, via programa, esse valor convertido digitalmente para seu real valor introduzido na entrada analógica). 11 UNIDADE Programação em Linguagem Assembler e C++Arduino Tempo de aquisição e conversão do sinal Para se evitar problemas de ruído e variações da entrada analógica durante o processo de conversão, já que nada é absolutamente instantâneo, alguns micro- controladores e também microprocessadores utilizam, internamente, um processo denominado Sample and Hold (S/H), termo que se traduzido para o português significaria amostra e congela; observa-se que, no caso da ausência do S/H interno, pode-se acrescentar um circuito integrado S/H para atuar nesse caso. No caso dos microcontroladores PIC®, eles costumam apresentar um S/H inter- no com capacitor de valor 25 pF (vide datasheet do microcontrolador para expli- cação mais detalhada do circuito com o ), que é ligado ao Canal Analógico em uso. Esse capacitor carrega-se com a tensão existente no canal (tensão da amostra); quando o processo de conversão é iniciado, esse capacitor é desligado automa- ticamente do Canal Analógico, mantendo a tensão sobre o capacitor constante. Por isso, durante todo o processo de conversão, a tensão utilizada é a existente no capacitor e não mais a do Canal Analógico. Logo, mesmo que a tensão externa no canal varie, a conversão não é afetada. Internamente, o capacitor nunca fica desligado, exceto durante a conversão; ele sempre se encontra ligado ao Sistema de Entradas Analógicas. Mas caso o canal ativo esteja ligado ao GND, o capacitor ficará totalmente des- carregado. Mas se, num momento seguinte, desejar-se medir outra Entrada Analó- gica (outro Canal) e por isso o Sistema é chaveado internamente (será visto mais à frente como isso é possível). Caso o outro Canal esteja com uma tensão de 5,0 V, o capacitor interno terá de ser completamente carregado antes que seja possível começar a efetuar a nova conversão. Obviamente, essa carga não é instantânea. Para evitar problemas, sugere-se que o tempo padrão deixado para garantir a carga do capacitor seja de pelo menos 40 us. Obviamente, esse é um tempo que garante a pior condição. Na verdade, o tempo de adequação pode ser bem menor que isso, chegando ao mínimo a 1 μs. Essa variação depende basicamente da diferença de tensão entre a entrada e o capacitor, da temperatura e da impedância de entrada. Essa impedância deve ser de no mínimo 50 Ω e no máximo 2,5 Ω. Quanto menor a impedância, menor também o tempo de adequação. Para o cálculo exato desse tempo, consulte o datasheet do microcontrolador. Para que o Sistema de Conversão funcione corretamente, um clock deve ser aplicado a ele; nesse caso, cada período desse clock é chamado TAD e é equivalente ao tempo de conversão de 1 bit. No caso de um conversor de 10 bits, o tempo total de conversão é de 10TAD + 2TDA, ou seja, 12TAD. Os dois períodos adicionais são para a adequação e o início da conversão. Além disso, o valor de TAD depende da frequência empregada e, para isso, o Sistema possui um RC interno ou divisores para o oscilador da própria máquina. 12 13 Com o término da conversão, o valor dos registradores de resultado é atuali- zado, o flag da interrupção é marcado e o capacitor religado. O tempo mínimo recomendado para que tudo isso aconteça é de 2TDA. Observa-se que durante o tempo da conversão, o valor da tensão no capacitor interno não foi alterado; porém, ao término da conversão, ele será religado à entrada analógica, que pode ter sofrido uma variação brusca (como no exemplo anterior), seja por imposição do próprio Sistema, seja por uma troca de Canal. Por isso, entre uma conversão e outra é necessário que haja uma adequação da carga do capacitor. Nesse caso, recomenda-se, novamente, um tempo mínimo de 40 µs. O Módulo PWM O módulo PWM (sigla que advém do termo em inglês Pulse Width Modulation), que significa Modulação por Largura de Pulso, é, provavelmente, um dos recursos mais poderosos de um microcontrolador ou microprocessador, pois com ele pode- se obter um Sinal Digital com Largura de Pulsos controlada por meio de software. As aplicações do módulo PWM são diversas: controle de abertura e fechamento de válvulas, controle de motores, controle de luminosidade para LEDs, gerador de tensão analógica (observação: para esse tipo de aplicação, faz-se necessário adicio- nar um hardware complementar de conversor Digital-Analógico (DA) ou filtro RC com frequência de corte igual à frequência do PWM para que o Sinal Analógico seja gerado a partir de um pulso digital como é o caso do sinal PWM), entre outras. A Figura 1 mostra uma função digital da tensão V(t) no tempo, cujo período é T e a tensão de pulso Vpulso: GNDpulsoV tp T Figura 1 – Forma de onda de um sinal PWM Num sinal PWM, a razão entre a Largura de Pulso e o período da forma de onda recebe o nome, oriundo da língua inglesa, de duty cycle, cuja tradução seria ciclo ativo ou ciclo de trabalho. Esse pulso apresenta uma tensão fixa; porém, o valor médio da sua tensão varia em função do duty cycle. Portanto, a tensão média (Vdc) é diretamente proporcional ao duty cycle e como esse varia entre 0 (quando tp = 0) e 1 (quando tp = T), a Tensão Média de Onda pode variar entre 0 e ou, mais especificamente, entre 0 e 5 Volts quando VSS = 0 e VDD = 5V, conforme a Equação V. V t T Vdc p pulso= (V) 13 UNIDADE Programação em Linguagem Assembler e C++Arduino Capítulo 2 – Programação Assembler Neste Capítulo, você aprenderá um pouco dos conceitos básicos de programação Assembler para microcontroladores e microprocessadores. Para o aprendizado e prática da Linguagem Assembler, recomenda-se instalar algum compilador de Assembler disponível na Internet ou utilizar, por exemplo, softwares já consolidados e conhecidos como o MPLAB®, do fabricante Microchip Technology Inc. Vale ressaltar, também, que você pode utilizar algum gravador de microcontro- lador comercial, ou comprar um gravador universal ou, até mesmo, construir seu próprio gravador para realizar testes de prototipagem, seguindo dicas facilmente encontradas na Internet. Na linguagem Assembler, a utilização do “;” serve para introduzir comentários no programa; esses comentários não terão função alguma dentro do programa, servindo apenas para sua organização pessoal e explicação de comandos utilizados. Os comentários o ajudarão a entender o seu programa caso você só volte a utilizá- lo após um longo prazo, mas, também, são úteis para que outros programadores possam entender o seu programa. Exemplo 1: Programa Pisca Leds Nesse primeiro exemplo, será utilizado o microcontrolador PIC12F675, um microcontrolador muito utilizado para aplicações simples e até semiprofissionais; por meio do seu datasheet, é possível descobrir quais Registradores de Função Especial (SFRs) devem ser configurados e com quais valores, de acordo com as especificações do Sistema. Ao fazer isso, para esse primeiro exemplo, constata-se que é preciso configurar os registradores a seguir para que o Programa, que será escrito, funcione adequa- damente conforme o circuito da Figura 2. Serão apresentados também alguns registradores e comandos básicos da Lin- guagem Assembler num programa cuja funcionalidade é fazer piscar três LEDs: um verde (ligado no pino 2), um amarelo (ligado no pino 3) e um vermelho (ligado no pino 6), em intervalos de 500 ms. 14 15 + + + PIC 12F675 5V 5V 5V 5V 10k 330 1 2 3 4 5678 330 330 Verde Amarelo VermelhoPotenciômetro Chave 1 Chave 2 + Figura 2 – Circuito base do exemplo pisca LED • a) ANSEL – Seleção da Função Analógica ou Digital para os pinos de entrada e saída que podem operar nesses dois modos, conforme descrito a seguir. Ao se escrever “1” no bit associado ao pino, indica-se que o seu funcionamento será no Modo Analógico; já se for escrito “0”, configura-se o pino para trabalhar no Modo Digital: » Pino 7 – Modo Digital (GPIO 0) ou Modo Analógico (AN 0); » Pino 6 – Modo Digital (GPIO 1) ou Modo Analógico (AN 1); » Pino 5 – Modo Digital (GPIO 2) ou Modo Analógico (AN 2); » Pino 3 – Modo Digital (GPIO 4) ou Modo Analógico (AN 3). • b) TRISIO – Definição da direção do sinal (entrada ou saída) em um pino. Ao escrevermos “0” no bit associado ao pino, configura-se o pino como saída (output); já se for escrito “1”, conFigura-se o pino como entrada (input); • c) CMCON – Controle das funções do comparador de tensão interno do microcontrolador; • d) GPIO – Seleção do nível lógico de um pino quando ele for configurado como saída digital, ou leitura do nível presente em um pino quando ele for configurado como entrada digital. Para fazer a configuração correta desses SFRs, é preciso estar atento ao fato de que os registradores ANSEL e TRISIO estão presentes fisicamente no Banco de Memória 1, enquanto os registradores CMCON e GPIO estão presentes fisicamente no Banco de Memória 0. Sendo assim, antes de utilizá-los, deve-se configurar adequadamente o bit 5 (RP0) do registrado STATUS. 15 UNIDADE Programação em Linguagem Assembler e C++Arduino A Tabela 1 traz, em sua coluna da esquerda, o Código completo de um Programa desse primeiro exemplo e, na coluna da direita, as explicações e o detalhamento das instruções desse Programa, que está dividido em blocos, para facilitar seu entendimento. Tabela 1 – Exemplo de um programa Assembler pisca LED com suas explicações ;INCLUSAO DE BIBLIOTECAS #INCLUDE <p12f675.inc> ; definições referentes ao PIC12F675 Deve-se incluir as bibliotecas necessárias; elas, geralmente, já estão nos compiladores. Mas, caso contrário, os fabricantes disponibilizam atualizações nos seus sites. ;CONFIGURAÇÃO DO MODO DE FUNCIONAMENTO __CONFIG _INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLR_ OFF & _CPD_OFF & _CP_OFF & Alguns comandos habilitam ou desabilitam chaves internas que apresentam algumas funcionalidades específicas, como a seguir: _INTRC_OSC_NOCLKOUT ;o PIC utilizará o oscilador interno de 4 MHz, _WDT_OFF ; desliga o Watchdog timer. _PWRTE_OFF ; desliga o reset de power on. _MCLRE_OFF ; desliga o masterclear. Os comandos se unem pelo concatenador & ;DEFINIÇÃO DOS NOMES E ENDEREÇOS DAS VARIÁVEIS UTILIZADAS NO PROGRAMA CBLOCK 0x0C ; endereço inicial da memória de usuário TEMP1 ; contador para o delay de 1 ms TEMP500 ; contador para o delay de 500 ms ENDC ; fim do bloco de memória de variáveis Precisa-se declarar o endereço inicial para a criação das variáveis e também definir cada uma das variáveis. ;DEFINIÇÃO DAS ENTRADAS DIGITAIS #DEFINE Chave_1 GPIO, 2; Pino 5 #DEFINE Chave_2 GPIO, 3; Pino 4 ;DEFINIÇÃO DAS SAÍDAS DIGITAIS #DEFINE LED_VD GPIO, 5 ; Pino 2 #DEFINE LED_AM GPIO, 4 ; Pino 3 #DEFINE LED_VM GPIO, 1 ; Pino 6 Além disso, é preciso associar nomes significativos aos pinos de entrada e saída do microcontrolador que serão utilizados. ;DEFINIÇÃO DO SELETOR DO BANCO DE MEMÓRIA #DEFINE Banco STATUS, RP0 ;bit RP0 do registradorSTATUS (SFR) ;CONFIGURAÇÃO DOS SFRs BSFBanco ; Seleção do Banco 1 da Memória MOVLW B’00000001’ ; modo analógico/digital dos pinos de I/O MOVWF ANSEL MOVLW B’00001101’ ; direção dos pinos de I/O digitais MOVWF TRISIO BCF Banco ; seleção do Banco 0 da Memória MOVLW B’00000111’ ; desativação do comparador de tensão MOVWF CMCON Também é preciso configurar alguns registradores internos que serão utilizados no programa. Costuma-se, inicialmente, colocar o valor numérico para o registrador W (comando MOVLW) e, na sequência, transferir o valor de W para o registrador alvo (comando MOVWF). ;INICIALIZAÇÃO DO PROGRAMA BCF LED_VD ; apaga o LED verde BCF LED_AM ; apaga o LED amarelo BCF LED_VM ; apaga o LED vermelho Aqui, são inicializados os pinos de saída, apagando todos os LEDs pela imposição de valor zero aos pinos correspondentes (comando BCF). 16 17 ;ROTINA PRINCIPAL, implementa um loop infinito Principal: BSF LED_VD ; acende o LED verde CALL DELAY_500MS ; pausa de 500 ms BCF LED_VD ; apaga o LED verde CALL DELAY_500MS ; pausa de 500 ms GOTO Principal ; salto para o início da rotina principal ; Rotina de delay de 500 ms. Repete 200 x a rotina de 2,5 ms Agora, deve-se implementar um loop infinito criando o rótulo Principal, executando algumas instruções e, no final, efetuando um salto incondicional (GOTO) para o mesmo label. Inicialmente, liga-se o LED verde pela imposição de nível 1 no pino correspondente (Comando BSF). Em seguida, chama-se a sub-rotina que provoca um delay de 500 ms. Depois, novamente coloca-se o nível “0” no LED (chamamos novamente a sub-rotina de delay de 500 ms) e se recomeça a mesma sequência. DELAY_500MS: MOVLW .200 MOVWF TEMP500 DL_50 CALL DELAY_2MS ; pausa de 10 ms DECFSZ TEMP500,F ; decrementa TEMP500. Zerou? GOTODL_50 ; não, repete o ciclo. RETURN ; sim, finaliza a rotina. ; Rotina de delay de 2,5 ms. Repete 250 x a rotina de 10 μs DELAY_2MS: MOVLW .250 MOVWF TEMP1 DL_10 ; cada ciclo gasta 10 microsegundos NOP ; gasta um ciclo de tempo NOP ; gasta um ciclo de tempo NOP ; gasta um ciclo de tempo NOP ; gasta um ciclo de tempo NOP ; gasta um ciclo de tempo NOP ; gasta um ciclo de tempo NOP ; gasta um ciclo de tempo DECFSZ TEMP1,F ; decrementa TEMP1. Zerou? GOTO DL_10 ; não, repete o ciclo RETURN ; sim, finaliza a rotina O delay de 500 ms é obtido por meio da repetição (200 vezes) da rotina de atraso de 2,5 ms. Inicia-se colocando o valor 200 na variável TEMP500 (por meio do registrador W) e se efetuam sucessivas chamadas à rotina de atraso de 2,5ms. Depois disso, deve-se ir decrementando a variável TEMP500 até que ela chegue a zero, momento em que haverá o retorno (RETURN) da sub-rotina. Analogamente, há a rotina de atraso de 2,5 ms, obtida pela repetição (250 vezes) de um bloco que consome 10 microsegundos. Esse tempo é alcançado por meio de sete instruções NOP (que não possuem função alguma e consomem 1 ciclo de máquina), uma instrução DECFSZ (que consome mais 1 ciclo de máquina) e a instrução GOTO (que consome 2 ciclos de máquina). END ;FIM DO PROGRAMA Finalmente, o programa se encerra com a instrução END. Exemplo 2: Programa Conversão AD Este segundo exemplo, diferente do primeiro, foi escrito com base no datasheet do microcontrolador PIC18F4520, outro microcontrolador muito utilizado por amantes de eletrônica e até mesmo para aplicações profissionais. Ele é muito parecido com o PIC12F675, mas, ao invés de 4 conversores AD, como é o caso do primeiro, o PIC18F4520 possui 10 conversores no caso dos encapsulamentos de 28 pinos (por exemplo, encapsulamento DIP) e 13 conversores AD no caso dos encapsulamentos de 44 pinos (por exemplo, encapsulamento TQFP e QFN); esse maior número de entradas analógico-digitais possibilitam-no se conectar a um maior número de sensores e, portanto, aplicações mais complexas. Claro que ainda são possíveis outros tipos de expansão ou conexão do mi- crocontrolador ou microprocessador digitalmente a circuitos integrados dedicados, especificamente para a conversão AD, ou também multiplexação de sinais, mas 17 UNIDADE Programação em Linguagem Assembler e C++Arduino essas abordagens mais complexas não serão vistas neste Curso Introdutório de microprocessadores e microcontroladores. Esse exemplo consiste num programa Assembler para leitura da tensão ajustada pelo potenciômetro ou trimpot P2 (Figura 3). A conversão será realizada direta- mente no loop principal do Programa, sem a utilização de interrupção específica (nem para verificar o término da conversão, nem para definir a frequência de amostragem); portanto, a conversão será realizada uma após a outra, na frequência definida pelo período do loop principal. + 4,7K LM358 P2 10K +5V +5V +5V 4MHz RS EN 10K Reset MC1 +5V 1uF 330R RA1 +5V 10K RS EN LCD 4 1 3 27 8 9 10 11 12 13 14 6 5 RS EN R/W VDB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 DD VSS VO MCLR RAD RA1 RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC6 PIC18F4520 RA2 RA3 RA4 RA5 RE0 RE1 RE2 RC0 RC1 RC2 RC3 RC4 RC524 23 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25 OSC1 OSC2 VDD VSS VDD VSS Figura 3 – Esquema elétrico do circuito de conversão AD interno utilizando um microcontrolador PIC18F4520 Nesse caso, terminada a conversão, descartam-se os dois bits menos significativos e se considera somente o resultado armazenado em ADRESH; isso fará com que já ocorra uma espécie de filtragem e se evita uma oscilação do valor final convertido. O valor a ser exibido por meio do display LCD nada mais é que o valor calculado por uma Regra de Três (Equação V). Isso ocorre porque o AD interno do microcontrolador retorna o valor de conversão 0 para valor de entrada Ventrada = 0,0 Volt e 255 para valor de entrada Ventrada = 5,0 Volts, no caso de microcontroladores alimentados a 5,0 Volts. Portanto, para se descobrir Ventrada basta-se dividir o valor convertido (Vconv) por 255 e multiplicar o resultado por 5,0. V Vconv Voltsentrada = 255 5 0* , [ ] (VI) A seguir, o exemplo de um Programa de Conversão AD utilizando um dos conversores AD internos ao microcontrolador PIC deste exemplo: 18 19 ;********************************************************************** ; EXEMPLO ELABORADO PARA EXPLICAR O MÓDULO DE CONVERSAO AD INTERNO DO ; PIC, ; Será convertido o valor analógico presente no pino RA2 do microcontrolador ; O valor na entrada a ser convertido varia entre 0,0 Volt a 5,0 Volts e é mostrado no LCD 16x16 ; Rotinas do LCD são baseadas no APLICATION NOTES da MICROCHIP. ; ; CONFIGURACÕESS PARA GRAVACAO ; CONFIG OSC= XT, FCMEN = OFF, IESO = OFF, PWRT= ON, BOREN = ON, BORV= 0 CONFIG WDT = ON, WDTPS = 128, MCLRE = ON, LPT10SC= OFF, PBADEN= OFF CONFIG CCP2MX = PORTC, STVREN= ON, LVP = OFF, DEBUG = OFF, XITNST=OFF CONFIG CP0= OFF, CP1 = OFF, CP2 = OFF, CP3= OFF, CPB=OFF, CPD = OFF CONFIG WRT0 = OFF, WRT1= OFF, WRT2 = OFF, WRT3 = OFF, WRTB= OFF CONFIG WRTC = OFF, WRTD = OFF, EBTR0 = OFF, EBTR1 = OFF, EBTR2= OFF CONFIG EBTR3= OFF, EBTRB = OFF ;********************************************************************* ; DEFINICAO DAS VARIAVEIS ;********************************************************************* CBLOCK 0X00 ; BANK 0 --- > 0X00 .. 0X5F --- > ACCESS BANK ACCaHI ; ACUMULADOR a DE 16 BITS A SER UTILIZADO ACCaLO ; NA ROTINA DE DIVISÃO ACCbHI ; ACUMULADOR b DE 16 BITS A SER UTILIZADO ACCbLO ; NA ROTINA DE DIVISÃO ACCcHI ; ACUMULADOR c DE 16 BITS A SER UTILIZADO ACCcLO ; NA ROTINA DE DIVISÃO ACCdHI ; ACUMULADOR d DE 16 BITS A SER UTILIZADO ACCdLO ; NA ROTINA DE DIVISÃO Temp ; CONTADOR TEMPORÁRIO UTILIZADO ; NA ROTINA DE DIVISÃO TEMPO0 ; TEMPORIZADORES PARA A ROTINA TEMPO1 AUX ; REGISTRADOR AUXILIAR DE USO GERAL UNIDADE ; ARMAZENA VALOR DA UNIDADE DE TENSÃO DEZENA ; ARMAZENA VALOR DA DEZENA DE TENSÃO ENDC 19 UNIDADE Programação em Linguagem Assembler e C++Arduino #INCLUDE <P18F4520.INC> ; BIBLIOTECA DO MICROCONTROLADORUTILIZADO ; ESTE PROGRAMA UTILIZA APENAS 1 ENTRADA, NO CASO A ENTRADA RA1 DO CONV. AD ; SERA UTILIZADO DEFINE APENAS P/ DEFINIR UM NOME MAIS PRÁTICO P/ ESTA ENTRADA ; OBS: O CANAL AD A SER CONVERTIDO É SELECIONADO NO REGISTRADOR ADCN0 ; DE FORMA BINÁRIA, E NÃO ATRAVÉS DE DEFINES #DEFINE CAD_P2 PORTA, 1 ; SERA UTILIZADO DEFINE TAMBÉM PARA FACILITAR NOMENCLATURA DAS ; SAÍDAS DO PROGRAMA #DEFINE DISPLAY LATD ; ACESSO AO BARRAMENTO DE DADOS P/ DISPLAY # RS LATE, 0; INDICA PARA O DISPLAY DADO ou COMANDO ; 1 -> DADO ; 0 -> COMANDO #DEFINE ENABLE LATE, 1; SINAL DE ANABLE P/ O DISPLAY . ATIVO NA BORDA DE DESCIDAS ; VETOR DE RESET DO MICROCONTROLADOR ; POSICAO INCIAL PARA EXECUÇÃO DO PROGRAMA ORG 0X0000 ; ENDEREÇO DO VETOR DE RESET BRA CONFIGURACAO ;PULA P/ CONFIGURACAO ;DEVIDO REGIAO DAS RITINAS SEGUINTES ;********************************************************************* ; ROTINA DE DELAY (de 1 ms até 256ms ;********************************************************************* ; OBS: Esta é uma rotina de delay variável, com duração de 1 ms x Valor passado em Work (W). DELAY_MS MOVWF TEMPO1 ;CARREGA TEMPO 1 (UNIDADE DE MS) MOVLW .250 MOVWF TEMPO0 ; CARREGA TMEPO PARA CONTAR 1 MS CLRWDT ; LIMPA WDT (GASTA TEMPO) DECFSZ TEMPO0, F ; FIM DE TEMPO0? BRA $-.4 ; NÃO = VOLTA 2 INSTRUÇÕES ; SIM = PASSOU-SE 1 MS DECFSZ TEMPO1, F ; FIM DE TEMPO 1? BRA $-.12 ; NÃO = VOLTA 6 INSTRUÇÕES ; SIM = RETORNA RETURN ;********************************************************************* 20 21 ; ROTINA PARA ESCRITA DE CARACTERES NO DISPLAY LCD ;********************************************************************* ; OBS: O caractera ser escrito deve ser colocado em work (W) antes de se chamar a rotina ESCREVE MOVWF DISPLAY ; ATUALIZA DISPLAY (PORTD) NOP BSF ENABLE ; ENVIA UM PULSO DE ENABLE AO DISPLAY BRA $+.2 BCF ENABLE MOVLW .1 RCALL DELAY_MS ; CHAMA ROTINA DELAY_MS para delay de 1ms RETURN ; RETORNA ;********************************************************************* ; ROTINA DE AJUSTE DECIMAL ; W [HEX] = DEZENA [DEC] ; UNIDADE [DEC] ;********************************************************************* ; OBS: esta rotina recebe um argumento passado pelo Work e retorna nas variáveis ; Dezena e Unidade o número BCD correspondente ao parâmetro passado AJUSTE_DECIMAL CLRF UNIDADE ; RESETA REGISTRADOR UNIDADE CLRF DEZENA ; RESETA REGISTRADOR DEZENA MOVWF AUX ; SALVA VALOR A CONVERTER EM AUX MOVF AUX, F ; VALOR A CONVERTER = 0? BZ $+.18 ; SIM = RETORNA INCF UNIDADE, F ; NÃO = INCREMENTA UNIDADE MOVF UNIDADE, W XORLW 0X0A ; UNIDADE = 10d? BNZ $+.6 ; NÃO CLRF UNIDADE ; SIM = RESETA UNIDADE INCF DEZENA, F ; INCREMENTA DEZENA DECFSZ AUX, F ; FIM DA CONVERSÃO? BRA $-.14 ; NÃO = VOLTA P/ CONTINUAR CONVERSÃO RETURN ; SIM ;********************************************************************* ; ROTINA DE DIVISÃO Double Precision Division ; ACCb (16 bits), ACCa (16 bits) ; ACCb with Reminder in ACCc (16 bits) 21 UNIDADE Programação em Linguagem Assembler e C++Arduino ;********************************************************************* D_divF MOVLW .16 MOVWF temp ; CARREGA CONTADOR PARA DIVISÃO MOVFF ACCbHI, ACCdHI MOVFF ACCbLO, ACCdLO ; SALVA ACCb M ACCd CLRF ACCbHI CLRF ACCbLO ; LIMPA ACCb CLRF ACCcHI CLRF ACCcLO ; LIMPA ACCc DIV BCF STATUS, C RLCF ACCdLO, F RLCF ACCdHI, F RLCF ACCcLO, F RLCF ACCcHI, F MOVF ACCaHI, W SUBWF ACCcHI, W ; CHECAR SE a > c BTFSS STATUS, Z BRA NOCHK MOVF ACCaLO, W SUBWF ACCcLO, W ;SE MSB IGUAL ENTÃO CHECAR LSB NOCHK BTFSS STATUS, C ; SETA O CARRY SE c>a BRA NOGO MOVF ACCaLO, W ; c-a em c SUBWF ACCcLO, F BTFSS STATUS, C DECF ACCcHI, F MOVF ACCaHI, W SUBWF ACCcHI, F BSF STATUS, C ; Muda um 1 dentro de b (resultado) NOGO RLCF ACCbLO, F RLCF ACCbHI, F DECFSZ temp, F ; FIM DA DIVISÃO? BRA DIV ; NÃO = VOLTA PARA DIV RETURN ; SIM = RETORNA ;********************************************************************* ; CONFIGURAÇÕES INICIAIS DE HARDWARE E SOFTWARE ; INCIALIZAÇÃO DAS PORTAS DE ENTRADA/SAÍDA DO MICROCONTROLADOR 22 23 ;ATRAVÉS DOS REGISTRADORES ESPECIAIS (SFR) ;********************************************************************* ; OBS: Coloca todas as saídas em nível Zero através do comando CLRF CONFIGURACAO CLRF PORTA CLRF PORTB CLRF PORTC CLRF PORTD CLRF PORTE CLRF LATA CLRF LATB CLRF LATC CLRF LATD CLRF LATE MOVLW B’11111111’ MOVWF TRISA ; CONFIGURA I/O DO PORTA MOVLW B’11111111’ MOVWF TRISB ; CONFIGURA I/O DO PORT B MOVLW B’11111111’ MOVWF TRISC ; CONFIGURA I/O DO PORT C MOVLW B’00000000’ MOVWF TRISD ; CONFIGURA I/O DO PORT D MOVLW B’00000100’ MOVWF TRISE ; CONFIGURA I/O DO PORT E MOVLW B’11011000’ MOVWF T0CON ; CONFIGURA TIMER 0 ; TIMER 0 INCREM. PELO CICLO DE MAQ. TIMER0 – 1:1 MOVLW B’00000000’ MOVWF INTCON ;DESABILITA TODAS AS INTERRUPÇÕES MOVLW B’00000000’ ;CONFIGURA CONVERSOR AD MOVWF ADCON2 ; VELOCIDADE ->Fosc/8 ; JUSTIFICADO À ESQUERDA ; 8 BITS EM ADRESH E 2 BITS EM ADRESL ; TEMPO AQUISICAO CAPACITOR POR SOFTWARE 23 UNIDADE Programação em Linguagem Assembler e C++Arduino MOVLW B’00001101’ ;CONFIGURA CONVERSOR AD MOVWF ADCON1 ; RA0 e RA1 ENTRADAS ANALÓGICAS ; RA2, RA3, RA4 E RA5 I/O DIGITAIS ; PORTB E PORTE COMO I/O DIGITAL ; Vref+ = +Vdd(+5V) ; Vref- = GND (0V) MOVLW B’00000101’ ;CONFIGURA CONVERSOR AD MOVWF ADCON0 ; CANAL 1 ; MODULO LIGADO ; As instruções a seguir fazem com que o microcontrolador trava quando houver um ; RESET ou POWER-UP, mas passe direto se o RESET for por Watchdog timer (WDT). ;Desta forma,sempre que o PIC for ligado, o microcontrolador trava, ;aguarda um estouro de WDT e começa novamente. Isto evita problemas no start-up. BTFSC RCON, NOT_TO ; RESET POR ESTOURO DE WDT BRA $ ; NÃO = AGUARDA ESTOURO WDT ; SIM ;********************************************************************* ; INICIALIZAÇÃO DA RAM ;********************************************************************* ; OBS: Esta rotina limpará toda a RAM. Do Banco 0 até o Banco 15 LFSR FSR, 0X00 ; APONTA FSR0 PARA O ENDEREÇO 0 LIMPA_RAM CLRF POSTINC0 ; LIMPA A POSIÇÃO E INCREMENTA FSR0 CLRWDT ; LIMPA O WATCHDOG TIMER MOVLW 0X0F ; TESTA SE JÁ CHEGOU AO BANCO 15 SUBWF FSR0H, W ; BNZ LIMPA_RAM ; SE NÃO, CONTINUA LIMPANDO ;********************************************************************* ; CONFIGURAÇÕES INICIAIS DO DISPLAY LCD ;********************************************************************* ; OBS: Esta rotina inicializa o LCD p/ comunicação 8 vias. configurando 2 Linhas, cursor apagado e ; deslocamento do cursos para a direita INICIALIZACAO_DISPLAY BCF RS ; SELECIONA DISPLAY PARA COMANDOS MOVLW 0X30 ; ESCREVE COMANDO 0X30 PAR RCALL ESCREVE ; INICIALIZAÇÃO 24 25 MOVLW .3 RCALL DELAY_MS ; DELAY DE 3MS (EXIGIDO PELO DISPLAY) MOVLW 0X30 ; ESCREVE COMANDO 0X30 PARA RCALL ESCREVE ; INICIALIZAÇÃO MOVLW 0X30 ; ESCREVE NOVAMENTE COMANDO 0X30 PARA RCALL ESCREVE ; INICIALIZAÇÃO MOVLW B’00111000’ ; ESCREVE COMANDO PARA INTERFACE DE RCALL ESCREVE ; 8 VIAS DE DADOS MOVLW B’00000001’ ; ESCREVE COMANDO PARA LIMPAR RCALL ESCREVE ; TODO O DISPLAY MOVLW .1 RCALL DELAY_MS ; DELAY DE 1MS (EXIGIDO PELO DISPLAY) MOVLW B’00001100’ ; ESCREVE COMANDO PARA RCALL ESCREVE ; LIGAR O DISPLAY SEM O CURSOR MOVLW B’00000110’ ; ESCREVE COMANDO PARA INCREMENTAR RCALL ESCREVE ; AUTOMATICO À DIREITA BSF RS ; SELECIONA O DISPLAY PARA DADOS ;********************************************************************* ; ROTINA PARA A ESCRITA DA TELA INICIAL ;********************************************************************* ; OBS: Esta rotina escreve nas duas respectivas linhas do display as seguintes palavras: ; LINHA 1: “AD Int (P2) “ ; LINHA 2: Volts “ MOVLW 0X81 ; COMANDO PARA POSICIONAR O CURSOR RCALL ESCREVE ; NA LINHA 0 / COLUNA 1 BSF RS ; SELECIONA O DISPLAY PARA DADOS MOVLW ‘A’ RCALL ESCREVE MOVLW ‘/’ RCALL ESCREVE MOVLW ‘D’ RCALL ESCREVE 25 UNIDADE Programação em Linguagem Assembler e C++Arduino MOVLW ‘ ’ RCALL ESCREVE MOVLW ‘I’ RCALL ESCREVE MOVLW ‘n’ RCALL ESCREVE MOVLW ‘t’ RCALL ESCREVE MOVLW ‘.’ RCALL ESCREVE MOVLW ‘ ’ RCALL ESCREVE MOVLW ‘ ’ RCALL ESCREVE MOVLW ‘ ( ’ RCALL ESCREVE MOVLW ‘P’ RCALL ESCREVE MOVLW ‘2’ RCALL ESCREVE MOVLW ‘)’ RCALL ESCREVE BCF RS ; SELECIONA O DISPLAY PARA COMANDOS MOVLW 0XC7 ; COMANDO PARA POSICIONAR O CURSOR RCALL ESCREVE ; NA LINHA 1 COLUNA 7 BSF RS ; RETORNA CONFIG. DISPLAY PARA DADOS MOVLW ‘V’ RCALL ESCREVE MOVLW ‘o’ RCALL ESCREVE MOVLW ‘l’ RCALL ESCREVE MOVLW ‘t’ RCALL ESCREVE MOVLW ‘s’ RCALL ESCREVE ;********************************************************************* ; LOOP PRINCIPAL DO PROGRAMA ;********************************************************************* 26 27 LOOP CLRWDT ; LIMPA O WDT BSF ADCON0, GO ; INICIA A CONVERSAO AD BTFSC ADCON0, GO ; FIM DA CONVERSAO? BRA $-.2 ; NÃO = VOLTA 1 INSTRUÇÃO ; SIM MOVF ADRESH, W ; SALVA VALOR DA CONVERSÃO NO WORK MULLW .50 ; MULTIPLICA VALOR DO AD POR 50 MOVFF PRODH, ACCbHI ; CARREGA ACCb C/ RESULTADO DA MULT MOVFF PRODL, ACCbLO ; (NUMERADOR) CLRF ACCaHI ; CARREGA ACCa COM 255d (Fundo de escala do MOVLW .255 ; CONVERSOR AD 8 BITS, JUSTIFICADO A ESQUERDA MOVWF ACCaLO ; (DENOMINADOR)RCALL D_divF ; CHAMA ROTINA DE DIVISÃO MOVF ACCbLO, W ; FAZ AJUSTE DECIMAL DO RESULT. DIVISÃO RCALL AJUSTE_DECIMAL ; PARA MOSTRAR NO DISPLAY LCD BCF RS ; SELECIONA O DISPLAY PARA COMANDOS MOVLW 0XC3 ; COMANDO PARA POSICIONAR O CURSOR RCALL ESCREVE ; NA LINHA 1 COLUNA 3 BSF RS ; RETORNA CONFIG. DISPLAY PARA DADOS MOVF DEZENA, W ADDLW 0X30 ; CONVERTE BCD DA DEZENA EM ASCII RCALL ESCREVE ; ENVIA AO LCD MOVLW ‘,’ ; ESCREVE UMA VÍRGULA RCALL ESCREVE ; NO LCD MOVF UNIDADE, W ADDLW 0X30 ; CONVERTE BCD DA UNIDADE EM ASCII RCALL ESCREVE ; ENVIA AO LCD BRA LOOP ; VOLTA PARA O LOOP ;********************************************************************* ; FIM DO PROGRAMA ;********************************************************************* END ; FIM 27 UNIDADE Programação em Linguagem Assembler e C++Arduino Capítulo 3 – Programação C/C++ para Arduino Neste Capítulo você aprenderá um pouco de Programação C/C++ utilizada nas Plataformas Arduino. Primeiramente, é importante justificar ao leitor o porquê da escolha de um novo microcontrolador para a explicação da programação C/C++, quando seria possível ter escolhido, novamente, a plataforma PIC® para microcontroladores. Como este Curso é introdutório e com ele se pretende apresentar um pouco dos principais recursos disponíveis para iniciar trabalhos com microcontroladores e microprocessadores. Portanto, basta o domínio dos conceitos iniciais de uma Linguagem e um fabricante que, com um pouco de estudo sobre os tutoriais e dicas disponíveis nos sites dos demais fabricantes e na Internet, o leitor pode, facilmen- te, adaptar-se às modificações necessárias e evoluir numa ou noutra linguagem e microcontrolador ou microprocessador escolhido. O Arduino é, hoje, uma das principais plataformas de Código Aberto utilizada em todo o mundo. Surgiu em meados de 2005, desenvolvida por professores e uni- versitários de uma Universidade italiana para auxiliar no ensino de eletrônica, e se difundiu entre os amantes de eletrônica, hobistas e afins. O objetivo principal sem- pre foi que o Arduino fosse uma plataforma de baixo custo e acessível para todos. Antes de galgar os primeiros passos na Linguagem C/C++ para Arduino, é preciso enfatizar que, assim como no C/C++ os comentários podem ser feitos colocando duas barras de divisão (//) na frente da frase comentário ou destacando um parágrafo inteiro como comentário ao se introduzir “/*” no início do parágrafo e, após a última palavra ou após o ponto final do parágrafo, coloca-se “*/” para simbolizar que o parágrafo de comentário foi finalizado. Introdução ao Arduino A Plataforma Arduino é formada, principalmente, pelo Hardware e pelo Software. O hardware é composto por uma Placa Eletrônica que facilita a programação e a utilização do microcontrolador; ela pode ser facilmente adquirida em sites de e-commerce, a partir da qual são construídos os projetos. O software para programação do microcontrolador do Arduino (o microcon- trolador base do ArduinoOne® é um microcontrolador ATMEGA328) é uma IDE, que é executado num computador no qual é feita a programação baseada em lin- guagem C/C++. Os programas desenvolvidos para Arduino são, costumeiramente, chamados pela comunidade de sketch. 28 29 Terminado um Sketch, deve ser feito o upload para a placa do Arduino, por meio de uma comunicação serial previamente configurada via software. O sketch feito pelo projetista dirá à Placa o que deve ser executado durante o seu funcionamento, assim como qualquer outro Programa desenvolvido em qualquer outra Linguagem para microcontroladores e microprocessadores. Existem diversas placas oficiais de Arduino e muitas outras cópias não oficiais; mas como o Código é Aberto, diga-se de passagem, que são adaptações projetadas e atualizadas pela comunidade. Para efeitos introdutórios deste Curso, serão abordados aqui conceitos de programação da placa Arduino Uno REV3: Figura 4 – Placa Arduino UMO Fonte: site do fabricante – <https://store.arduino.cc/usa/arduino-uno-rev3>. Essa placa possui diversos conectores que servem de interface para os demais componentes eletrônicos do Circuito Eletrônico do Projeto; possui 14 pinos de entrada e/ou saída digital (pinos 0 a 13), cuja finalidade pode ser programada de acordo com a necessidade do projeto e conforme definido no sketch criado na IDE do Arduino. Possui, ainda, 6 pinos de entradas analógicas (pinos A0 a A5), que são dedicados a receber valores analógicos, por exemplo, a tensão de um sensor de temperatura. O valor a ser lido deve estar na faixa de 0 a 5 V, para esse tipo de placa, na qual serão convertidos para valores entre 0 e 1023, já que o padrão de conversão é de 10 bits. Apresenta, também, 6 pinos de saídas analógicas (pinos 3, 5, 6, 9, 10 e 11), pinos digitais que podem ser programados para ser utilizados como saídas analógicas, utilizando modulação PWM. A alimentação da Placa pode ser feita a partir da porta USB do computador ou através de uma fonte DC externa. No software para programação do Arduino, quando pressionado o botão upload da IDE, o Código Escrito é traduzido para a Linguagem C e é transmitido para o compilador avr-gcc, que realiza a tradução dos comandos para uma Lingua- gem que pode ser compreendida pelo microcontrolador ATMEGA328 da Placa. 29 UNIDADE Programação em Linguagem Assembler e C++Arduino A IDE possui uma Linguagem própria baseada na linguagem C e C++. Um ciclo de programação do Arduino pode ser dividido da seguinte maneira: • Conexão da placa a uma porta USB do computador; • Desenvolvimento de um sketch com comandos para a placa; • Upload do sketch para a placa, utilizando a comunicação serial USB; • Aguardar a reinicialização; em seguida, ocorrerá à execução do sketch criado. A partir do momento que foi feito o upload do firmware, a Placa não necessita mais estar conectada ao computador; o Arduino executará o sketch criado, desde que seja ligado a uma fonte de energia externa ou bateria. A IDE pode ser baixada gratuitamente no site do Arduino, no qual pode ser escolhida a melhor opção de download conforme a Plataforma utilizada. Quando se abre o IDE do Arduino, será exibido algo semelhante à Figura a seguir: Figura 5 – Tela de um Sketch de Arduino Fonte: elaborada pelo próprio autor. O IDE é dividido em três partes: a Toolbar no topo, o Código ou a Sketch Window no centro, e a janela de mensagens na base, conforme exibido na Fi- gura anterior. Na Toolbar, há uma guia, ou um conjunto de guias, com o nome do sketch. Ao lado direito, há um botão que habilita o serial monitor. No topo, há uma barra de menus, com os itens File, Edit, Sketch, Tools e Help. Os botões na Toolbar fornecem acesso rápido às funções mais utilizadas dentro desses menus. 30 31 Após a conexão do Arduino ao computador, é atribuída à placa uma porta COM de comunicação. A primeira vez que o programa Arduino for executa- do, deve-se selecionar o modelo de Placa utilizado; nesse caso, deve-se escolher Arduino Uno, conforme a Figura 6 a seguir: Figura 6 – Tela de seleção de modelo de placa Arduino Fonte: elaborada pelo próprio autor. Após a definição do modelo, deve-se selecionar em qual porta serial a placa se comunicará com o computador. Após estas configurações, o ambiente está preparado para uso e se pode testar qualquer um dos exemplos que acompanham a IDE ou, até mesmo, um novo sketch. Uma das principais facilidades da plataforma Arduino são os exemplos pré- disponíveis que podem ser acessados por meio do Menu File >Examples. Esses exemplos trazem desde o mais simples programas C/C++ de um pica- pisca de led (Sketch denominado Blink), até exemplos mais complexos para transmissão de dados Wi-Fi e programação para display TFT, entre outros. 31 UNIDADE Programação em Linguagem Assembler e C++Arduino Programações mais complexas como, por exemplo, programação para controle PID de aquecimento, podem ser acessados após a instalação dabiblioteca específica no site do próprio fabricante. Outra facilidade é que, devido ao seu Código Aberto, praticamente, todas as placas similares desenvolvidas pela comunidade de Arduino são compatíveis e utilizam o mesmo compilador para programar seu microcontrolador. O exemplo mais simples para iniciar a programação do Arduino consiste em acionar um LED por meio de uma saída digital. A placa Arduino Uno já possui um Led ligado ao pino digital 13, que pode ser utilizado para o teste, e na IDE é possível carregar o exemplo Blink: Figura 7 – Tela de seleção de exemplos padrão do Arduino Fonte: elaborada pelo próprio autor. Exemplo 1: Pisca Led Padrão do Arduino (Blink) Este exemplo padrão denominado Blink é um Código exemplo de domínio público que já acompanha o compilador do Arduino. Ele serve para ligar um LED durante 1 segundo e o mantém desligado por mais 1 segundo, repetidamente; ou seja, é como um pisca pisca de frequência de ope- ração 1 Hz. Muitos Arduinos já têm na placa um LED padrão que pode ser controlado digitalmente. Nas placas UNO, MEGA e ZERO, o LED padrão está conectado à saída digital pino 13; na MKR1000, está conectado ao pino 6. 32 33 As novas versões dos compiladores, para evitar problemas com a diferença de pinagem, introduziram um comando padrão denominado LED_BUILTIN, que já configura a Placa para o pino correto do seu LED padrão, conforme a respectiva Placa utilizada. O exemplo a seguir já utiliza esse novo comando: */ // A função setup roda apenas quando é pressionado o botão reset ou a placa é ligada void setup() { // inicializa o pino digital LED_BUILTIN como saída digital. pinMode(LED_BUILTIN, OUTPUT); } void loop() { //A função Loop é executada a cada ciclo de varredura do microcontrolador digitalWrite(LED_BUILTIN, HIGH); // Ativa a saída LED em nível alto (+5V) delay(1000); // espera 1000 milissegundo (1s) digitalWrite(LED_BUILTIN, LOW); // Desliga Led colocando saída em GND delay(1000); // Espera 1 segundo } Para verificar se o código está correto, pode-se clicar no ícone verify (cujo símbolo é semelhante a um V de check). Em seguida à verificação da compilação, exibe-se uma mensagem de status da operação e, caso esteja tudo certo, será exibida a quantidade de bytes gerados pelo programa. Para gravar o código na memória flash do microcontrolador, é necessário clicar no ícone Upload; será transferido o Código para a Placa e após alguns segundos o LED ligado ao pino 13 começará a piscar em intervalos de 1 segundo. O código do exemplo Blink é relativamente simples; porém, apresenta a estru- tura básica de um programa desenvolvido na IDE Arduino. Inicialmente, nota-se que existem duas funções obrigatórias em um programa Arduino, setup() e loop(). A função setup () é executada na inicialização do Programa e é responsável pelas configurações iniciais do microcontrolador, tal como, definição dos pinos de I/O e inicialização da comunicação serial, entre outras. 33 UNIDADE Programação em Linguagem Assembler e C++Arduino A função loop () será aquela em que ocorrerá o laço infinito da programação, ou seja, em que será inserido o Código que será executado continuamente pelo microcontrolador, a cada ciclo de varredura. Dentro do loop principal, está o Código que fará o led ligado pino 13 piscar em intervalos de 1 segundo. A função digital Write (led, HIGH) coloca o pino em nível lógico 1, ligando o led. A função delay (1000) aguarda o tempo de 1000 ms, ou seja, 1 segundo para que possa ser executada a próxima instrução. A função digital Write (led, LOW) coloca o pino em nível lógico 0, desligando o led. E novamente é esperado 1 segundo com a função delay (); O loop é repetido infinitamente, enquanto a Placa estiver ligada. Testar outros exemplos básicos é um bom começo para aprender mais sobre a plataforma. Exemplo 2: Exemplo PWM com Arduino Pode-se implementar, manualmente, a geração de um sinal PWM em qualquer uma das saídas digitais do Arduino. Para isso, basta alternar os níveis alto e baixo intercalando os tempos desejados para a geração do PWM, conforme o exemplo a seguir: void setup() { pinMode(13, OUTPUT); // Utiliza a saída 13 da placa. Como na saída 13 já // existe um LED instalado, isto permite visualizar // o pulso PWM gerado; mas para outras aplicações // recomenda-se usar outro pino digital disponível. } void loop() { digitalWrite(13, HIGH); delayMicroseconds(100); // 10% duty cycle , freq 1KHz digitalWrite(13, LOW); delayMicroseconds(1000 - 100); } 34 35 Alguns microcontroladores Arduino, como o ATmega328P, já têm três timers, conhecidos como Timer 0, Timer 1 e Timer 2. Cada um deles têm saídas com comparadores que controlam a largura de pulso do PWM para as outras duas sa- ídas de timer: quando o temporizador atinge o valor do registro de comparação, a saída correspondente é alternada. As duas saídas para cada temporizador, nor- malmente, terão a mesma frequência, mas podem ter ciclos de trabalho diferentes (dependendo do respectivo registro de comparação de saída). Cada um dos temporizadores gera o relógio do temporizador, dividindo o relógio do Sistema por um fator de pré-escala como 1, 8, 64, 256 ou 1024. O Arduino possui um relógio do Sistema de 16MHz e a frequência do relógio do temporizador será a frequência do relógio do Sistema dividida pelo fator de pré- escala. Observe que o Timer 2 possui um conjunto diferente de valores de pré-escala dos outros temporizadores. Os principais modos PWM são “Fast PWM” e “PWM de fase corretiva”. O tem- porizador pode ser executado de 0 a 255 ou de 0 a um valor fixo. (O temporizador 1 de 16 bits possui modos adicionais para suportar valores de temporização de até 16 bits). Cada saída também pode ser invertida. Os temporizadores também podem gerar interrupções em excesso e/ou emparelhar contra qualquer registro de comparação de saída, mas isso está além do escopo deste Curso. Registros de temporizador são usados para controlar cada temporizador. Os Registros de Controle Temporizador/Contador TCCRnA e TCCRnB man- têm os bits de controle principais para o temporizador (Observe que TCCRnA e TCCRnB não correspondem às saídas A e B.) Esses registros possuem vários gru- pos de bits: • Bit de modo de geração de forma de onda (WGM): controla o modo geral do temporizador (esses bits são divididos entre TCCRnA e TCCRnB); • Seletor de Relógio (CS): controla a pré-escala do relógio; • Comparador da saída A (COMnA): ativa/desativa/inverte a saída A; • Comparador da saída B (COMnB): ativa/desativa/inverte a saída B. • Os comparadores OCRnA e OCRnB: define os níveis em que as saídas A e B serão afetadas. Quando o valor do temporizador corresponde ao valor do regis- tro, a saída correspondente será modificada conforme especificado pelo modo. Os bits são ligeiramente diferentes para cada temporizador; então, consulte a folha de dados para obter detalhes. 35 UNIDADE Programação em Linguagem Assembler e C++Arduino Timer 1 é um temporizador de 16 bits e tem modos adicionais. O temporizador 2 possui diferentes valores de preconceito. No modo PWM mais simples, o temporizador conta, repetidamente, de 0 a 255. A saída é ativada quando o temporizador está em 0 e se desliga quando o temporizador corresponde ao registro de comparação de saída. Quanto maior o valor no registro de comparação de saída, maior o ciclo de trabalho. Esse modo é conhecido como modo PWM rápido. Já no modo PWM Rápido, que exemplifica o seguinte fragmento de código, configura-se o PWM rápido nos pinos 3 e 11 (Temporizador 2). Para resumir as configurações de registro, definir os bits de modo de geração de Forma de Onda WGM para saída 11 seleciona PWM rápido. Definir os bits COM2A e os bits COM2B para 10 fornece PWM não invertido para as saídas A e B. Configurando os bits CS para 100 define o prescaler para dividir o relógio em 64 (vez que os bits são diferentes para os diferentes temporizadores, consulteo datasheet para os valores corretos.) Os registros de comparação de saída são arbitrariamente configurados para 180 e 50 para controlar o ciclo de trabalho PWM das saídas A e B, mas, podem-se modificar os registros diretamente, em vez de usar pinMode, mas, para isso, é preciso configurar os pinos para a saída. As linhas de código a seguir permitem a programação de uma PWM modo rápido, utilizando os timer e comparadores do Arduino: //Exemplo PWM rápido para Arduino pinMode(3, OUTPUT); pinMode(11, OUTPUT); TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM21) | _BV(WGM20); TCCR2B = _BV(CS22); OCR2A = 180; OCR2B = 50; Para outros exemplos de Programação C/C++ para Arduino ou PIC e até mesmo outros microcontroladores e microprocessadores, recomenda-se acessar os tutorias indicados em Material Complementar ou sites de Eletrônica, disponíveis na Internet. 36 37 Material Complementar Indicações para saber mais sobre os assuntos abordados nesta Unidade: Sites Arduino Acesse outros Materiais Complementares e Tutoriais para Arduino. https://www.arduino.cc Sparkfun Site de compras que contém esquemáticos de circuitos e exemplos de programas para microcontroladores. https://www.sparkfun.com/ Vídeos Gerando PWM com os Comparadores | Assembly para PIC #062 https://youtu.be/FCzLQ0y1CLc Leitura Secrets of Arduino PWM Acesse Material Complementar sobre PWM para Arduino. https://goo.gl/B0LCb4 37 UNIDADE Programação em Linguagem Assembler e C++Arduino Referências MCROBERTS, Michael. Arduino básico. São Paulo: Novatec, 2011. v.1. MIYADARIRA, N. A.; MICROCONTROLADORES, PIC18: Aprenda a Programar em Linguagem C. São Paulo: Érica, 2009. SOUSA, Daniel Rodrigues de; SOUZA, David José de; LAVINIA, Nicolás César. Desbravando o Microcontrolador PIC18 – Recursos Avançados. São Paulo: Érica, 2010. 38
Compartilhar