Memórias Flash:

O bloco de memória onde fica armazenado o código do programa é um tipo de memória somente de leitura. No passado esse tipo de memória era chamado de ROM (read only memory), e o único realmente “read only”, pois o código já era gravado durante o processo de fabricação e não podia ser alterado depois.

A memória chamada EPROM (erasable programmable read only memory) também é usada para gravar o código dos programas dos processadores e pode ser apagado e reprogramado com o auxilio de luz ultra-violeta. Para isso ela possui uma janela de vidro em seu corpo (figura abaixo).

eprom

Mas dentro de um microcontrolador temos um tipo de memória diferente para a gravação do código de programa. Chamamos esse tipo de memória de Flash. A memória flash não precisa de luz ultra-violeta para ser apagada e assim pode ser reprogramada várias vezes, o que facilita a criação e teste dos programas.

Quando criamos um programa, ele pode ser escrito em vários tipos de linguagem (C, assembler, etc). Mas para poder ser entendido pelo microcontrolador, esse programa tem que passar por um processo chamado de compilação. O compilador irá interpretar o programa que foi escrito na linguagem escolhida e irá criar uma lista de números que serão então gravados em sequência no bloco de memória flash dentro do microcontrolador.

Após o reset do microcontrolador o mesmo começa a ler os dados (números) gravados na memória flash e interpretá-los para realizar as instruções definidas no programa que escrevemos.

Memória RAM.

A diferença básica entre a memória flash e a memória RAM é que a memória RAM não armazena os valores gravados nela na falta de alimentação. Chamamos esse tipo de memória de não-retentiva. Por isso ela é usada somente para guardar dados que são usados durante a execução do programa.

Registradores.

Os registradores são parecidos com a memória RAM no sentido que podem ser ter seu valor alterado e lido durante a execução do programa e esse valor é apagado na falta de alimentação. Mas sua função é diferente. Ele não existe apenas para armazenas dados que são usados durante a execução do programa. Cada registrados tem uma função mais especifica que podemos enquadrar em 3 categorias:

  • Cálculo: usados na execução de cálculos e comparações, ficam diretamente conectados a unidade lógica e aritmética (ULA). Seus dados devem ser definidos antes da execução de instruções de cálculo e comparações.
  • Entradas e saídas: ficam conectados aos pinos de entradas e saídas digitais do microcontrolador. São usados para fazer a interface com o mundo externo. Veremos melhor isso na explicação sobre periféricos.
  • Configurações: são usados para definir como quase tudo dentro do microcontrolador irá funcionar. Por exemplo temos registradores específicos para definir quais pinos do microcontrolador serão entradas e quais serão saídas. Outro exemplo são os registradores que definem a frequência do clock principal e secundários do microprocessador.

Periféricos

Atualmente os microcontroladores podem conter inúmeros tipos de periféricos. Vamos detalhar por enquanto os principais que estão presentes na placa do Arduino e que iremos utilizar nas primeiras aulas práticas.

O primeiro periférico a ser explorado neste curso será a interface paralela do microcontrolador. A interface paralela é composta pelas portas de entradas e saídas digitais (IO). Dizemos que um sinal é digital quando o mesmo possui apenas dois estados, estado 0 e estado 1. Na verdade se formos medir a tensão com um voltímetro, veremos que o nível de tensão no sinal não é 0 nem 1. A tensão do sinal fica entre algum valor entre 0 volts e a tensão positiva de alimentação do circuito, que é normalmente 3,3 volts ou 5,0 volts dependendo da placa. O microcontrolador irá traduzir o nível de tensão presente em seus pinos de IO para um dos estados possíveis 0 e 1. Se a tensão estiver abaixo de um certo valor de tensão Va, o estado é 0, Se estiver acima de outro valor Vb, o estado é 1. Existe sempre uma faixa entre Va e Vb onde o estado do sinal é indefinido. Estes valores Va e Vb estão definidos no documento técnico (Datasheet) do microcontrolador e devem ser sempre observados quando utilizamos diferentes circuito integrados no mesmo circuito. Vamos sempre encontrar outros nomes e referências para estes dois estados do sinal digital. Por exemplo, ON e OFF, FALSE e TRUE, FALSO e VERDADEIRO.

As portas digitais possuem 8 bits ou pontos. Em alguns modelos de microcontroladores pode acontecer de nem todos os pontos de alguma porta estarem disponíveis por falta de pinos no chip, mas sempre teremos os mesmos tipos de controle para todos os pontos e todas as portas.

O funcionamento das portas é definido por 3 registradores de configuração. São eles:

PORTxn, DDxn, PINxn.

A letra x faz referência a qual porta estamos acessando, devendo ser substituída pela letra correspondente a porta A, B, C, D, E etc.

A letra n faz referencia ao bit da porta devendo ser substituída pelos números 0 a 7.

Por exemplo, os nomes de registradores PORTB5, DDB5 e PINB5, se referem ao bit 5 da porta B.

DDxn – este registrador define a direção do bit de entrada/saída. Quando escrevemos este bit com valor 0, o pino da porta se torna uma entrada. Quando escrevemos este bit com valor 1, o pino da porta se torna uma saída.

PORTxn – este registrador é usado para definir o estado do pino da porta quando o mesmo está definido como uma saída. Quando escrevemos o valor 0, o pino da porta assume o estado lógico 0 (0 v). Quando este bit com valor 1, o pino da porta assume o estado lógico 1 (Vcc).

PINxn – este registrador é usado quando o pino está definido como uma entrada. Neste caso o bit do registrador reflete o estado lógico que está aplicado ao pino da porta. Se o pino da porta está com nível lógico 0, lemos o valor 0 no bit do registrador. Se o pino da porta está com nível lógico 1, lemos o valor 1 no bit do registrador.

Logo no início do programa, definimos os valores dos registradores DDxn para estabelecer quais pinos irão se comportar como entradas e quais irão se comportar como saídas. Assim como definimos os valores dos registradores PORTxn para estabelecer o estado inicial dos pinos de saídas.

Durante a execução do programa iremos usar os pinos de entradas e saídas das portas paralelas para várias funções diferentes. As principais são o reconhecimento do acionamento de teclas ligadas aos pinos de entradas e o acionamento de leds e outros dispositivos de saída. Como descrito no diagrama abaixo:

fig3_1

Para ler o estado da tecla, acionada ou não-acionada, usamos os registradores PINxn para testar o nível lógico nos pinos de entrado do microcontrolador.

Para acender ou apagar o Led usamos os registradores PORTxn para definir o estado lógico nos pinos de saída do microcontrolador. Na figura acima podemos ver o esquema de ligação para um LED. Neste caso o LED está sendo aceso quando colocamos a saída com estado lógico zero porque o anodo do LED está ligado ao positivo da fonte. É possível fazer a ligação do LED com o catodo ligado ao negativo da fonte e acendendo quando colocamos a saída com estado lógico 1, já que a saída tem boa capacidade de corrente nos dois sentidos. Mas eu recomendo sempre que possível utilizar a lógica do desenho (com o anodo ligado ao positivo) já que na maioria dos casos a capacidade de corrente dos pinos de saída é maior no sentido de dreno.

 

Temporizadores/Contadores (timer)

Outro periférico muito utilizado nos microcontroladores são os temporizadores. Estes módulos são compostos por um contador que recebe o estímulo de um clock para incrementar ou decrementar o valor de sua contagem. Uma vez que o sinal de clock é um sinal com frequência fixa e conhecida, o resultado deste contador é uma contagem de tempo muito precisa. Sua precisão depende exclusivamente da precisão do sinal de clock.

Podemos utilizar o temporizador, por exemplo para definir a taxa de pisca-pisca de um led ligado a uma saída. Para isso programamos o valor inicial do temporizador com um valor apropriado. Em seguida preparamos o programa para que ao atingir o valor zero o estado da saída que atua o led sofra uma inversão de estado (se estiver com 0 vai para 1 e se estiver com 1 vai para 0), e ao mesmo tempo recarregamos o valor inicial do temporizador, para que ele demore exatamente o mesmo tempo para atingir o valor zero e recomeçar o ciclo.

O temporizador possui varias funções que auxiliam no controle e utilização do mesmo. Um dos modos de funcionamento do temporizador já faz automaticamente o carregamento do valor inicial ao final da contagem. Neste mesmo modo podemos programar o funcionamento de uma interrupção para avisar o programa que o tempo foi atingido.

As interrupções são muito úteis e estão presentes em quase todos os periféricos do microcontrolador, como veremos nos módulos a frente.

Os temporizadores também podem ser configurados para trabalhar como contadores de eventos. Para isso, mudamos a fonte do sinal de contagem do temporizador. Ao invés de usar o sinal de clock, usamos um outro sinal aplicado a um pino de entrada. Desta forma o temporizador funciona como um contador de eventos. Pode ser uma tecla sendo pressionada, ou um sensor que detecta a passagem de algum objeto ou qualquer outro tipo de componente que possa gerar um sinal digital que registre a ocorrência de um evento externo ao microcontrolador. O contador irá informar a quantidade de vezes que o sinal da entrada mudou de estado.

No microcontrolador ATMega328, presente na placa do Arduino, temos 3 temporizadores. O timer 0, timer 1 e timer 2. Os temporizadores timer0 e timer2 tem 8 bits com seu contador. O timer1 tem 16 bits.

 

Interface de comunicação serial assíncrona (USART)

Este periférico é muito comum e está presenta em quase todos os modelos de microcontroladores. É o mesmo tipo de circuito, presente na maioria dos computadores, conhecido por porta serial COM. Através deste circuito é possível a troca de mensagens entre duas CPUs interligadas através de suas respectivas interfaces seriais.

A interligação física entre duas interfaces é feita por poucos fios e tem capacidade de trocar informações a uma taxa bem grande. Com apenas 3 fios já podemos realizar uma troca de informações entre 2 CPUs com a interface serial. Estes fios são o de transmissão (TX), o de recepção (RX) e o fio que coloca os dois circuitos no mesmo potencial elétrico, normalmente o fio de 0 v.

A ideia básica que torna possível esta troca de dados é a seguinte:

-os bits da informação da CPU1 são colocados no sinal de saída TX um após o outro a um intervalo de tempo fixo (taxa de comunicação);

-o sinal TX da CPU1 é ligado ao sinal de entrada RX da CPU2;

-a CPU2 conhece a priori a taxa de comunicação utilizada pela CPU1;

-desta forma a CPU2 consegue remontar os dados enviados pela CPU1 e recria a informação.

Os sinais da interface serial nos pinos do microcontrolador tem os níveis de tensão já descritos anteriormente mas para poder fazer a comunicação entre 2 circuitos diferentes é necessário que estes sinais sejam convertidos para níveis de tensão mais apropriados para suportar a distância física entre os circuitos. No padrão de comunicação RS232 estes níveis de tensão são  -15V para sinal lógico 0 e +15V para sinal lógico 1. Existem circuitos integrados especializados que fazem esta conversão de forma simples e eficiente. Um deles é o MAX232.

A figura abaixo mostra como a codificação do dado é feita no padrão RS232:

serial1

Com um pouco de esforço é possível fazer uma comunicação entre o Arduino e a porta serial do seu computador. Fazendo isso é possível utilizar um programa de hiperterminal que mostra na tela do computador os dados recebidos pela posta serial do computador, e envia os dados correspondentes as teclas que forem apertadas no teclado do computador. Desta forma temos uma interface de comunicação com a placa do Arduino que nos permite visualizar os dados que estamos processando no programa do microcontrolador e também enviar dados para ele processar.

Tivemos um volume enorme de informações nesta lição. Para o aluno iniciante pode parecer difícil entender a maioria das informações aqui, mas não se preocupe porque você não precisa entender tudo para prosseguir com o curso. As aulas práticas de utilização do Arduino tem o passo a passo para qualquer um conseguir rodar os programas propostos. Eu recomendo sempre que os alunos coloquem em prática os exemplos e depois voltem as aulas teóricas. Desta forma a compreensão fica mais fácil.