299

Microcontroladores RL78: Guia Básico - renesas.com · Microcontroladores RL78: Guia Básico 3 Agradecimentos Este é o meu nono livro e ele não teria sido possível sem a colaboração

Embed Size (px)

Citation preview

Microcontroladores RL78: Guia Básico 1

Fábio Pereira

Microcontroladores RL78

Guia Básico

1ª Edição

Versão 1.0

Joinville - SC

Edição do Autor

2013

Microcontroladores RL78: Guia Básico 2

Copyright © 2013 Fábio Pereira

Todos os direitos reservados.

É proibida a redistribuição, de forma parcial, do conteúdo deste livro ou arquivo eletrônico. A utilização parcial do material desta obra é condicionada a sua citação como fonte do conteúdo.

Todas as marcas registradas, nomes ou direitos de uso citados neste livro pertencem aos seus respectivos proprietários.

O autor acredita que todas as informações apresentadas nesta obra estão corretas e podem ser utilizadas para qualquer fim legal. Entretanto, não existe qualquer garantia implícita ou explícita, de que o uso de tais informações conduzirá sempre ao resultado esperado.

Acesse: www.perse.com.br para adquirir cópias impressas adicionais.

Material para download disponível em:

www.sctec.com.br/blog

ISBN: 978-85-8196-334-1

Microcontroladores RL78: Guia Básico 3

Agradecimentos

Este é o meu nono livro e ele não teria sido possível sem a colaboração de algumas pessoas, por isso, os meus agradecimentos a:

- André Machado de Oliveira, da Renesas do Brasil, pela amizade e incentivo (há anos) na utilização dos microcontroladores Renesas, além do suporte, ajuda na revisão do texto, sugestões, kits e apoio incondicional ao livro.

- Huéliquis Fernandes, da Renesas do Brasil, pela amizade e grande apoio dado à viabilização deste livro e também por acreditar no meu trabalho.

- Felipe Torrezan e Leonardo Carlos Afonso, da Renesas do Brasil, pelo apoio técnico, ajuda na revisão e suporte ao livro.

- William Severino, da Renesas Electronics America, pelas sugestões iniciais e apoio dado ao livro.

- Ritesh Tyagi, diretor da área de marketing de microcontroladores pelo apoio da Renesas Electronics America a edição deste livro.

- José Carlos Nunes, da VLA, representante da Renesas no Brasil, pelo apoio dado ao livro, sugestões e amostras.

Dedicatória

Escrever um livro implica em centenas de horas de dedicação. Por isso, quero dedicar este livro a minha esposa Débora e agradecer pelo carinho, compreensão, apoio e por estar ao meu lado!

Amo você!

Microcontroladores RL78: Guia Básico 4

Sobre o Autor

Fábio Pereira é técnico em Eletrônica (CEFET-PR), bacharel em Direito (ACE-SC), especialista em projeto de equipamentos eletrônicos (CEFET-SC) e autor de outros oito livros na área de programação de microcontroladores (sete deles em português e um em inglês).

Também atuou como professor de disciplinas relacionadas a microcontroladores e programação em C em cursos técnicos e universidades na região de Joinville e atualmente trabalha como advogado e nas horas vagas mantém o seu blog FPB (www.sctec.com.br/blog) além de desenvolver projetos de sistemas embarcados.

Ao longo dos últimos 20 anos, desenvolveu diversas aplicações utilizando diferentes plataformas tais como 8051, ARM, AVR, Cortex, Coldfire, HC908, HCS08, MSP430, PIC, RL78, Z8-Encore, Z-80 em diferentes linguagens como Assembly, BASIC, C e Pascal.

Outros livros do autor:

Microcontroladores PIC: Técnicas Avançadas;

Microcontroladores PIC: Programação em C;

Microcontroladores HC908Q: Teoria e Prática;

Microcontroladores MSP430: Teoria e Prática;

Microcontroladores HCS08: Teoria e Prática;

Tecnologia ARM: Microcontroladores de 32 bits;

HCS08 Unleashed: Designer’s guide to the HCS08 Microcontrollers;

Microcontrolador PIC18 Detalhado : Hardware e Software.

Para entrar em contato com o autor, acesse o blog: www.sctec.com.br/blog

Microcontroladores RL78: Guia Básico 5

Sobre a Renesas

Renesas é uma empresa japonesa na área de eletrônica e foi fundada em 2003 como uma joint venture entre a Hitachi e a Mitsubishi Electric, ambas gigantes japonesas com grande atuação na área da eletrônica. Em 2010 a NEC Electronics Corporation juntou-se à Renesas e trouxe com ela a sua linha de microcontroladores e microprocessadores (expandindo ainda mais a já ampla linha de MCUs e MPUs da Renesas).

A linha de produtos fabricados pela Renesas é digna do peso dos três principais sócios da empresa: vai de microcontroladores 8 bits de baixo custo (como os 78K0 desenvolvidos pela NEC e H8 desenvolvidos pela Hitachi), passando pelos microcontroladores de 16 bits (H8, R8C e M16C desenvolvidos pela Hitachi, 78K0R desenvolvidos pela NEC e RL78 da Renesas), microcontroladores de 32 bits (como o R32C, RX e RH850 da Renesas, V850 desenvolvido pela NEC e os SuperH desenvolvidos pela Hitachi), até microprocessadores SoC de alta performance para os mercados móveis e automotivos (utilizando múltiplos núcleos ARM, Cortex e SuperH). Além dos MCUs e MPUs a Renesas fabrica diversos outros semicondutores como integrados LSI, ASSP, Displays, IGBTs, MOSFETs, etc.

A Renesas foi o quinto maior fabricante de semicondutores nos anos de 2010 e 2011 e o primeiro em venda de microcontroladores no mesmo período. A participação da Renesas no mercado mundial de microcontroladores é de aproximadamente 28%, com vendas anuais de mais de 4 bilhões de dólares.

A empresa possui diversos escritórios ao redor do mundo. No Brasil, a presença da empresa vem crescendo, com um escritório em São Paulo e investimentos em divulgação e ampliação da margem local de mercado.

Microcontroladores RL78: Guia Básico 6

Microcontroladores RL78 Guia Básico 7

Índice

1. Introdução ...............................................................................................................................13 1.1. Uma Breve História da Computação ..........................................................................13 1.2. Sistemas Embarcados .................................................................................................17 1.3. Conceitos Básicos.......................................................................................................18 1.4. Microcontroladores RL78...........................................................................................30 1.5. Pinagens e Encapsulamentos ......................................................................................32 1.6. R5F100LEA ...............................................................................................................35 1.7. Kits e Ferramentas de Programação ...........................................................................36 1.8. Convenções Utilizadas ...............................................................................................38

2. Ferramentas de Programação ...............................................................................................41 2.1. O Ambiente Embedded Workbench EWRL78...........................................................41

2.1.1. Criando o Primeiro Projeto .............................................................................41 2.1.2. Simulando um Programa.................................................................................46 2.1.3. Depurando um Programa ................................................................................51 2.1.4. Gerando o Código Final ..................................................................................52

3. Arquitetura e Modelo de Programação ................................................................................55 3.1. A CPU RL78 ..............................................................................................................55

3.1.1. Registradores Especiais da CPU .....................................................................56 3.1.1.1. Registrador PSW....................................................................................................57 3.1.1.2. Registrador PC.......................................................................................................58 3.1.1.3. Registrador SP .......................................................................................................58 3.1.1.4. Registradores ES e CS ...........................................................................................60 3.1.1.5. Registrador PMC ...................................................................................................60

3.1.2. Mapa de Memória ...........................................................................................61 3.1.3. Modos de Endereçamento ...............................................................................63

3.2. Conjunto de Instruções Assembly ..............................................................................65 3.2.1. Instruções de Manipulação de Dados..............................................................65 3.2.2. Instruções Aritméticas, Lógicas e de Comparação..........................................66 3.2.3. Instruções de Incremento e Decremento .........................................................68 3.2.4. Instruções de Rotação e Deslocamento de Bits ...............................................68 3.2.5. Instruções de Manipulação e Processamento de Bits ......................................71 3.2.6. Instruções de Desvio .......................................................................................71

Microcontroladores RL78: Guia Básico 8

3.2.7. Instruções para Sub-rotinas e Funções ............................................................ 72 3.2.8. Instruções de Pulo Condicional....................................................................... 73 3.2.9. Instruções de Controle da CPU....................................................................... 73 3.2.10. Temporização das Instruções ........................................................................ 74

3.3. Módulo OCD e Código de Segurança (Security ID) .................................................. 74 3.4. Configurações do Chip ............................................................................................... 76

4. Suporte à CPU ........................................................................................................................ 81 4.1. Reset ........................................................................................................................... 81 4.2. Sistema de Clock ........................................................................................................ 83

4.2.1. Oscilador X1 ................................................................................................... 84 4.2.2. Oscilador XT1................................................................................................. 85 4.2.3. Oscilador Interno de Alta Frequência ............................................................. 86 4.2.4. Oscilador Interno de Baixa Frequência........................................................... 87 4.2.5. Registradores do Sistema de Clock................................................................. 87 4.2.6. Exemplo .......................................................................................................... 91

4.3. Gerenciamento de Energia ......................................................................................... 92 4.3.1. Modo Halt ....................................................................................................... 93 4.3.2. Modo Stop....................................................................................................... 93 4.3.3. Modo Snooze .................................................................................................. 94 4.3.4. Gerenciamento de Clock................................................................................. 95 4.3.5. Dicas para Reduzir o Consumo de Energia..................................................... 96 4.3.6. Exemplo .......................................................................................................... 96

4.4. Clock/Buzzer Output .................................................................................................. 98 4.4.1. Exemplo .......................................................................................................... 99

4.5. Detector de Baixa Tensão......................................................................................... 100 4.5.1. Modo Reset ................................................................................................... 100 4.5.2. Modo Interrupção.......................................................................................... 101 4.5.3. Modo Interrupção e Reset ............................................................................. 101 4.5.4. Registradores do LVD .................................................................................. 102

4.6. Watchdog (WDT)..................................................................................................... 104 4.6.1. Exemplo ........................................................................................................ 106

4.7. Regulador Interno de Tensão.................................................................................... 108

5. Portas de Entrada e Saída.................................................................................................... 109

Microcontroladores RL78 Guia Básico 9

5.1. Registradores das Portas de E/S ...............................................................................110 5.2. Redirecionamento de Funções..................................................................................116 5.3. Exemplo....................................................................................................................117

6. Sistema de Interrupções .......................................................................................................120 6.1. Categorias de Interrupções .......................................................................................122 6.2. Sistema de Interrupções do RL78.............................................................................122

6.2.1. Sistema de Prioridades de Interrupção ..........................................................126 6.2.2. Latência de Interrupção.................................................................................128 6.2.3. Utilizando os Bancos de Registradores dos RL78.........................................129

6.3. Interrupções Externas ...............................................................................................130 6.3.1. Exemplo ........................................................................................................132

6.4. Interrupção de Teclado .............................................................................................133 6.4.1. Exemplo ........................................................................................................133

7. Periféricos de Temporização................................................................................................135 7.1. Timer de Intervalo (IT).............................................................................................136

7.1.1. Exemplo ........................................................................................................137 7.2. RTC ..........................................................................................................................138

7.2.1. Configuração do RTC ...................................................................................140 7.2.2. Registradores do RTC ...................................................................................141 7.2.3. Ajuste do RTC...............................................................................................145 7.2.4. Exemplo ........................................................................................................146

7.3. TAU..........................................................................................................................148 7.3.1. Visão Geral de uma Unidade TAU ...............................................................149 7.3.2. Operação em Modo Timer/Gerador de Onda Quadrada ...............................151 7.3.3. Operação no Modo Gerador de Atraso/Disparo Único .................................154 7.3.4. Operação em Modo Contador de Eventos.....................................................156 7.3.5. Operação como Divisor de Frequência .........................................................157 7.3.6. Operação no Modo de Captura de Período....................................................158 7.3.7. Operação no Modo de Captura de Ciclo .......................................................159 7.3.8. Operação no Modo de Pulso Configurável ...................................................160 7.3.9. Operação em Modo PWM.............................................................................164 7.3.10. Registradores das TAU ...............................................................................167

7.4. Outros Timers ...........................................................................................................175

Microcontroladores RL78: Guia Básico 10

8. Periféricos de Analógicos ..................................................................................................... 177 8.1. Detalhes Gerais do Conversor A/D .......................................................................... 177 8.2. Modos de Operação.................................................................................................. 183

8.2.1. Conversão Simples ou Múltipla .................................................................... 183 8.2.2. Conversão de Um Canal ou Varredura de Canais......................................... 184 8.2.3. Formas de Disparo do Conversor.................................................................. 184

8.2.3.1. Disparo por Software........................................................................................... 185 8.2.3.2. Disparo por Hardware ......................................................................................... 185

8.3. Referência Interna de Tensão ................................................................................... 186 8.4. Sensor de Temperatura ............................................................................................. 186 8.5. Operação em Modo Snooze...................................................................................... 187 8.6. Registradores do ADC.............................................................................................. 188 8.7. Exemplo ................................................................................................................... 191 8.8. Outros Periféricos Disponíveis................................................................................. 192

8.8.1. Comparador Analógico ................................................................................. 192 8.8.2. Conversor A/D de 12 bits.............................................................................. 192 8.8.3. Conversor D/A.............................................................................................. 192

9. Periféricos de Comunicação................................................................................................. 193 9.1. Unidades SAU.......................................................................................................... 193

9.1.1. Registradores das SAU ................................................................................. 196 9.1.2. Modo UART ................................................................................................. 203

9.1.2.1. Configuração do Baud Rate................................................................................. 205 9.1.2.2. Operação em Modo Snooze................................................................................. 208 9.1.2.3. LIN ...................................................................................................................... 208 9.1.2.4. API Applilet ........................................................................................................ 208 9.1.2.5. Exemplo .............................................................................................................. 209

9.1.3. Modo CSI...................................................................................................... 211 9.1.3.1. Configuração do Baud Rate................................................................................. 214 9.1.3.2. API Applilet ........................................................................................................ 215

9.1.4. Modo I2C....................................................................................................... 216 9.1.4.1. I2C Simplificado na SAU .................................................................................... 218 9.1.4.2. Configuração do Baud Rate................................................................................. 221 9.1.4.3. Comunicação I2C................................................................................................. 221 9.1.4.4. API Applilet ........................................................................................................ 223

9.2. Unidades IICA (I2C)................................................................................................. 224 9.2.1. Operação da IICA ......................................................................................... 225 9.2.2. API Applilet .................................................................................................. 226 9.2.3. Registradores IICA ....................................................................................... 228

Microcontroladores RL78 Guia Básico 11

10. Tópicos Avançados .............................................................................................................233 10.1. Ajuste BCD ............................................................................................................233 10.2. Funções de Segurança ............................................................................................234

10.2.1. Checagem de CRC da Flash........................................................................235 10.2.2. Checagem de Paridade da RAM .................................................................236 10.2.3. Bloqueio de Registradores e da RAM.........................................................237 10.2.4. Execução de Opcode Ilegal (Trap)..............................................................238 10.2.5. Acesso Ilegal à Memória (IAW) .................................................................238 10.2.6. Verificação do A/D .....................................................................................238 10.2.7. Verificação do Clock...................................................................................238

10.3. CRC de Uso Geral ..................................................................................................239 10.4. Gravação e Apagamento da Flash e DataFlash.......................................................240

10.4.1. FSL..............................................................................................................240 10.4.1.1. Utilização da FSL ..............................................................................................245

10.5. Hardware de Multiplicação e Divisão ....................................................................251 10.6. DMA.......................................................................................................................253

10.6.1. Registradores dos Canais de DMA .............................................................256 10.6.2. Exemplo ......................................................................................................259

10.7. Otimizando Aplicações para o RL78......................................................................261 10.7.1. Tamanho do Dado .......................................................................................261 10.7.2. Endereçamento Rápido ...............................................................................262 10.7.3. Campos de Bit .............................................................................................262 10.7.4. Funções CALLT..........................................................................................263

10.8. Utilizando o Applilet3 ............................................................................................264 10.8.1. Configuração do Timer de Intervalo ...........................................................266 10.8.2. Configuração da UART ..............................................................................269

11. Exemplos de Aplicação .......................................................................................................271 11.1. Utilização de Módulos LCD Alfanuméricos ..........................................................271 11.2. Mostrador Analógico no LCD ................................................................................278 11.3. Termômetro Digital ................................................................................................281 11.4. Medidor de Distância por Ultrassom......................................................................284

12. Tabela ASCII ......................................................................................................................289

Microcontroladores RL78: Guia Básico 12

Introdução 13

1

Introdução 1. Introdução

O objetivo deste livro é apresentar a família RL78 de microcontroladores da Renesas, com ênfase nos modelos RL78/G13. Antes de nos dedicarmos ao estudo deles é importante conhecer um pouco da história da computação digital, além de revisar conceitos cruciais na área da eletrônica digital e lógica de programação.

1.1. Uma Breve História da Computação

As primeiras máquinas de computação de que se tem notícia datam de 1623 (a máquina de cálculos de Wilhelm Schickard) e 1642 (a máquina Pascaline de Blaise Pascal). Ambas eram totalmente mecânicas e utilizavam intrincados mecanismos para realizar operações de adição.

Em 1671, o matemático e filósofo alemão Gottfried Von Leibniz desenhou a Staffelwalze (também conhecida como “Stepped Reckoner” ou calculadora de passos), a primeira calculadora mecânica capaz de realizar as quatro operações básicas da matemática (adição, subtração, multiplicação e divisão).

Figura 1.1 – Pascaline

Fonte: http://fr.wikipedia.org/wiki/Fichier:Arts_et_Metiers_Pascaline _dsc03869.jpg

Figura 1.2 – Stepped Reckoner

Fonte:http://en.wikipedia.org/wiki/File:Leibniz_Stepped_Reckoner.png

Todas essas máquinas eram apenas calculadoras mecânicas e não podiam ser programadas para executar operações predefinidas.

As primeiras máquinas programáveis surgiram no início do século XIX e eram muito diferentes do conceito atual de um computador. O tear Jacquard (criado por Joseph Marie Jacquard em 1801) é provavelmente a primeira máquina passível de ser programada pelo usuário. Utilizando cartões de papel perfurados, era possível programar complexos padrões a serem tecidos, aumentando drasticamente a flexibilidade dos teares, que até então somente podiam tecer um mesmo padrão. Isso permitiu que um mesmo tear fosse utilizado para produzir diferentes padrões de tecidos.

Microcontroladores RL78: Guia Básico 14

Alguns anos depois (1837), Charles Babbage desenhou a sua “Analytical Engine” (máquina analítica) que seria provavelmente o primeiro computador totalmente programável se ela tivesse sido realmente construída.

Figura 1.3 - Tear Jacquard.

Fonte: http://commons.wikimedia.org/wiki/Image:Jacquard.loom. full.view.jpg

Figura 1.4 – Cartões perfurados para programação

do tear Jacquard. Fonte: http://en.wikipedia.org/ wiki/File:Jacquard.loom.cards.jpg

O grande progresso da computação ocorreu com o advento das “Tabulating Machines” (máquinas de tabular) de Herman Hollerith (manufaturadas pela “Computing Tabulating Recording Corporation”, que algum tempo depois originou a IBM).

As máquinas de tabular de Hollerith também utilizavam cartões de papel perfurados e permitiram que o censo Norte-Americano de 1890 fosse completado em apenas dezoito meses (o censo anterior, de 1880, foi completado em sete anos!). Essas máquinas não eram programáveis, mas foram um passo importante na direção dos computadores programáveis.

Em 1941, no Iowa State College, o pesquisador John Vincent Atanasoff projetou e construiu o Atanasoff-Berry Computer (ABC), primeiro computador eletrônico norte-americano. Ele foi projetado especificamente para auxiliar na resolução de equações lineares e, apesar de não ser programável nem ser máquina Turing completa, o ABC apresentou alguns conceitos importantes:

• Sistema organizado com unidades separadas de computação e de memória (como nos computadores atuais).

• Memória capacitiva regenerativa com aproximadamente 3.200 capacitores organizados em dois tambores, cada um com 32 bandas de 50 capacitores (duas bandas não eram utilizadas e ficavam como reserva), resultando numa capacidade total de armazenamento de 60 números de 50 bits. Esse sistema de regeneração foi o precursor dos sistemas de refresh das memórias DRAM atuais e funcionava rotacionando os tambores num eixo com pinças para acesso aos dados.

Introdução 15

• Unidade lógica e aritmética (ULA) totalmente eletrônica construída com uso de cerca de 280 válvulas a vácuo.

• O sistema de I/O era composto de um sistema primário e um sistema secundário para resultados intermediários (utilizado quando os problemas sendo resolvidos excediam a capacidade de armazenamento da memória eletrônica interna).

O primeiro computador digital (e binário) totalmente programável foi o Z3, projetado e construído pelo engenheiro alemão Konrad Zuse em 1941.

Esse computador utilizava cerca de 2.000 relés no papel de chaves, portanto era eletromecânico. O programa era armazenado externamente numa fita perfurada, permitindo que diferentes programas fossem executados com relativa facilidade.

O Z3 possuía em seu conjunto de instruções praticamente todas as funcionalidades encontradas nos computadores modernos, com exceção das instruções de

Figura 1.5 - Zuse Z3. Fonte:http://www.computerhistory.org/timeline/images/1941_zuse_z3_

large.jpg

desvio (que foram implementadas posteriormente no microcódigo para cálculos em ponto flutuante).

Em 1943, os pesquisadores do Post Office Research Station em Dollis Hill (Inglaterra) apresentaram o protótipo de um dos primeiros computadores eletrônicos: o Colossus Mark 1. Esse computador (na verdade a sua segunda geração, Colossus Mark 2) foi utilizado para auxiliar na decodificação das mensagens alemãs criptografadas durante a Segunda Guerra Mundial.

Outro famoso computador dessa era foi o ENIAC (Electronic Numerical Integrator And Computer), um computador eletrônico projetado e construído pelo Laboratório de Pesquisa Balística do Exército Norte-Americano, em 1946, para auxiliar no cálculo de tabelas de artilharia e outros problemas matemáticos complexos (como os relacionados ao projeto das primeiras bombas atômicas).

O ENIAC era um computador enorme, composto por milhares de válvulas eletrônicas, diodos de cristal e relés. Possuía registradores decimais de dez dígitos e operava com clock de 100kHz, consumindo cerca de 174kW em operação. Uma de suas grandes fraquezas era o sistema de armazenamento do programa, que era realizado pela interligação de fios no interior do computador. Sendo assim, qualquer alteração implicava esforço considerável.

Em 1948, alguns melhoramentos foram adicionados ao ENIAC; o mais importante foi um

Figura 1.6 - ENIAC. Fonte: http://en.wikipedia.org/wiki/Image:Classic_shot_of_the_ENIAC.jpg

Microcontroladores RL78: Guia Básico 16

dispositivo de leitura de programa utilizando tabelas de funções (proposto pelo matemático John von Neumann). Esse mecanismo funcionava como uma ROM (Read-Only Memory ou memória somente de leitura) de programa primitiva.

Outro computador famoso e importante foi o ASCC (Automatic Sequence Controlled Calculator - calculadora automática de sequência controlada) da IBM (também conhecido como IBM Mark I), projetado por Howard H. Aiken da Universidade de Harvard e construído pela IBM em 1944. Ele foi o primeiro computador totalmente automático e que funcionava de forma muito semelhante aos computadores modernos.

O ASCC era um computador eletromecânico e possuía memórias separadas para o armazenamento das instruções do programa e os dados. Essa arquitetura ficaria conhecida como “arquitetura Harvard”.

Já o IBM SSEC (Selective Sequence Electronic Calculator - calculadora eletrônica de sequência seletiva), construído em 1948, implementava outra abordagem para a sua arquitetura interna: um espaço de memória unificado onde são armazenadas tanto as instruções quanto os dados. Essa arquitetura ficou conhecida como “Von Neumann” ou Princeton, em homenagem ao matemático John von Neumann da Universidade de Princeton (EUA), ainda que John Presper Eckert (um dos homens por trás do projeto do ENIAC) tenha proposto a mesma arquitetura anos antes de Von Neumann.

Essas duas arquiteturas de computadores (Von Neumann e Harvard) ainda estão em uso mesmo nos mais modernos computadores da atualidade. A Figura 1.7 mostra os diagramas simplificados dessas duas arquiteturas.

A arquitetura Von Neumann (também chamada Princeton) caracteriza-se por utilizar três barramentos de comunicação que são compartilhados pela memória e E/S, um para o endereçamento (seleção da posição a ser lida ou escrita), um para o controle (seleção do tipo de operação a ser realizada) e outro para dados (que carrega a informação propriamente dita).

A arquitetura Harvard, por sua vez, utiliza conjuntos de barramentos separados para as memórias e E/S, diferenciando ainda entre memória de programa (onde ficam armazenados as instruções do programa) e de dados (onde ficam os dados utilizados pelo programa).

Arquitetura Von Neumann (Princeton) Arquitetura Harvard

Figura 1.7

Cada arquitetura apresenta prós e contras: Von Neumann oferece mais flexibilidade, pois não faz distinção entre instruções e dados. Por outro lado, ela impõe uma única largura para o barramento de dados, implicando que uma CPU de 8 bits busque instruções de 8 ou múltiplos de

Controle

Endereço

Dados

CPU

Memória Programa/

Dados

Periféricos

Controle (periféricos)

Endereço (periféricos)

Endereço (programa)

Endereço (dados)

Controle (programa)

Dados (programa) Memória de Programa

Controle (dados)

Dados (dados)

Dados (periféricos)

CPU Memória de

Dados

Periféricos

Introdução 17

8 bits. Outro ponto fraco da arquitetura Von Neumann é um problema conhecido como “gargalo de Von Neumann”, causado pela capacidade limitada de transferência de dados da memória, quando comparada à necessidade da CPU de acessar a memória para leitura de instruções e a leitura/escrita de dados.

Apesar de todos os problemas impostos por essa arquitetura, ela ainda é vastamente utilizada pela maioria dos computadores atuais e dos microprocessadores e microcontroladores no mercado.

Na arquitetura Harvard, a velocidade é o benefício mais relevante do arranjo de múltiplos barramentos: enquanto executa uma instrução, a CPU pode ler e escrever dados na memória de dados e simultaneamente buscar a próxima instrução na memória de programa. Neste caso, os prós e contras se misturam devido à distinção entre a memória de programa e de dados: normalmente não é possível ter dados na memória de programa ou instruções na memória de dados. Algumas máquinas Harvard incluem instruções especiais que permitem o acesso à memória de programa para leitura/escrita de dados. Outras implementam áreas especiais de memória compartilhadas por instruções e dados.

Além das arquiteturas de projeto citadas, existem também dois diferentes conceitos básicos de projeto do conjunto de instruções de um processador: o conceito CISC e o conceito RISC.

O conceito CISC (computador com conjunto complexo de instruções) defende que a máquina possua uma grande quantidade de instruções (normalmente acima de 100), capazes de desempenhar as mais diferentes tarefas. Máquinas CISC normalmente possuem instruções complexas que realizam uma série de operações.

Já o conceito RISC (computador com conjunto reduzido de instruções) defende que a máquina possua um conjunto pequeno de instruções, mas que devem ser executadas rapidamente. Máquinas RISC normalmente possuem instruções simples e rápidas e necessitam de múltiplas instruções para realizar operações mais complexas.

Normalmente encontramos máquinas RISC associadas à arquitetura Harvard, ao passo que as máquinas CISC normalmente utilizam a arquitetura Von Neumann.

1.2. Sistemas Embarcados

A aplicação de computadores em dispositivos móveis ou capazes de ser movidos resultou em uma geração totalmente diferente de computadores e originou o termo “embedded system” ou sistema embarcado.

Um dos primeiros sistemas embarcados de que se tem notícia foi o Apollo Guidance Computer, ou AGC. Ele foi um computador (na verdade um microcomputador) de 16 bits (15 de dados mais um de paridade), que operava a 1,024MHz e que possuía 2.048 words de memória RAM e 36.864 words de memória de programa. Este microcomputador foi um dos primeiros computadores digitais a utilizar circuitos integrados e foi utilizado para o controle das espaçonaves Apollo (que em diversas missões nas décadas de 60 e 70, levaram o homem à Lua).

Ele também possuía uma IHM (Interface Homem Máquina) composta de um teclado numérico e displays eletroluminescentes, através da qual os astronautas podiam operá-lo, inserir

Microcontroladores RL78: Guia Básico 18

e visualizar dados, executar comandos e programas e até mesmo reprogramá-lo (como aconteceu na missão Apollo 14).

A – Módulos AGC e DSKY

Fonte: http://en.wikipedia.org/wiki/File:Agc_view.jpg

B – Módulo DSKY.

Fonte:http://www.computerhistory.org/timeline/images/ 1968_apollo.jpg

Figura 1.8

O AGC utilizava a primeira geração de circuitos integrados (portas NOR duplas com 3 entradas cada e implementadas utilizando tecnologia RTL – Resistor Transistor Logic), mas foi o advento do microprocessador (o 4004 desenvolvido pela Intel em 1971) e posteriormente do microcontrolador (o TMS1000 desenvolvido pela Texas Instruments em 1971 e lançado em 1974) que permitiu que os sistemas embarcados pudessem ser barateados e terem reduzidos drasticamente o seu tamanho físico e o consumo de energia (todos fatores importantes quando se fala em sistemas embarcados).

Atualmente os microcontroladores e o termo “sistema embarcado” possuem uma aplicação muito ampla, sendo utilizados em equipamentos simples (como torradeiras, cafeteiras, etc.) até complexos (como equipamentos médicos, smartphones, GPS, etc.).

1.3. Conceitos Básicos

Eletrônica é a ciência que estuda e aplica a eletricidade (o movimento de cargas elétricas) aos componentes (resistores, capacitores, indutores, semicondutores etc.) para construir circuitos complexos que podem interagir com o ambiente ou com os seres humanos.

De cafeteiras a TVs LCD, de lâmpadas elétricas a smartphones, de relógios de pulso a tablets e computadores, interagimos diariamente com um grande número de diferentes dispositivos elétricos e eletrônicos, alguns dos quais são tão pequenos ou simples que sequer nos damos conta da sua existência.

Dentro do universo da eletrônica, uma das áreas mais interessantes e que movimenta o mercado é a dos microprocessadores e microcontroladores, pequenos chips que incluem internamente praticamente toda a eletrônica necessária para construir máquinas e dispositivos dotados de alguma forma de inteligência.

A base por trás dos microcontroladores e microprocessadores é a eletrônica digital. Para melhor entendê-la, é necessária uma breve reflexão sobre como o universo funciona.

Introdução 19

O mundo é analógico: a temperatura de uma sala, a intensidade da luz, o tempo, as dimensões físicas de uma caixa, o som, a distância entre casas e trabalhos, tudo isso é medido por grandezas analógicas. Elas podem ser medidas utilizando algum tipo de unidade de medição e podem variar consideravelmente (imagine que nada no mundo é exatamente igual; mesmo os mecanismos produzidos pela máquina mais precisa serão ligeiramente diferentes se medidos com a devida precisão).

Por outro lado, os computadores modernos são máquinas eminentemente binárias. Eles somente podem reconhecer dois tipos de informação: 0 (falso) ou 1 (verdadeiro). As imagens, filmes e cores que vemos na tela de um computador ou em filme em DVD, a música que ouvimos de um CD player ou de um MP3 player, tudo isso pode ser reduzido somente a zeros e uns.

As razões para utilizar um sistema binário (digital) em vez de um sistema analógico são muito simples:

1. Por existirem somente dois níveis de tensão, é mais simples projetar os circuitos eletrônicos de computadores digitais. A utilização de transistores como chaves permite obter dois níveis distintos de tensão (0V para chave aberta ou falso e 5V para chave fechada ou verdadeiro).

2. A matemática por trás dos modernos computadores é baseada na álgebra booleana, criada por George Boole (um matemático e filósofo inglês que viveu no século XVIII e que criou a álgebra booleana, baseada em dois estados: verdadeiro e falso).

Vemos então que os computadores utilizam a base binária, ao passo que nós, seres humanos, utilizamos a base decimal, constituída de 10 diferentes símbolos (0 a 9) e adotada em virtude de possuirmos 10 dedos nas mãos (as mãos foram o primeiro instrumento de cálculo na história da humanidade), mas além dessas duas bases, existem outras bases numéricas importantes, entre elas a octal (que utiliza 8 diferentes símbolos, de 0 a 7) e hexadecimal (base 16 diferentes símbolos, de 0 a 9, A, B, C, D, E, F).

A base hexadecimal permite representar diretamente um valor binário utilizando poucos dígitos. Ela foi muito importante nos primórdios da computação, pois permitia que os sistemas de apresentação de dados utilizassem displays com poucos dígitos, assim como os teclados também eram mais fáceis de construir (displays eram itens complexos e caros até a década de 80, foi somente com a invenção dos LEDs e posteriormente dos displays LED que houve uma redução significativa no custo dos mesmos).

A facilidade de representação de valores binários em hexadecimal é oriunda do processo de conversão, que é absolutamente simples e intuitivo (o mesmo não ocorre com binário e decimal, por exemplo).

Para entender a razão desta simplicidade, vejamos como funciona o sistema de bases numéricas. Primeiramente, é importante observar que em qualquer base numérica existem dígitos e através da junção de múltiplos dígitos é que se pode representar uma quantidade arbitrária qualquer.

O primeiro dígito (o menos significativo) em qualquer base tem sempre o peso 1. Ele corresponde a base elevada a potência 0. O dígito de magnitude imediatamente superior é o da

Microcontroladores RL78: Guia Básico 20

base elevada a potência 1 e assim por diante. Os pesos das diferentes posições nas bases numéricas podem ser vistos na tabela 1.2.

Binário Decimal Hexadecimal 0000 0 0 0001 1 1 0010 2 2 0011 3 3 0100 4 4 0101 5 5 0110 6 6 0111 7 7 1000 8 8 1001 9 9 1010 10 A 1011 11 B 1100 12 C 1101 13 D 1110 14 E 1111 15 F

Tabela 1.1

Peso

3 2 1 0

Binário 23=8 22=4 21=2 20=1

Decimal 103=1000 102=100 101=10 100=1

Hexadecimal 163=4096 162=256 161=16 160=1

Tabela 1.2

Seguindo a tabela 1.2, o número 1001 binário equivale a 1*8 + 0*4 + 0*2 + 1*1 = 9 decimal, o número 1001 decimal equivale a uma milhar (1*1000) mais uma unidade (1*1) e o número 1001 hexadecimal equivale a 1*4096 + 1*1 = 4097 decimal.

É fácil perceber que com dois dígitos binários podemos representar até 4 diferentes valores (00, 01, 10 e 11), com dois dígitos decimais podemos representar até 100 diferentes valores (de 0 a 99) e com dois dígitos hexadecimais podemos representar até 256 valores (de 0 a FF).

Mas além da simplificação da representação de dados (em termos de redução no número de dígitos), a base hexadecimal oferece ainda a facilidade adicional de permitir a simples e rápida conversão de/para binário. Tudo o que é necessário é agrupar os dígitos binários em nibbles (conjuntos de 4 bits) e em seguida realizar diretamente a conversão de/para hexadecimal.

Vejamos alguns exemplos: 01000010 em binário pode ser separado em 0100 e 0010, 0100 equivale a 4 hexadecimal, 0010 equivale a 2 hexadecimal, então 01000010 binário equivale a 42 hexadecimal. 10100110 em binário, 1010 equivale a A hexadecimal, 0110 equivale a 6 hexadecimal, então 10100110 binário equivale a A6 hexadecimal. A recíproca também é

Introdução 21

verdadeira: 7B hexadecimal, 7 hexadecimal equiva e 0111 binário e B hexadecimal equivale a 1011 binário, então 7B hexadecimal equivale a 01111011 binário!

A aritmética, em qualquer que seja a base, também é baseada em princípios comuns e deve sempre levar em consideração a quantidade de símbolos únicos existentes na base, para cada posição numérica.

Assim, a soma de 7 + 5 em decimal é feita agrupando os dígitos de magnitude equivalente. Nos casos onde não há dígito para representar a magnitude desejada, ocorre o transporte para a próxima posição:

7 +

5

12

No caso, a adição de 7 com 5, resulta que não há um símbolo decimal único para representar a grandeza, por isso, há um transporte para a próxima posição.

Nas operações em outras bases (seja binário, hexadecimal, etc.), o procedimento é exatamente o mesmo. Vejamos a adição dos valores binários 10 + 10:

10 +

10

100

Outro exemplo, desta vez em hexadecimal. Vejamos a adição de 9 + 9: 9

+ 9

12

Quando se realiza operações aritméticas envolvendo bytes (conjuntos de 8 bits), diz-se que ocorre um transporte (carry em inglês) quando há um transporte binário do bit 7 (o oitavo bit do byte).

No caso das operações de subtração, utiliza-se basicamente o mesmo princípio da adição e os circuitos somadores, no entanto, para a subtração, faz-se a soma do minuendo com subtraendo, sendo este escrito com sinal inverso:

10 10 -

4 +

-4

6

é o mesmo que 6

Isto permite que as unidades lógicas e aritméticas dos microprocessadores e microcontroladores possam realizar operações de subtração a partir de um circuito somador. Para isso, utiliza-se uma representação binária chamada de “complemento de dois”, que consiste no complemento (inversão de todos os bits) e a adição de um. Assim, para obtermos o equivale a -4, utilizamos o valor absoluto 4 para obter o complemento de dois conforme abaixo:

Valor absoluto (4) 0 0 0 0 0 1 0 0 Complemento 1 1 1 1 1 0 1 1

+ 1 0 0 0 0 0 0 0 1

Resultado 1 1 1 1 1 1 0 0

Para realizar a operação 10-4 podemos, através de uma adição (8 bits), fazer:

Microcontroladores RL78: Guia Básico 22

10 0 0 0 0 1 0 1 0 +

-4 1 1 1 1 1 1 0 0 Resultado 0 0 0 0 0 1 1 0

A representação em complemento de dois também é utilizada nas operações com números sinalizados (como os signed char e signed int em C). Neste caso, o bit mais significativo (aquele mais à esquerda) representa o sinal (0 = positivo e 1 = negativo), enquanto que os demais bits representam a magnitude do número.

Assim, a representação binária de 8 e 16 bits em complemento de dois segue a seguinte forma:

sinal Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

sinal Bit 14 Bit 13 Bit 12 Bit 11 Bit 10 Bit 9 Bit 8 Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

Figura 1.9

A tabela a seguir mostra uma escala reduzida dos valores decimais de 8 bits sinalizados e a sua representação binária em complemento de dois.

Decimal Binário 127 01111111 126 01111110 ... ... 2 00000010 1 00000001 0 00000000 -1 11111111 -2 11111110 ... ...

-126 10000010 -127 10000001 -128 10000000

Tabela 1.3

Agora que já vimos alguns conceitos importantes acerca de bases numéricas e suas operações básicas é hora de rever alguns dos conceitos relacionados aos circuitos digitais que formam a base para os computadores e microcontroladores.

Circuitos digitais podem ser construídos com transistores (circuitos TTL - Transistor-Transistor Logic), MOSFETs (circuitos CMOS - Complementary Metal-Oxide-Seminconductor), etc. Nos circuitos TTL, transistores NPN e PNP, figura 1.10B, são utilizados para controlar os níveis lógicos no interior do chip. Nos circuitos CMOS, MOSFETs canal N e canal P (figura 1.10C), fazem o papel das chaves. O propósito é sempre o mesmo: utilizar um elemento de comutação para simular uma chave, de forma a produzir os dois estados lógicos possíveis.

Com base na álgebra booleana existem quatro funções básicas na eletrônica digital: NÃO,

Figura 1.10 - Três elementos de

comutação

Introdução 23

E, OU e OU exclusivo (ou simplesmente EOU). A função NÃO realiza a inversão do nível lógico de entrada: NÃO 0 = 1 e NÃO 1 = 0. A função E retorna verdadeiro (1) quando todas as entradas são verdadeiras, a função OU retorna verdadeiro quando qualquer uma das entradas é verdadeira e a função EOU retorna verdadeiro quando as entradas são diferentes. A tabela 1.4 mostra a tabela verdade para as três funções lógicas básicas.

Entrada Saída A B AND OR EOR 0 0 0 0 0 0 1 0 1 1 1 0 0 1 1 1 1 1 1 0

Tabela 1.4 - Funções lógicas básicas da eletrônica digital

Nas figuras 1.11A e 1.11B é possível ver como são construídas portas lógicas NÃO e NÃO-E utilizando MOSFETs.

A - Porta lógica NÃO B - Porta lógica NÃO-E (NAND)

Figura 1.11

Os símbolos padronizados das funções lógicas básicas (chamadas portas lógicas) estão representados na figura 1.12.

Figura 1.12 - Portas lógicas básicas: NÃO (A), E (B), OU (C) e EOU (D)

Utilizando estas funções lógicas básicas é possível criar circuitos digitais complexos que podem ser classificados em duas categorias: circuitos combinacionais e sequenciais.

Nos circuitos combinacionais, a saída é uma função do sinal de entrada. Alguns exemplos são os somadores, subtratores, comparadores digitais etc. A figura 1.13A mostra a implementação de um somador completo (o bloco básico dos circuitos aritméticos de qualquer computador).

Nos circuitos sequenciais, a saída é uma função não somente do conteúdo atual da entrada, mas também dos estados anteriores. Alguns exemplos de circuitos lógicos sequenciais

Microcontroladores RL78: Guia Básico 24

são os flip-flops, registradores, contadores, latches etc. A figura 1.13B mostra um latch de dados que constitui um dos elementos básicos de memória nos computadores modernos.

A - Somador completo

B - Latch de dados

Figura 1.13

Os circuitos lógicos sequenciais e combinacionais são elementos construtivos básicos das CPUs (Unidades Centrais de Processamento) dos microprocessadores e microcontroladores que utilizamos diariamente.

Mas o que é microprocessador? Como ele funciona? Qual a diferença entre microprocessador e microcontrolador?

Para entender o que é um microprocessador, primeiro devemos entender mais alguns conceitos relacionados a programação.

Um programa é a codificação em linguagem computacional de um algoritmo lógico criado para resolver um problema específico.

Para escrever um programa, é necessário analisar cuidadosamente o problema a ser resolvido, identificando todos os passos necessários para se atingir a solução.

Uma vez determinados os passos para chegar à solução, é preciso criar um algoritmo que os descreva. A utilização de uma ferramenta gráfica como um fluxograma pode auxiliar na criação de tal algoritmo.

Como exemplo, imagine o problema simples de contar de 0 até 10. Os passos para a solução deste problema poderiam ser:

1. Iniciar a contagem em 0.

2. A contagem atual é igual a 10?

3. Sim? Então vai para o final.

4. Não? Então incrementa a contagem em um.

5. Retorna ao passo 2.

Listagem 1.1

O fluxograma que descreve o algoritmo sugerido pode ser visto na figura 1.14.

Estando de posse do algoritmo, é possível iniciar a codificação do programa de forma que um computador entenda, mas como se faz isso?

A resposta é simples: utilizando a linguagem binária de zeros e uns!

Introdução 25

Figura 1.14 - Fluxograma

À primeira vista pode parecer incrível que um computador capaz de desempenhar tarefas tão complexas (como navegar pela Internet, reproduzir música, jogos etc.) somente seja capaz de diferenciar zeros de uns, mas é exatamente isso que acontece.

De fato, é possível agrupar bits formando-se sequências maiores, que podem representar números, instruções, cores ou o que quer que o programador deseje representar.

Qualquer computador, microcomputador, microprocessador, microcontrolador, etc. reconhece algumas sequências de bits como instruções. Essas instruções dizem o que ele deve fazer: adicionar números, armazenar algo na memória, desviar para outro ponto do programa etc. A CPU é responsável pela leitura dessas instruções da memória, sua interpretação e execução.

Esses grupos de bits que possuem significado especial para a CPU são chamados de códigos de operação (em inglês operation codes ou opcodes).

Computadores diferentes frequentemente possuem diferentes CPUs e diferentes CPUs possuem diferentes opcodes para as instruções que elas reconhecem (isso explica por que você não pode executar uma aplicação de um celular Android® em um celular iPhone® ou vice versa).

Tomemos como exemplo a instrução clear (CLRB). Ela apaga (preenche com zero) um registrador ou o conteúdo de uma posição da memória. Nos microcontroladores RL78, essa instrução pode ser representada por diversos opcodes (dependendo do tipo de operando da instrução), assim, a instrução CLRB end (apaga o conteúdo da posição de memória indicada por end) é representada pelo código binário 11110100 xxxxxxxx yyyyyyyy (onde xxxxxxxx yyyyyyyy é o endereço em binário de end). Após a leitura do opcode na memória do chip, a CPU decodifica a instrução e executa a operação indicada.

Depois de apagar o conteúdo da posição de memória end, a CPU busca uma nova instrução no endereço seguinte da memória e o processo de decodificação e execução é realizado novamente. A figura 1.15 demonstra os ciclos básicos de execução de uma instrução.

No interior da CPU encontramos normalmente alguns importantes elementos (que variam de um modelo de CPU para outro): o decodificador de instruções (responsável por decodificar

Microcontroladores RL78: Guia Básico 26

cada opcode), o PC (Program Counter - contador de programa, responsável por controlar a sequência do programa), a unidade lógica e aritmética (ULA, responsável pelos cálculos), o registrador acumulador de resultados, além de outros registradores de propósitos gerais.

O decodificador de instruções é um circuito lógico que traduz os opcodes na sequência interna de microoperações necessárias para realizar a operação descrita pela instrução.

Algumas CPUs utilizam um decodificador chamado de hardwired, ao passo que outras utilizam

Figura 1.15 - Ciclos de execução de uma instrução.

um decodificador baseado em microcódigos.

Os decodificadores hardwired são normalmente mais rápidos, pois fazem com que grupos de bits do opcode selecionem e ativem diretamente as partes da CPU necessárias para a execução da instrução.

Os decodificadores baseados em microcódigos utilizam máquinas de estado para realizar a decodificação das instruções, o que os torna normalmente mais lentos e ao mesmo tempo mais flexíveis que os decodificadores hardwired.

A maioria das CPUs modernas inclui também algum tipo de memória interna. Os elementos básicos de memória interna são os registradores, geralmente utilizados para o armazenamento temporário de dados e no controle da operação da CPU. Os registradores mais importantes em praticamente todas as arquiteturas são o contador de programa (PC) e o acumulador.

O contador de programa (PC) é um registrador especial responsável pelo controle e sequenciamento do fluxo do programa. Devido ao fato de ser uma máquina sequencial (na maioria dos casos), a CPU deve executar uma sequência de instruções armazenadas em algum tipo de memória. A função do PC é apontar o endereço de memória onde a próxima instrução a ser executada encontra-se armazenada. A instrução apontada pelo PC é buscada e enviada ao decodificador seguindo os passos descritos na figura 1.15. Antes de completar a instrução corrente a CPU automaticamente incrementa o PC de forma que ele aponte sempre o endereço de memória da próxima instrução.

O acumulador é utilizado principalmente nas operações lógicas e aritméticas. A maioria das CPUs utiliza o conteúdo do acumulador como um operando nas instruções aritméticas e lógicas (o outro operando pode ser um registrador ou um valor lido da memória). Como veremos mais adiante, os RL78 não possuem um registrador acumulador específico, ao invés disso existe um conjunto de registradores que podem também atuar como acumuladores.

Outro componente importante da CPU é a unidade lógica e aritmética (ULA). Esse circuito lógico combinacional é utilizado por todas as operações aritméticas e lógicas. Na maioria dos sistemas, a ULA possui duas entradas (os operandos das operações): uma é geralmente conectada ao acumulador e a outra, a um registrador ou recebe um valor lido da memória. Os resultados das operações da ULA são normalmente armazenados no acumulador.

Busca instrução na memória

Decodifica a instrução

Escreve o resultado da operação

Introdução 27

Antes de retomarmos o tópico de programação, vejamos a diferença entre microprocessador e microcontrolador. Em poucas palavras, podemos dizer que microprocessador é um chip com uma CPU, ULA e circuitos básicos de suporte. Esses chips necessitam de memórias externas e outros chips para poderem realizar tarefas úteis. Já o microcontrolador é um chip que integra num mesmo encapsulamento a CPU, ULA, circuitos de suporte, memórias e periféricos. Um microcontrolador é frequentemente referido como um computador num único chip.

A aplicação alvo de um microprocessador também é diferente daquela de um microcontrolador. Enquanto um microprocessador é projetado para ser utilizado em computadores e dispositivos computacionais (como tablets e smartphones) de uso geral, capazes de executar programas complexos e sistemas operacionais, um microcontrolador, por outro lado, é projetado para realizar tarefas específicas e executar programas mais simples (geralmente sem a necessidade de um sistema operacional).

É cada vez mais complexo estabelecer uma distinção entre microprocessadores e microcontroladores, pois estes tornam-se mais e mais complexos e muitas vezes confundem-se com microprocessadores.

Voltando ao tópico de programação, é fácil constatar que a utilização de números binários e opcodes para escrever um programa pode ser bastante trabalhosa, especialmente porque dificultam a leitura e o entendimento do código, além de aumentar a probabilidade de erros (inclusive aqueles oriundos de falhas de digitação). Por isso, ainda na década de 1950 surgiu a primeira linguagem de programação, o assembly.

Na verdade, a linguagem assembly é somente uma representação simbólica dos opcodes. Utilizando um programa especial (chamado Assembler ou montador), os mnemônicos assembly são traduzidos diretamente para códigos binários (opcodes). Essa tradução é feita numa razão de um para um, ou seja, cada instrução assembly é traduzida em um único opcode.

Sendo assim, para podermos programar uma máquina, é necessário primeiramente conhecer quais instruções essa máquina é capaz de entender e como utilizá-las corretamente.

Considerando a CPU dos RL78, existem cinco instruções (de um conjunto de oitenta e uma) que podem ser utilizadas para implementar o programa descrito na listagem 1.1:

CLRB: apaga o conteúdo de um registrador ou endereço da memória.

CMP a,b: compara o conteúdo de uma registrador ou posição da memória (operando “a”) com o conteúdo do segundo operando (“b”), modificando os bits Z, CY e AY, de acordo com o resultado (a comparação é feita pela subtração do operando “b” do operando “a”).

INC: adiciona um ao operando.

BR: desvio incondicional para o endereço especificado.

BZ: desvio para o endereço especificado no caso do flag Z = 1.

A figura 1.16 apresenta uma adaptação do fluxograma da figura 1.13 utilizando instruções assembly do RL78.

Microcontroladores RL78: Guia Básico 28

Figura 1.16

A listagem 1.2 mostra o programa codificado em linguagem assembly. Ele foi escrita com base em algumas considerações iniciais:

1. O programa é armazenado a partir do endereço 0x000CE (0x significa que o número está em hexadecimal). Este é normalmente o endereço inicial da memória flash para armazenamento de programas nos microcontroladores RL78;

2. A variável “cnt” está localizada no endereço 0xEF00 da memória, o primeiro endereço válido da memória RAM no modelo do RL78/G13 utilizado (o R5F100LE);

3. Utilizaremos o prefixo “N:” para especificar um endereço de 16 bits na memória do microcontrolador, esta é a notação utilizada pelo compilador IAR para representar o modo de endereçamento direto de 16 bits (maiores detalhes serão vistos no capítulo 3);

4. Uma constante (como o valor 10 decimal) é escrita precedida do símbolo #. Este símbolo indica ao assembler que o valor que o segue é uma constante imediata;

5. Os endereços e opcodes estão escritos em base hexadecimal.

Analisando o fluxograma da figura 1.16 e a listagem 1.2, podemos entender o funcionamento do pequeno programa apresentado. É fácil perceber que a instrução CMP possui um importante papel no controle do programa. Endereço Opcode Assembly Comentários

000CE F500EF CLRB N:cnt Apaga o conteúdo da memória cnt

000D1

4000EF0A

repete:

CMP N:cnt,#10

Compara o valor de cnt com 10 (cnt-10)

000D5 DD07 BZ final Desvia para “final” se Z=1 (Z=1 se na

comparação anterior cnt era igual a 10)

000D7 A000EF INC N:cnt Incrementa cnt em um

000DA EFF7 BR repete Desvia para “repete”

000DC final:

Listagem 1.2

Início

CLRB CNT

CMP CNT,#10

INC CNT

Fim

Introdução 29

A instrução “CMP N:cnt,#10” realiza a comparação entre dois valores: o conteúdo da variável “cnt” e o valor imediato 10 decimal. Observando a coluna dos opcodes, encontramos o valor 0x4000EF0A, sendo 0x40 o código da instrução, 0x00EF o endereço do operando “cnt” na memória de dados (o endereço da variável é 0xEF00 e na instrução é escrito em formato little endian, iniciando pela parte menos significativa) e finalmente a constante com a qual deve ser feita a comparação (0x0A que é a representação hexadecimal de 10 decimal).

Os termos little endian e big endian são utilizados em computação para especificar como uma máquina armazena dados numéricos de múltiplos bytes na memória. No formato little endian tais dados são armazenados na memória sempre iniciando-se pelo seu byte menos significativo, já no formato big endian, tais dados são armazenados na sua forma natural, ou seja, iniciando-se pelo byte mais significativo. Exemplo: o número 0x1234 hexadecimal é armazenado 0x34,0x12 no formato little endian e 0x12,0x34 no formato big endian!

Observe que a comparação é realizada por meio de uma operação de subtração realizada no interior da ULA. De acordo com o resultado da comparação (subtração) alguns bits do registrador PSW são alterados: Z, AC e CY. Se o valor do contador for igual a 10, o bit Z é setado.

Em seguida, a instrução “BZ final” é o chamado desvio condicional. Este tipo de instrução avalia uma condição e efetua o desvio do programa caso a condição seja verdadeira. No caso, a instrução avalia o estado do bit Z (localizado no registrador PSW) e desvia para “final” caso Z=1. Caso Z=0, a instrução não produz efeito e o programa segue a sua sequência natural.

Note que o opcode da instrução é 0xDD07, onde 0xDD indica a instrução propriamente dita (BZ) e 0x07 é o endereço de destino do desvio. Nestas instruções o endereço de destino é escrito relativamente ao endereço da instrução de desvio, ou seja, o valor 0x07 indica que o endereço de destino é igual ao endereço de BZ (0x000D5) mais o deslocamento 0x07, ou seja, 0x000DC.

A próxima instrução “INC N:cnt” faz o incremento do valor da variável “cnt”, ou seja, soma um ao conteúdo dela. Novamente podemos perceber que o opcode da instrução é 0xA000EF, onde 0xA0 indica a instrução INC e 0x00EF é o endereço little endian da variável “cnt”.

A última instrução “BR final” provoca o desvio do fluxo do programa para o endereço indicado por “repete”, ou seja 0x000D1. O opcode da instrução é 0xEFF7, sendo 0xEF o código da instrução e 0xF7 o deslocamento do endereço de destino. Observe que neste caso o endereço de destino está localizado antes da instrução de desvio e por isso o deslocamento é negativo. O valor de deslocamento é calculado da seguinte forma: 0xD1 (o destino) – 0xDA (endereço onde está a instrução de desvio) = 0xF7. Note que 0xF7 é a representação em complemento de dois do número -9 decimal.

Analisando o programa inteiro podemos perceber que inicialmente a variável “cnt” é iniciada em zero “CLRB N:cnt”, em seguida verificamos se o valor dela é igual a 10 “CMP N:cnt,#10”, caso negativo “BZ final”, o programa segue, incrementa a variável “INC N:cnt” e em seguida desvia “BR repete” para uma nova comparação. Quando a comparação da variável com

Microcontroladores RL78: Guia Básico 30

10 “CMP N:cnt,#10” resulta verdadeira (Z=1), o desvio condicional “BZ final” é tomado e o programa desvia para o endereço “final”!

Esta foi apenas uma apresentação rápida da operação de uma CPU e de como uma sequência de instruções é executada. No decorrer do livro vamos explorar em mais detalhes o funcionamento de cada instrução dos RL78.

1.4. Microcontroladores RL78

A linha de microcontroladores RL78 da Renesas é derivada da união de duas linhas de microcontroladores: a linha 78K0R originalmente desenvolvida pela NEC e R8C da Renesas.

Os microcontroladores RL78 são máquinas CISC de 16 bits que possuem como diferencial a sua alta eficiência, decorrente de duas características importantes das CPUs RL78: alta velocidade de execução de código (pois utilizam um pipeline de três estágios que faz com que 56% das instruções sejam executadas em apenas um ciclo de clock) e consumo de energia extremamente baixo (graças ao design focado principalmente na eficiência energética e a utilização de tecnologias de semicondutores de baixo consumo de energia), o consumo de energia, no melhor caso, é de aproximadamente 66µA/MHz.

Um regulador interno de tensão também auxilia na redução do consumo de energia e permite que os RL78 apresentem níveis muito baixos de emissão eletromagnética (EMI).

Além de consumirem pouca energia quando em operação, a existência dos modos de baixo consumo de energia halt, stop e snooze permite reduzir grandemente o consumo de energia quando a CPU não está em operação.

Em termos de performance, os RL78 podem operar até 32MHz, executam a maioria das instruções em 1 ou 2 ciclos de clock e possuem capacidade de endereçamento de até 1MiB, permitindo que o fabricante disponibilize grandes quantidades de memória flash e RAM (até 512KiB de flash e até 32KiB de RAM nos modelos mais poderosos lançados até o momento).

A linha de periféricos inclui unidades de temporização TAU onde cada canal de 16 bits pode atuar praticamente como um timer independente, relógio de tempo real com calendário, timer de intervalo, timer para controle de motores (até 6 canais de PWM), interfaces de comunicação serial (síncronas SPI e I2C, assíncronas UART/LIN e USB), conversor A/D de 8, 10 ou 12 bits (com capacidade de varredura de 4 canais), conversor D/A, comparadores analógicos, controlador de displays LCD, etc.

Praticamente todos os modelos contam com DMA (Direct Memory Access - acesso direto a memória) de 1 ou 2 canais, que permite automatizar as transferências entre os periféricos e a memória, dispensando a intervenção da CPU. Além de facilitar a transferência de dados entre a memória e os periféricos, o DMA também pode auxiliar na redução do consumo de energia (permitindo fazer transferências enquanto a CPU está em modo halt).

A maioria dos modelos (exceto os G10) possui suporte a divisão e multiplicação, em alguns modelos por meio de um módulo periférico de hardware, em outros, por meio de instruções DSP especiais (RL78/G14).

Introdução 31

Também estão disponíveis periféricos de segurança como, por exemplo, checagem de erros na memória flash (ECC com CRC) e RAM (paridade), watchdog com janela de tempo, detector de baixa tensão, detecção de falha de oscilador e de acesso a endereço ilegal da memória.

A linha RL78 é composta dos seguintes membros:

Modelos de uso geral:

• RL78/G10 – com versões de 10 e 16 pinos, capacidades de memória flash de 1KiB até 4KiB e memória RAM de 128 até 512 bytes. Estes microcontroladores possuem núcleo de 8 bits e operam a até 20MHz, incluem interfaces de comunicação como UART, SPI e I2C (nos modelos de 16 pinos), conversor A/D de 10 bits, comparador analógico (nos modelos de 16 pinos) e são os elementos de uso geral e mais baixo custo da linha RL78. Nestes chips a faixa de tensões de alimentação vai de 2,0 a 5,5V.

• RL78/G12 - com versões de 20, 24 e 30 pinos, capacidades de memória flash de 2KiB até 16KiB, memória RAM de 256 bytes até 2KiB e dataflash até 2KiB. Estes microcontroladores operam a até 24MHz, incluem interfaces de comunicação como UART, SPI e I2C, conversor A/D de 10 bits, DMA (em alguns modelos) e juntamente com os G10 são os elementos de uso geral e mais baixo custo da linha RL78.

o RL78/G1C - com versões de 32 e 48 pinos, capacidade de memória flash de 32KiB, memória RAM de 5,5KiB e dataflash de 2KiB. Estes microcontroladores operam a até 24MHz e incluem interfaces de comunicação como UART, SPI, I2C e USB 2.0 full speed (12Mbits/s) capaz de operar como host ou device e compatível com a versão 1.2 da especificação de carga de bateria pela porta USB (até duas portas USB disponíveis).

• RL78/G13 - com versões de 20 a 128 pinos, capacidades de memória flash de 16KiB até 512KiB, memória RAM de 2KiB até 32KiB e dataflash de 4 ou 8KiB. Estes microcontroladores operam a até 32MHz, incluem múltiplas interfaces de comunicação como UART, SPI, I2C, conversor A/D de 10 bits, DMA e são voltados ao uso geral em aplicações de pequena e média complexidade.

o RL78/G1A - com versões de 25 a 64 pinos, capacidades de memória flash de 16KiB até 64KiB, memória RAM de 2KiB até 4 KiB e dataflash de 4KiB. Estes microcontroladores operam a até 32MHz, incluem interfaces de comunicação como UART, SPI e I2C, DMA e um conversor A/D de 12 bits.

• RL78/G14 - com versões de 30 a 100 pinos, capacidades de memória flash de 16KiB até 256KiB, memória RAM de 2,5KiB até 24KiB e dataflash de 4 ou 8KiB. Estes microcontroladores operam a até 32MHz, além dos periféricos da linha G13, incluem instruções DSP para processamento digital de sinais, timer para controle de motores, D/A de 8 bits e comparador analógico. Eles são os membros mais avançados da linha RL78 e são voltados ao uso geral em aplicações de média complexidade.

Com controlador de display LCD integrado:

Microcontroladores RL78: Guia Básico 32

• RL78/L12 - com versões de 32 a 64 pinos, capacidades de memória flash de 8KiB até 32KiB, memória RAM de 1KiB até 1,5KiB e dataflash de 2KiB. Estes microcontroladores operam a até 24MHz e incluem controladores para displays LCD com até 280 segmentos (13 a 39 segmentos com 4 planos ou 18 a 35 segmentos com 8 planos).

• RL78/L13 - com versões de 64 e 80 pinos, capacidades de memória flash de 16KiB até 128KiB, memória RAM de 1KiB até 8KiB e dataflash de 4KiB. Estes microcontroladores operam a até 24MHz e incluem controladores para displays LCD com até 376 segmentos (36 a 51 segmentos com 4 planos ou 32 a 47 segmentos com 8 planos).

Modelos destinados a aplicações específicas:

• RL78/D1x - com versões de 48 a 100 pinos, capacidades de memória flash de 24KiB até 256KiB, memória RAM de 2KiB até 16KiB e dataflash de 8KiB. Estes microcontroladores operam a até 32MHz e incluem controladores para displays LCD com até 212 segmentos (4 planos com até 53 segmentos), controlador de motor de passo e gerador de som, são voltados a aplicações de mostradores e painéis automotivos.

• RL78/F1x - com versões de 20 a 64 pinos, capacidades de memória flash de 8KiB até 64KiB, memória RAM de 512 bytes até 4KiB e dataflash de 4KiB. Estes microcontroladores operam a até 32MHz, suportam temperaturas de até 150ºC e são voltados para aplicações automotivas em dispositivos de carroceria (car body).

• RL78/I1x - com versões de 20 a 38 pinos, capacidades de memória flash de 32KiB até 64KiB, memória RAM de 2KiB até 4KiB e dataflash de 4KiB. Estes microcontroladores operam a até 32MHz, com tensões de alimentação de 2,7 a 5,5V e incluem controladores PWM para leds , UART com suporte a DALI e DMX512 e são voltados a aplicações de controle de iluminação e correção de fator de potência.

1.5. Pinagens e Encapsulamentos

Abaixo apresentamos a pinagem de alguns modelos de RL78:

Figura 1.17 – Modelos de 10 pinos (RL78/G10)

Introdução 33

Figura 1.18 – Modelos de 20 pinos (RL78/G12)

Figura 1.19 – Modelos de 20 pinos (RL78/G13)

Figura 1.20 – Modelos de 30 pinos (RL78/G13)

Microcontroladores RL78: Guia Básico 34

Figura 1.21 – Modelos de 64 pinos (RL78/G13)

Pinos especiais:

• VDD - alimentação positiva (1,6 a 5,5 Volts, nos G10 é de 2,0 a 5,5V)

• EVDD0 - alimentação positiva (1,6 a 5,5 Volts) para as portas P0, P1, P3, P4, P5, P6, P7 e P14

• VSS - referência de terra (0 Volt)

• EVSS0 - referência de terra (0 Volt) para as portas P0, P1, P3, P4, P5, P6, P7 e P14

• REGC - estabilização do regulador interno (conectar um capacitor de 0,47 a 1µF)

• RESET - sinal de reset ativo em nível lógico “0”

• P40/TOOL0 – pino de E/S (bit 0 da porta 4) e pino de programação/depuração (TOOL0)

Cuidado ao utilizar o pino TOOL0 como E/S na aplicação, pois cargas muito elevadas neste pino podem prejudicar a programação e a depuração do chip no circuito!

Introdução 35

1.6. R5F100LEA

O microcontrolador objeto de estudo deste livro é o R5F100LEA, um membro da linha RL78/G13 de microcontroladores da Renesas. Ele inclui uma CPU RL78, além de 64kibibytes de memória flash, 4.096 bytes de memória RAM e 4.096 bytes de memória dataflash. Este chip pode operar a até 32MHz e a tensão de alimentação pode ir de 1,6 a 5,5 Volts.

Além das características gerais dos RL78/G13, o R5F100LEA inclui também:

• 58 pinos de entrada/saída, divididos em 11 portas de entrada/saída (E/S): P0, P1, P2, P3, P4, P5, P6, P7, P12, P13 e P14;

• Diversos pinos podem ser configurados para operar como saídas dreno aberto e podem fazer interface com outros níveis de tensão (desde que dentro da faixa de 1,6 a 5,5V);

• Seis pinos de interrupção externa, com borda de sensibilidade configurável;

• Oito pinos de interrupção de teclado (geram interrupção ao mudar de estado);

• Quatro diferentes periféricos de temporização:

o Duas unidades de temporização TAU, cada uma com 8 canais (total de 16 canais). Cada canal do TAU pode operar como um timer independente ou ser utilizado em conjunto com outros canais. Os canais dos TAU podem fazer captura de sinais (medição de período), comparação (geração de interrupção ou sinais de largura definida), PWM, etc.

o Relógio de tempo real com calendário e interrupção de alarme, que pode operar com clock externo de 32768Hz ou com clock interno de 15kHz;

o Timer de interrupção periódica (12 bits) que pode ser utilizado para criar bases de tempo;

o Watchdog programável com operação em “janela de tempo”.

• Dois tipos de interface de comunicação (até 7 portas seriais simultâneas):

o Duas unidades seriais SAU, que podem operar no modo SPI de 3 fios, UART ou I2C simplificado* (a SAU0 pode operar como 4 canais SPI/I2C ou 2 canais UART, a SAU1 pode operar como 2 canais SPI/I2C ou 1 canal UART com suporte a LIN);

o Uma unidade I2C completa. A interface I2C simplificada não pode operar no modo escravo e nem suporta o modo multimaster.

• Conversor A/D de 10 bits com 12 canais de entrada, taxa de conversão de até 470ksps (mil amostras por segundo), varredura de até 4 canais, comparador digital interno e capacidade de operação em modo snooze;

• Quatro canais de DMA, cada canal pode transferir blocos de até 1024 bytes ou words (um byte ou word a cada disparo).

Microcontroladores RL78: Guia Básico 36

1.7. Kits e Ferramentas de Programação

A Renesas possui uma série de kits disponíveis para facilitar o aprendizado e desenvolvimento de aplicações com o RL78.

O kit mais acessível é o YRPBRL78G13, também chamado de “Promotion Board” do RL78/G13. Este kit consiste numa PCI contendo um R5F100LEA e um microcontrolador 78F0730, que atua como programador e depurador USB.

Figura 1.22 – YRPBRL78G13

A placa possui também dois leds, um cristal de 32.768Hz conectado ao oscilador secundário do RL78, um trimpot, duas fileiras de pads conectados aos pinos de E/S do chip e um conector para programação do RL78 através de um programador E1 externo. Também existem jumpers que podem ser utilizados para medição do consumo de corrente do chip.

A figura 1.23 mostra as conexões das duas fileiras de 30 pinos nas bordas da placa (o pino 1 é indicado na borda da placa).

Não conectado Não conectado P30 P70 P05 P71 P06 P72

P147 P73 P146 P74 P137 P75

P41 P76 P42 P77 (conectado ao LED D2) P43 P31

P120 P63 T_RESET P62

P27 P61 P26 P60 P25 P50 P24 P51 P23 P52

(conectado ao trimpot R15) P22 P53 AVREFM P54 AVREFP P55

P130 P17 P04 P16 P03 P15 P02 P14 (recebe dados da COM virtual) P01 P13 (transmite dados para a COM virtual) P00 P12

P141 P11 P140 P10 VDD VDD GND GND

Conector E1

Figura 1.23

Introdução 37

Para desenvolvimento de aplicações mais avançadas o “Starter kit” ou RSK do RL78/G13 inclui 4 leds, 3 teclas de usuário, módulo de display LCD de 8 caracteres por 2 linhas, cristal de 20MHz e de 32.768Hz, conector para depurador E1, porta serial DB9 e interface LIN. O kit inclui um depurador E1 que pode ser utilizado para programar e depurar qualquer microcontrolador RL78, RX e alguns modelos do R8C, 78K e V850.

Figura 1.24 – Starter kit do RL78/G13

Figura 1.25 – Depurador/programador E1

Outro kit bastante interessante e que inclui uma quantidade de periféricos muito maior que os anteriores, é o “Demonstration kit” do RL78/G14. Ele utiliza um microcontrolador R5F104PJA (256KiB de flash, 8KiB de dataflash e 24KiB de RAM num encapsulamento de 100 pinos) e inclui diversos periféricos interessantes na placa: módulo Wi-Fi GainSpan GS1011, display LCD TFT gráfico de 1,5 polegadas, display Eink com seis segmentos, conector para cartão MicroSD, acelerômetro de 3 eixos, sensor de temperatura, EEPROM I2C de 512kib, memória flash SPI de 8Mib (conectada ao módulo Wi-Fi), sensor de luz, microfone, alto falante, sensor de IR, led IR, conector serial DB9, treze leds de usuário, 4 teclas (1 reset), potenciômetro, FET com conector externo, TRIAC isolado com conector externo, portas de expansão e depurador TK integrado com conector USB.

Figura 1.26 – Demonstration kit do RL78/G14

Microcontroladores RL78: Guia Básico 38

1.8. Convenções Utilizadas

No decorrer deste livro utilizamos algumas convenções para representação de símbolos, nomes e outros termos técnicos:

• Este livro utiliza as unidades de informação padronizadas pela Comissão Internacional de Eletrotécnica (IEC) em 2000, as quais foram criadas para ajudar na diferenciação entre os padrões decimais (utilizados no cotidiano) e os padrões binários (utilizados para representar grandezas binárias, comuns no mundo da computação digital):

Prefixo Padrão (Sistema Internacional)

Prefixo Binário (Sistema Internacional)

Prefixo Símbolo Peso Prefixo Símbolo Peso

Kilo k 103 kibi Ki 210

Mega M 106 mebi Mi 220

Giga G 109 gibi Gi 230

Tera T 1012 tebi Ti 240

Peta P 1015 pebi Pi 250

Exa E 1018 exbi Ei 260

Tabela 1.5

Note que 1024 bytes são 1KiB e 1024 bits são 1Kibit!

• Referências a nomes de bit e nomes de registrador são feitas sempre utilizando letras maiúsculas.

• As referências aos nomes dos bits são feitas sempre utilizando o nome ou a associação do nome do registrador e o nome do bit no seguinte formato: REGISTRADOR.BIT. Assim, a referência ao bit Z do registrador PSW pode ser feita apenas ao nome do bit (Z) ou PSW.Z.

• Para representar genericamente um conjunto de registradores ou bits pertencentes a um periférico ou registrador, utilizamos a letra “x” minúscula. Assim, o termo Px representa qualquer um dos seguintes registradores: P0, P1, P2, etc. No caso dos timers, TAUx poderá significar TAU1 ou TAU0 e assim por diante.

• Os símbolos C utilizados neste livro são aqueles definidos e fornecidos pela IAR. Os registradores e bits específicos que podem ser manipulados diretamente pelo código em C estarão sempre grafados em letras maiúsculas. Os símbolos escritos com a primeira letra minúscula “b” referem-se aos bits dos registradores e somente devem ser utilizados nas operações envolvendo registradores. Por exemplo: para se setar o bit RTCEN (registrador PER0) é possível escrever RTCEN = 1 (uma operação de manipulação direta de bit) ou ainda PER0 = bRTCEN (uma operação de escrita de 8 bits no registrador). Os símbolos bXXXX estão definidos no arquivo myRL78.h.

Introdução 39

• No decorrer do texto, as palavras reservadas da linguagem C estão escritas em negrito.

• As notas importantes são apresentadas utilizando a seguinte caixa de texto:

Esta é uma nota importante!

• As dicas de utilização utilizam a seguinte caixa de texto:

Esta é uma dica!

• Os registradores do microcontrolador são representados por figuras como a mostrada a seguir:

Registrador LVIM (Exemplo)

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura LVIOMSK LVIF

Escrita LVISEN 0 0 0 0 0

0 0 LVIM

Reset 0* 0 0 0 0 0 0* 0*

* Após um reset LVD este registrador não é alterado.

Nome do Bit Descrição Bit C Símbolo C

LVISEN Controle de escrita no registrador LVIS: 0 – escrita desabilitada (não produz efeito) 1 – escrita habilitada

LVISEN bLVISEN

LVIOMSK Máscara de estado de saída do LVD: 0 – LVD operando normalmente 1 – LVD em estabilização

LVIOMSK bLVIOMSK

LVIF

Indicador de status do LVD: 0 – tensão (VDD) ≥ valor configurado (VLVD) (ou quando o LVD está desligado) 1 – tensão (VDD) < valor configurado (VLVD)

LVIF bLVIF

Vejamos como ler a tabela:

Existem três linhas rotuladas “Leitura”, “Escrita” e “Reset”. A primeira e a segunda linhas indicam a função de cada bit na sua leitura e escrita respectivamente. A linha “Reset” indica o estado de cada bit após um reset.

Os bits 0 e 1 deste registrador são do tipo “somente leitura”, o que significa que eles somente podem ser lidos pelo software, mas não modificados por ele.

A leitura do bit 0 do registrador retorna o estado do bit LVIF, mas a escrita no mesmo não produz efeitos. Da mesma forma, a leitura do bit 1 retorna o estado do bit LVIOMSK, mas a escrita não produz efeitos.

Os bits 2 a 6 não são implementados e a leitura deles retorna sempre o valor “0”. Normalmente se recomenda escrever somente “0” nos bits não implementados. Alguns bits

Microcontroladores RL78: Guia Básico 40

podem apresentar um “?” no seu estado de reset. Isso significa que ele não é alterado após um reset.

O bit 7 (LVISEN) pode ser lido ou escrito pelo software.

Desta forma, supondo que o registrador LVIM possua o valor 0x00, após a seguinte linha de código:

LVIM = 0x81;

O registrador irá conter o valor 0x80 (já que o bit 0 não é alterado pelo programa).

Observe que os símbolos definidos na coluna “Bit C” estão incluídos nos headers do chip e são fornecidos juntamente com o compilador (pasta include dentro da pasta onde foi instalado o compilador IAR).

Cada modelo de microcontrolador possui dois arquivos header com as definições dos seus registradores SFR e GPR: o arquivo “ior5f10xxx.h” para os SFR principais e “ior5f10xxx_ext.h” para o conjunto de registradores estendido.

No caso do microcontrolador utilizado neste livro (R5F100LE) os arquivos header são "ior5f100le.h" e "ior5f100le_ext.h".

Os símbolos mostrados na coluna “Símbolo C” estão definidos no arquivo “myRL78.h” que pode ser baixado juntamente com os projetos deste livro.

Ferramentas de Programação 41

2

Ferramentas de Programação 2. Ferramentas de Programação

2.1. O Ambiente Embedded Workbench EWRL78

O ambiente IAR Embedded Workbench for RL78 (EWRL78) é um IDE que integra editor, compilador, assembler, linker, simulador e depurador em um único software.

Os leitores dos livros “MSP430: Teoria e Prática” e “Tecnologia ARM: Microcontroladores de 32 bits” irão perceber que o EWRL78 (como é chamado o Embedded Workbench para os RL78) é muito semelhante ao EW430 e EWARM. Esta identidade de ambientes é sem dúvida uma vantagem para os desenvolvedores que necessitam trabalhar com múltiplas plataformas, pois o tempo gasto com a familiarização com a ferramenta de programação é amplamente reduzido.

2.1.1. Criando o Primeiro Projeto

No decorrer deste tópico o leitor poderá aprender como configurar corretamente o ambiente EWRL78 (versão 1.20) e a criação de um projeto em linguagem C.

Para criar um novo projeto no IAR, é necessário selecionar a opção “Create a New Project” dentro do menu principal.

Figura 2.1A Figura 2.1B

Em seguida, devemos selecionar a linguagem de programação a ser utilizada no projeto. Nos exemplos deste livro, utilizaremos a linguagem C, por isso, a seleção deve ser feita conforme a figura 2.1A. Uma vez selecionada a linguagem é necessário dar um nome ao projeto, conforme demonstra a figura 2.1B.

Microcontroladores RL78: Guia Básico 42

Feito isso, teremos uma tela igual a representada na figura 2.2. Nela encontramos a janela do workspace atual (2), a janela de edição de código fonte (3) e a janela de mensagens da IDE (4) e a seleção do modo do projeto (1).

Figura 2.2

O projeto inclui um arquivo genérico “main.c” que consiste no mínimo de código necessário a um programa em C, ou seja, apenas a função principal (main).

Vencida esta etapa é necessário configurar o projeto. Para isso, selecione a opção Project > Options... no menu principal ou, alternativamente, pressione as teclas ALT+F7, ou ainda, pressione o botão direito do mouse sobre a janela do workspace e selecione a opção Options no menu flutuante. A janela de opções (figura 2.3) será exibida.

As configurações de projeto feitas para o modo “Debug” (item 4 da figura 2.2) deverão ser feitas também para o modo “Release”. O modo “Debug” é útil durante a fase de desenvolvimento e testes da aplicação, ao passo que a o modo “Release” é utilizado para geração do código final (normalmente um arquivo .hex para gravação em produção).

Nesta janela, o programador irá selecionar o modelo de RL78 utilizado (no campo Device), além do modelo de memória a ser utilizado para o código (Code model) e dados (Data model) e como as constantes “near” serão colocadas na memória.

Modelos “near” utilizam apenas um segmento de 64KiB de memória, ao passo que modelos “far” utilizam todo o espaço de 1MiB de endereçamento. Preferencialmente devemos utilizar modelos “near”, pois eles geram códigos menores e mais rápidos que os gerados com modelos “far”.

3

4

2

1

Ferramentas de Programação 43

Figura 2.3

Ainda na categoria “General Options”, clique na aba “Library Configuration”. Ali é possível selecionar o tipo de biblioteca padrão C que será utilizada com o projeto (“Normal DLIB”, “Full DLIB” ou “Custom”) e também é possível selecionar se o compilador deve ou não utilizar o hardware de multiplicação integrado (“Use hardware multiplier/divider unit”). Esta opção, ao ser selecionada, faz com que o compilador inclua uma pequena biblioteca (cerca de 260 bytes) que faz com que o multiplicador/divisor por hardware seja utilizado para acelerar as operações de divisão e multiplicação.

Cabe ao programador decidir sobre a necessidade ou não de se utilizar o hardware multiplicador/divisor interno, mas via de regra, se você tiver 260 bytes de flash sobrando, os benefícios em termos de ganho de velocidade valem o espaço adicional necessário.

Além das configurações da categoria “General Options” é importante também configurarmos outras opções. Na categoria “C/C++ compiler”, verifique a aba “Output” e certifique-se de que a opção “Generate debug information” esteja selecionada. Esta opção faz com que o compilador gere informações adicionais necessárias à depuração do programa.

Na aba “Optimizations” é possível configurar algumas opções de otimização de código. Por hora não iremos nos preocupar com isso, mas para produção de código final, é importante utilizar a otimização máxima do compilador (“level high”). Note que é possível otimizar o programa para ocupar menos espaço (Optimize for space), para ser executado mais rapidamente (optimize for speed) ou para a melhor relação custo/benefício entre velocidade e tamanho (balanced).

Na categoria “Linker”, aba “Output”, é importante que a opção “Debug information for C-SPY” esteja selecionada. Ela é responsável por gerar código de depuração necessário para que a ferramenta C-SPY possa funcionar corretamente.

Pressione este botão para

selecionar a CPU

Microcontroladores RL78: Guia Básico 44

Ainda na categoria “Linker” é possível selecionar outro arquivo de configuração do linker. Isto é necessário quando se necessita modificar a forma como o linker utiliza e distribui código e dados na memória do microcontrolador. Um exemplo típico é o uso das bibliotecas FSL, FDL ou EEL para armazenamento de dados na flash, todas elas necessitam de modificações na configuração do linker para poder operar corretamente.

Adicionalmente, pode ser interessante configurar o linker para gerar um arquivo de informações sobre a utilização e alocação da memória. Para isso, basta selecionar a aba “List” e habilitar a opção “Generate linker listing”.

O arquivo .map gerado irá conter diversas informações acerca da distribuição das funções e símbolos na memória do chip. Também é possível verificar a quantidade de memória flash e RAM utilizada.

Figura 2.4

Finalmente, o último passo para configuração do projeto consiste em selecionar o tipo de depurador a ser utilizado. Esta seleção será realizada conforme o tipo de hardware de depuração disponível. Normalmente iremos optar entre o simulador e um depurador externo como o TK ou E1.

A opção pelo simulador (figura 2.4) pode ser interessante para se testar trechos de código, desde que estes não utilizem nenhum periférico dos RL78, pois o simulador da IAR não simula periféricos internos do microcontrolador.

Uma vez que o projeto esteja configurado, podemos nos dedicar ao programa propriamente dito. Assim, o arquivo “main.c” do projeto recém criado deve ser alterado conforme a listagem do exemplo 2.1. Este programa exemplo irá fazer com que o led da placa de demonstração do RL78 pisque. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

Seleção do depurador a ser utilizado

pelo EWRL78

Ferramentas de Programação 45

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED_D2 P7_bit.no7

unsigned long int temp, cnt;

void main( void )

PM7_bit.no7 = 0; // porta P77 como saída

cnt = 0;

while (1)

LED_D2 = 1;

for (temp=100000;temp;temp--);

LED_D2 = 0;

for (temp=100000;temp;temp--);

cnt++;

Exemplo 2.1 – Pisca led por software

Uma vez que o programa tenha sido digitado (ou carregado) corretamente, a aparência do IDE deve ser próxima a da figura 2.5. Podemos então passar a etapa de compilação e depuração.

Para proceder à compilação e montagem completa do projeto, basta clicar no botão MAKE indicado na figura 2.5. O IDE irá automaticamente compilar e “linkar” o programa, gerando os arquivos binários conforme selecionado nas opções do projeto. O mesmo efeito pode ser obtido pressionando-se a tecla F7 ou selecionando-se a opção Project>Make no menu principal.

Figura 2.5

MAKE Compilar o

projeto atual

DEBUG Depurar o

projeto atual

Microcontroladores RL78: Guia Básico 46

Após o processo, a janela de mensagens da IDE estará mostrando, na aba Build, as mensagens emitidas pelo compilador e pelo linker. Caso a mensagem exibida seja diferente de “Total number of errors: 0” e “Total number of warnings: 0”, verifique o código digitado a procura de erros.

2.1.2. Simulando um Programa

Após termos compilado o programa, podemos passar ao teste do mesmo. Primeiramente iremos testar o programa utilizando o simulador do EWRL78.

Para isso é necessário selecionar a opção simulator na janela de opções do projeto conforme a figura 2.4.

Pressionando-se o botão DEBUG (figura 2.5), poderemos dar início a uma sessão de depuração utilizando o simulador.

Após pressionar o botão DEBUG, a tela do IDE deverá passar a ser aquela da figura 2.6.

Figura 2.6 – Depurador do EWRL78

Repare que a janela de mensagens apresenta informações na aba Debug Log, informando que o download foi completado e que o Target (dispositivo alvo, que no caso é o simulador) foi ressetado.

Além disso, temos uma nova janela (Disassembly) e uma barra de botões do depurador.

A janela Disassembly apresenta uma visão da memória de programa do chip, incluindo os endereços de memória, o conteúdo hexadecimal e a instrução assembly correspondente. Permeando as instruções assembly encontramos linhas de código C: as instruções seguintes a cada linha de código C representam as instruções necessárias para executar a tarefa determinada pela linha de código de alto nível.

Botões do depurador

Janela de disassembly

Go to

Ferramentas de Programação 47

O campo “Go to” permite visualizar o código a partir de um endereço específico, por exemplo: se o programador desejar visualizar o código a partir do endereço 0x2000, basta entrar com este valor no campo “Go to” e pressionar a tecla ENTER.

As linhas destacadas em fundo verde representam o próximo comando/instrução a ser executado

A barra de botões do depurador permite controlar a execução do programa: estão disponíveis botões para executar o programa, paralisar a execução, execução passo a passo, criação de breakpoints, etc. A figura 2.7 apresenta a função de cada um dos botões.

Saída do modo de depuração;

Executa o programa até um ponto de parada (breakpoint) ou o término do programa (tecla F5);

Executa o programa até o ponto em que se encontra o cursor;

Pula para o próximo comando (o atual é executado sem visualização no depurador) (tecla F10);

Executa o programa até o término da função atual (teclas SHIFT + F11);

Executa a próxima instrução ou comando (passo a passo) (tecla F11);

Executa a próxima instrução ou comando (se for uma chamada de função, ela é inteiramente executada e o controle retorna para a instrução seguinte à chamada);

Para a execução do programa;

Reset do processador.

Figura 2.7 – Botões de controle do depurador

Utilizando a execução passo a passo (tecla F10), podemos acompanhar exatamente o que ocorre com a CPU RL78 durante a execução dos comandos C ou das instruções assembly.

Observe que se a janela selecionada for a disassembly, a execução passo a passo do programa será feita instrução por instrução assembly. Se a janela selecionada for a do código fonte em C, a execução do programa será de comando por comando C.

Além de executar o programa é possível visualizar o estado dos registradores da CPU e dos periféricos, além do conteúdo das variáveis e da memória.

Para visualizar o conteúdo dos registradores é necessário selecionar a opção View > Register no menu principal. Isto fará com que a janela Register (figura 2.8) seja apresentada na tela.

A janela “Register” pode ser utilizada para visualizar e alterar o conteúdo tanto dos registradores da CPU (conforme mostra a figura 2.8) como de qualquer registrador de periféricos. Para selecionar o conjunto de registradores a ser apresentado, basta utilizar a caixa drop-down localizada no topo da janela.

Figura 2.8 – Janela de registradores

Seleção do conjunto de registradores a

ser visualizado

Contadores de ciclos

Microcontroladores RL78: Guia Básico 48

Agora que já vimos os procedimentos para execução do programa, o próximo passo é visualizarmos o conteúdo das variáveis. No presente caso, iremos nos limitar a visualizar as variáveis globais “temp” e “cnt”. Para isso, basta selecionar a opção View > Statics no menu principal, o que irá fazer com que a janela da figura 2.9A seja apresentada.

Figura 2.9A Figura 2.9B

Repare que estão listados outros símbolos globais, como os bytes de opção (option bytes) e a variável “temp”, que aparece na última linha. Também são apresentados os endereços onde os símbolos estão armazenados. No caso da variável “temp”, o endereço da mesma é 0xFEF00. Caso necessário, também é possível alterar o formato de visualização da variável, bastando clicar com o botão direito do mouse sobre a mesma e no menu flutuante selecionar a opção desejada (figura 2.9B).

Também é possível alterar o valor de qualquer variável, basta clicar sobre ela e digitar o novo valor seguido da tecla ENTER.

Uma outra possibilidade interessante é a janela de visualização em tempo real “Live Watch”, ela permite que se acompanhe a alteração do conteúdo das variáveis em tempo real, ou seja, durante a execução do programa. Selecionando a opção View > Live Watch no menu principal será apresentada uma janela similar a da figura 2.10A, onde podem ser inseridas as variáveis cujo conteúdo se deseja visualizar em tempo real.

Figura 2.10A Figura 2.10B

Por padrão, o conteúdo da janela “Live Watch” é atualizado a cada segundo (1000ms), mas este valor pode ser modificado na janela de opções da IDE (Tools > Options no menu principal). A figura 2.10B mostra esta janela e o campo para alteração do intervalo de atualização da janela “Live Watch”.

Outra característica importante é a criação de breakpoints (pontos de parada) que são utilizados para interromper a execução do programa. Os breakpoints permitem que o

Ferramentas de Programação 49

programador possa paralisar o programa em um determinado ponto ou no instante em que uma determinada condição ocorra (breakpoints condicionais).

Primeiramente, iremos criar um breakpoint de código, que consiste em marcar uma determinada linha de código ou um endereço de memória que ao ser atingido, a execução do programa é suspensa. Para fazer isso, basta um duplo-clique na área cinza que precede a linha de código na janela do código fonte.

A título de exemplo, sugerimos que se dê um duplo-clique na linha de programa indicada como breakpoint 1 na figura 2.11.

Ao fazer isso, surgirá um círculo vermelho em frente a linha, indicando que a mesma possui um breakpoint ativo.

Antes de prosseguirmos com os testes é interessante que o leitor habilite a janela de breakpoints, de forma a poder visualizar e selecionar os breakpoints marcados. Para fazer isso, basta selecionar a opção View > Breakpoints no menu principal.

Figura 2.11 – Breakpoints

Uma vez que tenha marcado o breakpoint e ativado a janela de breakpoints, a aparência do IDE deve ser aproximadamente igual a da figura 2.11.

Se o leitor desejar, poderá iniciar a execução do programa pressionando a tecla F5 e verá que o programa será executado até encontrar o ponto marcado como breakpoint 1 na figura 2.11.

Até aqui, nada mais fizemos do que criar breakpoints de código. No entanto, podemos adicionar inteligência ao mesmo: clique com o botão direito do mouse sobre a variável “temp” no código fonte, no menu que irá surgir (figura 2.12A), selecione a opção “Set Data Breakpoint for ‘temp’”. Um novo breakpoint será adicionado na janela de breakpoints (figura 2.12B).

Breakpoint 2 Breakpoint 1

Janela de breakpoints

Microcontroladores RL78: Guia Básico 50

Figura 2.12A Figura 2.12B Figura 2.12C

Clicando-se com o botão direito do mouse sobre o data breakpoint na janela de breakpoints e selecionando-se a opção “Edit” será apresentada a janela da figura 2.12C, na qual é possível preencher a condição desejada para que o programa seja interrompido (no caso o programa irá parar quando “temp” atingir o valor 10000).

Se o programa for executado (tecla F5), o leitor poderá observar que a execução será paralisada na linha do comando for e no mesmo instante, a janela de visualização das variáveis estáticas estará indicando que a variável “temp” possui o valor 10000, exatamente o que seria de se esperar. Desta forma, criamos um breakpoint condicional.

Finalmente é importante saber que é possível desabilitar temporariamente um breakpoint. Para isso, basta clicar sobre a marca em frente ao mesmo na janela de breakpoints. Um breakpoint desabilitado é representado como um círculo vermelho preenchido de branco.

Uma característica interessante do simulador é a disponibilidade de dois contadores de ciclos (CCTIMER1 e CCTIMER2), que podem ser utilizados para se efetuar medições do tempo de execução do programa ou de trechos do mesmo, inclusive com a possibilidade de alterar o conteúdo dos mesmos de forma a facilitar as medições. Estes contadores estão disponíveis na janela de visualização de registradores da CPU do simulador.

As figuras 2.13 e 2.14 demonstram a utilização do contador de ciclos para medição do intervalo de tempo transcorrido durante uma chamada à função atraso no nosso programa exemplo.

Na figura 2.13, o CCTIMER1 foi zerado manualmente antes de executar o comando for.

Figura 2.13

A figura 2.14 mostra o conteúdo do CCTIMER1 após a execução do laço for. Observe que o conteúdo do mesmo é apresentado em vermelho, indicando que o mesmo foi alterado desde o último comando do depurador.

Ferramentas de Programação 51

Figura 2.14

Observando o conteúdo do CCTIMER1 e conhecendo o clock da CPU, podemos facilmente determinar o tempo total de execução da função. Supondo que a CPU estivesse operando a 32MHz, este tempo seria 1/32MHz * 1965555 = 61,42 ms.

2.1.3. Depurando um Programa

Os procedimentos para depuração de um programa utilizando o TK (integrado em diversos kits da Renesas) ou um depurador externo como o E1 ou E20 são praticamente idênticos aos descritos para a simulação do programa.

Primeiramente é importante alterar as configurações do projeto, especialmente a seleção do driver de depuração. A seleção é realizada na janela de opções do projeto, na categoria Debugger conforme mostra a figura 2.15A).

Uma vez selecionado o driver de depuração adequado é necessário configurar as opções de download (figura 2.15B): a opção “Suppress” permite iniciar a depuração sem que se altere a memória flash do microcontrolador. A opção “Verify” permite que o código seja programado e verificado na memória do chip.

Figura 2.15A Figura 2.15B

A primeira sessão de depuração do projeto irá apresentar a janela da figura 2.16. Ao clicar no botão OK, a janela de configuração do depurador (figura 2.17) será apresentada.

Figura 2.16

Microcontroladores RL78: Guia Básico 52

Nesta janela é possível configurar diversas opções do depurador, incluindo o código de identificação (ID code), clock principal e auxiliar, parada dos periféricos ao parar o programa, distribuição de memória no chip, etc.

Figura 2.17

Os procedimentos já vistos para o simulador podem também ser aplicados ao depurador in circuit (inclusive a janela de visualização em tempo real “Live Watch”).

Atenção: caso uma gravação em andamento tenha sido interrompida ou tenha sido gravado valores incorretos nos bytes de opção, é possível que o depurador não consiga reprogramar a memória flash do microcontrolador. Neste caso, uma possível solução é utilizar software Renesas Flash Programmer (RFP) e realizar o apagamento da memória do chip. Este programa pode ser baixado no seguinte endereço: http://am.renesas.com/products/tools/flash_prom_programming/rfp/ index.jsp . Para download é necessário preencher um simples cadastro (gratuito) no site. Este cadastro também permite acesso a outros documentos e arquivos disponíveis no site da Renesas.

2.1.4. Gerando o Código Final

Uma vez que a aplicação tenha sido completamente testada e esteja operando dentro das especificações do projeto, é necessário gerar um arquivo para gravação do microcontrolador.

Apesar de ser tentador utilizar o programa gravado na memória do chip através de uma sessão de depuração (no modo “Debug”), é importante ressaltar que o programa gravado desta forma irá manter o depurador interno (OCD) ativado, fazendo com que a quantidade de energia consumida pelo chip seja maior, especialmente nos modos halt e stop.

Por isso, é importante gerar um arquivo (normalmente do tipo Intel .hex) para gravação através de uma ferramenta como o Renesas Flash Programmer (RFP).

A configuração do projeto em modo “Release” deve seguir todos os passos já mostrados para o projeto em modo “Debug”, com exceção das opções do linker, especialmente a geração do

Ferramentas de Programação 53

arquivo de saída (aba Output), que deverá ser configurada para “Other” e selecionado o formato “intel-extended”. Na aba “Extra Output” deverá ser marcada a opção “Generate extra output file” e “Override default”. O nome do arquivo poderá então ser configurado pelo programador, não esquecendo de utilizar a extensão “.hex”.

Figura 2.18A Figura 2.18B

Microcontroladores RL78: Guia Básico 54

Arquitetura e Modelo de Programação 55

3

Arquitetura e Modelo de Programação 3. Arquitetura e Modelo de Programação

Como já dissemos na parte introdutória deste livro, os microcontroladores RL78 utilizam uma CPU CISC de 16 bits capaz de operar a até 32MHz. Neste capítulo iremos estudar em maiores detalhes as principais características da CPU RL78, bem como o seu modelo de programação e modos de operação.

3.1. A CPU RL78

A linha de microcontroladores RL78 utiliza uma CPU derivada da linha 78K0R (inicialmente desenvolvida pela NEC). Os RL78 utilizam a mesma estrutura de registradores, conjunto de instruções, modos de operação e mapas de memória da linha 78K0R.

A CPU utiliza a arquitetura Von Neumann modificada, com um mapa de memória unificado para dados e programa, mas utilizando barramentos de acesso distintos, permitindo que ocorram operações simultâneas de busca de instrução (na flash) e leitura/escrita da dados (na RAM).

O modelo de programação da CPU RL78 é baseado num conjunto de 4 bancos de 8 registradores de uso geral da CPU, cada um com capacidade de 8 bits. Diversas instruções permitem também tratar conjuntos de dois registradores como um único registrador de 16 bits.

Os registradores de propósitos gerais da CPU são batizados de X, A, B, C, D, E, H e L, ou ainda R0 a R7. Os conjuntos de 16 bits são batizados de AX, BC, DE e HL, ou ainda RP0 a RP3.

O leitor mais experiente poderá perceber alguma similaridade entre o modelo de programação da CPU RL78/78K0R e outros microprocessadores mais antigos, como o Zilog Z80 e inclusive o Intel 8080. Esta similaridade não é mera coincidência, pois a linha 78K0 foi projetada pela NEC utilizando como base o modelo de programação (registradores e conjunto básico de instruções) do Z80 (originado do 8080). Posteriormente, a NEC aprimorou a CPU 78K0 de 8 bits e lançou a linha 78K0R de 16 bits!

Outra característica interessante é que os registradores de uso geral mencionados acima estão mapeados na memória RAM do chip, o que permite uma enorme flexibilidade ao programador, sendo possível inclusive acessá-los através de ponteiros em C!

A existência de quatro conjuntos ou bancos de registradores também é uma característica importante, pois permite trocas de contexto extremamente rápidas (uma troca de contexto típica é a que ocorre na alternância entre o processamento de programa e o processamento de uma interrupção).

Em arquiteturas tradicionais (com apenas um conjunto de registradores da CPU), quando ocorre uma interrupção, é necessário salvar os registradores da CPU na pilha, antes de se realizar

Microcontroladores RL78: Guia Básico 56

o tratamento da interrupção. Ao final do tratamento da interrupção, é necessário restaurar o estado dos registradores da CPU antes de retornar ao programa principal. Todas estas operações consomem tempo precioso da CPU.

Nos RL78, basta utilizar um banco de registradores para o processamento do programa e outros bancos para as interrupções. Basicamente, o único registrador da CPU que ainda precisará ser preservado na pilha é o PSW (dependendo da complexidade do programa, outros podem necessitar ser preservados na pilha também).

A tabela 3.1 mostra os registradores de uso geral da CPU, bem como a organização dos bancos e os endereços absolutos de memória onde os mesmos estão mapeados.

Registradores Endereço na RAM

16 bits 8 bits Banco 0 Banco 1 Banco 2 Banco 3 H (R7) 0xFFEFF 0xFFEF7 0xFFEEF 0xFFEE7

HL (RP3) L (R6) 0xFFEFE 0xFFEF6 0xFFEEE 0xFFEE6

D (R5) 0xFFEFD 0xFFEF5 0xFFEED 0xFFEE5 DE (RP2)

E (R4) 0xFFEFC 0xFFEF4 0xFFEEC 0xFFEE4

B (R3) 0xFFEFB 0xFFEF3 0xFFEEB 0xFFEE3 BC (RP1)

C (R2) 0xFFEFA 0xFFEF2 0xFFEEA 0xFFEE2

A (R1) 0xFFEF9 0xFFEF1 0xFFEE9 0xFFEE1 AX (RP0)

X (R0) 0xFFEF8 0xFFEF0 0xFFEE8 0xFFEE0

Tabela 3.1

3.1.1. Registradores Especiais da CPU

Além dos registradores de uso geral, a CPU dos RL78 inclui outros registradores especiais:

• Program Status Word (PSW), de 8 bits, e que é utilizado para armazenar bits de estado da CPU;

• Program Counter (PC), de 20 bits, e que é utilizado para indicar o endereço da próxima instrução a ser executada;

• Stack Pointer (SP), de 16 bits, e que aponta o topo da pilha de memória;

• Extra Segment (ES), de 8 bits, e que armazena os 4 bits mais significativos utilizados por algumas instruções no acesso aos dados (endereços de 20 bits);

• Code Segment (CS), de 8 bits, e que armazena os 4 bits mais significativos utilizados em algumas instruções de desvio ou chamada de sub-rotina;

• Processor Mode Control (PMC), de 8 bits, e que controla o espelhamento de memória disponível em alguns modelos.

Assim como os registradores de uso geral da CPU, os registradores especiais também estão mapeados na memória RAM do chip. A tabela 3.2 mostra o endereço de cada um deles (SPL é o byte menos significativo do SP e SPH é o byte mais significativo do SP).

Arquitetura e Modelo de Programação 57

Endereço Registrador

0xFFFF8 SPL

0xFFFF9 SPH

0xFFFFA PSW

0xFFFFB Reservado

0xFFFFC CS

0xFFFFD ES

0xFFFFE PMC

Tabela 3.2

Adicionalmente, os microcontroladores da linha RL78/G14 incluem um registrador acumulador de 32 bits (MACR) utilizado pelas instrução de multiplicação e acúmulo MACH e MACHU. O registrador MACR também está mapeado na área de SFRs nos endereços 0xFFFF0 (MACRL, que guarda os 16 bits inferiores do MACR) e 0xFFFF2 (MACRH, que guarda os 16 bits superiores do MACR).

3.1.1.1. Registrador PSW

O registrador PSW contém alguns importantes bits de controle da CPU RL78. Nele estão localizados os sinalizadores ou flags da ULA (Unidade Lógica e Aritmética), os bits de seleção do banco de registradores de uso geral e os bits de controle do sistema de interrupção.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita IE Z RBS1 AC RBS0 ISP1 ISP0 CY

PSW

Reset 0 0 0 0 0 1 1 0

Primeiramente vejamos a função dos bits Z, AC e CY, relacionados à ULA:

Z – indicador de zero. Este bit é setado quando determinadas operações resultam em um valor igual a zero.

AC – transporte auxiliar (auxiliary carry). O transporte auxiliar, nas operações de adição, quando setado, indica que houve transporte do bit 3 para o bit 4 do resultado. Nas operações de subtração, quando setado, indica que houve empréstimo do bit 4 para o bit 3.

CY – transporte (carry). Ele é setado quando ocorre transporte nas operações de adição ou empréstimo nas operações de subtração. Nas operações de rotação e deslocamento de bits, ele recebe o bit deslocado para fora do registrador. Também pode atuar como um acumulador de bit em algumas operações de manipulação de bits.

Os bits RBS1 e RBS0 selecionam o banco de registradores a ser utilizado. A tabela 3.3 mostra as configurações possíveis.

Microcontroladores RL78: Guia Básico 58

RBS1 RBS0 Banco

0 0 0

0 1 1

1 0 2

1 1 3

Tabela 3.3

Apesar de ser possível alterar estes bits através de operações de escrita, tanto no registrador PSW quanto no endereço de memória 0xFFFFA, os RL78 possuem uma instrução assembly específica para modificar estes bits: SEL RBx, onde x é o número do banco (0 a 3).

Finalmente, temos os 3 bits relacionados ao sistema de interrupções dos RL78: IE, ISP1 e ISP0.

O bit IE é o controle global de interrupções, quando IE = 0, as interrupções (exceto as não mascaráveis) estão desabilitadas ao passo que quando IE = 1, todas as interrupções estão habilitadas. Os RL78 possuem duas instruções especiais para manipular o bit IE: DI (Disable Interrupts), que faz IE = 0 e EI (Enable Interrupts) que faz IE = 1.

Os bits ISP1 e ISP0 controlam a prioridade atual de interrupção. O sistema de interrupções dos RL78 possui 4 níveis de prioridade (0 a 3), sendo o nível 0 o de maior prioridade e 3 o de menor prioridade. A disponibilidade de um sistema com quatro níveis de prioridade significa que é possível configurar prioridades diferentes para cada fonte de interrupção e, além disso, é possível que uma interrupção de mais alta prioridade interrompa uma interrupção de menor prioridade que se encontre em tratamento. Veremos mais detalhes sobre o sistema de interrupções dos RL78 no capítulo 6.

3.1.1.2. Registrador PC

O PC (Program Counter) indica o endereço na memória onde está localizada a próxima instrução a ser executada.

Nos RL78 o PC possui um tamanho de 20 bits e não pode ser acessado diretamente pelo usuário.

Após um reset, o registrador PC é carregado com o conteúdo do vetor de reset (endereços 0x00000 e 0x00001 da memória).

3.1.1.3. Registrador SP

O apontador da pilha (SP) indica o topo da pilha de software, uma estrutura de dados utilizada para armazenamento de endereços de retorno das sub-rotinas, funções e interrupções, além de permitir também o armazenamento de dados (as variáveis locais de uma função C são armazenadas na pilha).

O registrador SP possui largura de 16 bits, o que significa que a pilha está limitada a um tamanho máximo de 65536 bytes, o que não constitui nenhuma limitação séria, já que o RL78 mais poderoso até o momento possui 32KiB de memória RAM. O registrador SP é internamente

Arquitetura e Modelo de Programação 59

dividido em dois bytes, sendo o SPH a parte alta do SP e SPL a parte baixa do SP (veja a tabela 3.2).

Outra característica da pilha dos RL78 é que ela possui alinhamento par e o bit menos significativo do SP é sempre mantido em 0. Isso significa que não é possível guardar bytes na pilha, apenas words de 16 bits.

Além disso, a pilha cresce para baixo, ou seja, a cada word armazenada na pilha, o SP é decrementado em 2.

Observe que o SP aponta sempre para endereços de oito bits na memória RAM, por isso, após salvar uma word (2 bytes) na pilha, o SP é decrementado em 2!

A tabela 3.4 demonstra o comportamento do SP e a utilização da pilha em todos os casos possíveis.

Endereço da Pilha PUSH AX PUSH PSW CALL/CALLT Interrupções/BRK

SP

SP-1 A PSW 0x00 PSW

SP-2 X 0x00 PC19-PC16 PC19-PC16

SP-3 PC15-PC8 PC15-PC8

SP-4 PC7-PC0 PC7-PC0

Tabela 3.4

O primeiro caso (PUSH AX) demonstra o empilhamento de dados. A instrução assembly PUSH permite salvar um par de registradores (AX, BC, DE ou HL) na pilha. Nestes casos, primeiramente é salvo o registrador mais significativo (A, B, D ou H) no endereço SP-1 e em seguida o registrador menos significativo (X, C, E, ou L) é salvo no endereço SP-2, que passa a ser o novo topo da pilha.

No segundo caso (PUSH PSW), o conteúdo do registrador PSW é salvo na posição indicada por SP-1 e o valor zero é salvo na posição SP-2, que passa a ser o novo topo da pilha.

O terceiro caso demonstra a utilização da pilha em uma chamada de sub-rotina ou função utilizando as instruções assembly CALL ou CALLT. A primeira posição da pilha recebe o valor zero, e as posições seguintes recebem o valor do PC (que aponta a instrução seguinte ao CALL/CALLT) dividido em três bytes: em os bits 19 a 16 do PC são salvos em SP-2, os bits 15 a 8 do PC são salvos em SP-3 e os bits 7 a 0 do PC são salvos em SP-4, que passa a ser o novo topo da pilha.

O quarto exemplo demonstra a utilização da pilha num evento de interrupção ou execução de uma instrução BRK (que é uma interrupção por software). A pilha é utilizada de forma muito semelhante ao terceiro caso, porém, o PSW é salvo na primeira posição (o PSW é sempre preservado na pilha numa interrupção).

Após um reset o conteúdo do registrador SP é indeterminado e por isso ele deve ser inicializado para apontar para uma área válida de memória RAM antes que se utilizem interrupções ou chamadas de sub-rotina/função! Esta inicialização é feita automaticamente pelos compiladores C.

Microcontroladores RL78: Guia Básico 60

3.1.1.4. Registradores ES e CS

Os registradores ES e CS são utilizados para auxiliar no endereçamento de dados (ES) e programa (CS). Ambos atuam como complemento para formar endereços de 20 bits, necessários para acessar toda a faixa de 1MiB de memória dos RL78.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 ES3 ES2 ES1 ES0

ES

Reset 0 0 0 0 1 1 1 1

Nos RL78, as instruções que acessam a memória para ler escrever dados estão normalmente restritas a operar na faixa de endereços entre 0xF0000 e 0xFFFFF. A existência do registrador ES e de um modo de endereçamento especial permite que as instruções utilizem dados localizados em qualquer endereço de memória, esta funcionalidade é utilizada principalmente na leitura de constantes armazenadas nas áreas de memória flash.

Já o registrador CS é utilizado para endereçamento de programa. Como o PC dos RL78 possui 20 bits, mas a maioria das instruções de desvio utilizam operandos de 16 bits, é necessário utilizar o registrador CS para se ter acesso a toda a faixa de 1MiB de memória dos RL78.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 CS3 CS2 CS1 CS0

CS

Reset 0 0 0 0 0 0 0 0

3.1.1.5. Registrador PMC

O registrador PMC (Processor Mode Control) é utilizado para controlar o espelhamento da primeira faixa de 64KiB de memória dos RL78.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 0 0 MAA

PMC

Reset 0 0 0 0 0 0 0 0

Nos RL78/G12, G13, G14 e G1A, quando o bit MAA está setado, o bloco de 64KiB compreendido entre 0x00000 e 0x0FFFF é espelhado na faixa compreendida entre 0xF0000 e 0xFFFFF. Isto permite que se acesse dados constantes (armazenados em flash) e dados da RAM no mesmo banco de memória. Quando MAA=0, a faixa entre 0x10000 e 0x1FFFF é espelhada na região entre 0xF0000 e 0xFFFFF.

Note que, como veremos mais adiante, a memória RAM e os registradores SFR dos RL78 também estão localizados na faixa de endereços entre 0xF0000 e 0xFFFFF. Neste caso, os endereços com RAM/SFR possuem preferência e irão manter esta funcionalidade. Apenas os endereços não implementados nesta área é que poderão acessar a área espelhada.

Arquitetura e Modelo de Programação 61

Uma particularidade deste registrador é que ele somente pode deve ser modificado uma única vez e na inicialização do programa, além disso, após setado o bit MAA, é necessário esperar um ciclo de clock antes de se acessar a área espelhada.

3.1.2. Mapa de Memória

Como já vimos, os microcontroladores RL78 possuem um espaço de endereçamento de 1MiB. Este espaço é compartilhado por memória flash, RAM e registradores SFR. A figura 3.1 mostra o mapa de memória simplificado para alguns modelos de RL78 (G12 com 4KiB de flash, G13 com 64KiB de flash e G13 com 512KiB de flash).

R5F10267/10277/102A7 R5F100xE R5F100xL 0xFFFFF

0xFFF00

Registradores de funções especiais SFR (256 bytes)

Registradores de funções especiais SFR (256 bytes)

Registradores de funções especiais SFR (256 bytes)

0xFFEFF

0xFFEE0

Registradores de propósito geral (32 bytes)

Registradores de propósito geral (32 bytes)

Registradores de propósito geral (32 bytes)

0xFFEDF

0xFFD00 RAM (512 bytes)

0xFFCFF

0xFEF00

RAM (4KiB)

0xFEEFF

0xF7F00

RAM (32KiB)

0xF7EFF

0xF3000 Espelhamento (19,75KiB)

0xF2FFF

0xF2000

Espelhamento (51,75KiB)

0xF1FFF

0xF1800

Área reservada

0xF17FF

0xF1000 Dataflash (2KiB)

Dataflash (4KiB) Dataflash (8KiB)

0xF0FFF

0xF0800 Área reservada Área reservada Área reservada

0xF07FF

0xF0000

Registradores de funções especiais SFR (2KiB)

Registradores de funções especiais SFR (2KiB)

Registradores de funções especiais SFR (2KiB)

0xEFFFF

0x80000 Área reservada

0x7FFFF

0x10000

Área reservada

0x0FFFF

0x01000

Área reservada

0x00FFF

0x00000 Memória flash (4KiB)

Memória flash (64KiB) Memória flash (512KiB)

Figura 3.1

Podemos perceber que os endereços iniciais da memória são ocupados pela memória flash, onde é armazenado o programa a ser executado. Esta área de memória varia de 2KiB (no menor RL78) a 512KiB. Observe que, para efeitos de apagamento, a memória flash é organizada em blocos de 1KiB (não é possível apagar áreas menores que 1KiB). A função de apagamento FSL_Erase(), parte da biblioteca FSL de manipulação da memória flash, utiliza como parâmetro o número do bloco de memória, conforme a figura 3.2.

Podemos facilmente calcular o número de qualquer bloco a partir de um endereço, utilizando-se a fórmula (apenas a parte inteira do resultado deve ser utilizada):

1024

EndereçoNBLOCO = ou

400x0

)hex(Endereço)hex(N BLOCO =

Após a área de memória flash encontra-se uma área reservada e não implementada, por esta razão não é permitido acessar esta faixa de endereços para nenhum propósito (operações de

Microcontroladores RL78: Guia Básico 62

leitura ou escrita nestas áreas podem provocar um reset por acesso ilegal à memória (IAW) caso o bit IAWEN esteja setado no registrador IAWCTL ou quando o watchdog está ativado).

0x7FFFF

0x7FC00 Bloco 511 0x7FBFF

0x7F800 Bloco 510 0x7F7FF

0x7F400 Bloco 509 0x7F3FF

0x7F000 Bloco 508

...

0x01FFF

0x01C00 Bloco 7 0x01BFF

0x01800 Bloco 6 0x017FF

0x01400 Bloco 5 0x013FF

0x01000 Bloco 4 0x00FFF

0x00C00 Bloco 3 0x00BFF

0x00800 Bloco 2 0x007FF

0x00400 Bloco 1 0x003FF

0x00000 Bloco 0

Figura 3.2

A faixa de endereços entre 0xEF000 e 0xEFFFF não é implementada do ponto de vista do usuário, mas contém memória ROM com código utilizado pelas bibliotecas de escrita na flash (FSL e FDL). Por esta razão, a execução de código nesta área não gera um reset IAW.

Em seguida temos uma das áreas dedicadas aos registradores de funções especiais (SFR), que controlam os periféricos e algumas funcionalidades dos microcontroladores RL78. Esta área é seguida por outra faixa de endereços não implementados (reservados).

A área seguinte é a dataflash. Esta área de memória (opcional, conforme o modelo de microcontrolador utilizado) é destinada exclusivamente ao armazenamento de dados não voláteis, ou seja, dados que devem ser mantidos mesmo quando o microcontrolador é desligado (por exemplo, senhas, configurações, etc.).

A área de dataflash difere da área de flash normal principalmente por utilizar um barramento de acesso exclusivo. Isto permite que se realizem operações na dataflash em paralelo com o acesso a memória flash de código.

Nos modelos em que a memória dataflash não está presente, esta área de memória é reservada e não deve ser utilizada (conforme já dito para as demais áreas reservadas).

Seguindo a área de dataflash encontramos (nos modelos com 12KiB ou mais de memória flash) a área de espelhamento de memória. Já vimos a finalidade e forma de utilização do espelhamento de memória no tópico 3.1.1.5, quando estudamos o registrador PMC.

No topo da faixa de endereçamento encontramos a área de memória RAM, os registradores de propósito geral (GPRs), que são os registradores da CPU mapeados na memória RAM e outra área de registradores de funções especiais (SFR).

Arquitetura e Modelo de Programação 63

Uma característica interessante acerca dos RL78 é que os primeiros 4KiB da memória flash são ocupados por uma série de elementos conforme mostra a figura 3.3. Os primeiros 206 bytes são ocupados pelos vetores de interrupção (64 vetores de 16 bits), tabela de endereços de CALLT (32 endereços de 16 bits), bytes de opção e código de segurança. Isto significa que na prática, um microcontrolador de 4KiB possui apenas 3890 bytes de área útil para código.

0x00FFF

0x000CE

Área de programa 0x000CD

0x000C4

Área de código de segurança (Security ID) (10 bytes) 0x000C3

0x000C0 Área de bytes de opção (4 bytes)

0x000BF

0x00080

Área de tabela CALLT (64 bytes) 0x0007F

0x00000 Área de Vetores de Interrupção (128 bytes)

Figura 3.3

Este bloco inicial de 4KiB é chamado de bloco de boot e em microcontroladores com 16KiB ou mais de flash, podem existir dois blocos de boot: o primeiro localizado nos endereços mostrados na figura 3.3 e o segundo no bloco de 4KiB imediatamente posterior (endereços 0x01000 a 0x01FFF). A existência de dois blocos de boot permite que a aplicação possa alterar um bloco de boot com total segurança, resistindo inclusive a falhas de alimentação durante a operação de gravação do novo bloco de boot (esta funcionalidade é extremamente útil em boot loaders).

A funcionalidade de bloco duplo de boot é utilizada através da função FSL_InvertBootFlag() que inverte o sinalizador que identifica o bloco de boot atual. Desta forma, supondo uma atualização de firmware em campo, o boot loader pode escrever o novo código de boot no bloco de boot 1 e somente após completar e verificar a gravação de todo o bloco de boot 1 é que a função FSL_InvertBootFlag() é chamada, invertendo o flag de bloco de boot ativo e selecionando o bloco 1 para o boot. Na próxima atualização o boot loader irá modificar o bloco de boot 0, mantendo o bloco 1 totalmente operacional.

3.1.3. Modos de Endereçamento

A CPU RL78 suporta diversos modos de endereçamento. Estão disponíveis praticamente todos os principais modos de endereçamento encontrados nas CPUs RISC/CISC atuais (quatro modos para programa e oito para dados).

Os modos de endereçamento de código (utilizados nos desvios e chamadas de sub-rotinas ou funções) incluem:

1. Endereçamento relativo de 8 ou 16 bits: neste modo o valor do operando (em complemento de dois) é somado ao PC, de forma a obter o endereço de destino do programa;

2. Endereçamento absoluto de 16 ou 20 bits: o endereço do operando é utilizado como destino do desvio/chamada. Operandos de 16 bits devem ser precedidos do símbolo “!” e operandos de 20 bits devem ser precedidos do símbolo “!!”. Endereços de 16 bits estão limitados sempre aos primeiros 64KiB de memória;

Microcontroladores RL78: Guia Básico 64

3. Endereçamento de tabela CALLT: neste modo utiliza-se um operando de 5 bits para especificar uma das 32 posições da tabela de saltos CALLT localizada na área entre 0x00080 e 0x000BF. Isto permite chamar funções na faixa de endereços de 0x00000 a 0x0FFFF utilizando instruções CALLT com tamanho de apenas 2 bytes, reduzindo o tamanho final do código;

4. Endereçamento por registrador: o conteúdo de um dos pares de registradores (AX, BC, DE ou HL) é utilizado em conjunto com o registrador CS para formar o endereço de destino de 20 bits.

Os modos de endereçamento de dados são os seguintes:

1. Implícito: o operando não está escrito com o opcode mas está implícito no mesmo;

2. Registrador: o operando é um dos registradores de 8 ou de 16 bits;

3. Direto: o operando é uma posição de memória especificada pelo operando de 16 bits (endereços entre 0xF0000 e 0xFFFFF) ou em qualquer posição da memória (com o uso do registrador ES);

4. Endereçamento rápido (short): o operando de 8 bits especifica um endereço na faixa entre 0xFFE20 e 0xFFF1F. Este modo permite um rápido acesso a uma pequena porção da RAM, aos GPRs e uma parte dos SFRs;

5. Endereçamento SFR: o operando de 8 bits especifica um endereço na faixa entre 0xFFF00 e 0xFFFFF (uma das áreas dos SFR). Este modo permite um rápido acesso aos principais SFRs do microcontrolador;

6. Endereçamento indireto por registrador: o par de registradores especificado pelo operando (DE ou HL) contém o endereço do operando. Este modo comporta-se exatamente como os ponteiros em C. A faixa de memória endereçável é aquela entre os endereços 0xF0000 e 0xFFFFF, ou qualquer área de memória (com o uso do registrador ES);

7. Endereçamento de base (base address): neste modo um par de registradores (normalmente BC, DE, HL ou SP) fornece o endereço base e um valor imediato de 8 ou 16 bits fornece o deslocamento. A soma do endereço base mais o deslocamento fornece o endereço do dado. Este modo permite acesso aos dados salvos na pilha (como por exemplo as variáveis locais em funções C), além de permitir também operações com outras estruturas de dados (como arrays);

8. Endereçamento de base indexado: este modo é semelhante ao anterior, mas o par de registradores HL fornece o endereço base e os registradores B ou C fornecem o índice. O endereço do dado é obtido pela soma da base mais o índice (é possível utilizar o registrador ES para cobrir toda a faixa de memória);

De maneira geral, podemos dizer que o modo de endereçamento rápido (short) é o mais rápido para acesso à memória RAM do microcontrolador (já que o tamanho total da instrução é menor que nos demais modos). Por isso, sempre que possível, devemos manter as variáveis mais utilizadas na área compreendida entre os endereços 0xFFE20 e 0xFFEDF. Podemos utilizar o modificador __saddr para forçar o compilador IAR a armazenar uma ou mais variáveis nesta área da RAM.

Arquitetura e Modelo de Programação 65

3.2. Conjunto de Instruções Assembly

O conjunto de instruções dos RL78 é bastante poderoso e constitui, sem dúvidas, uma das grandes qualidades desta linha de microcontroladores. O conjunto de instruções é enxuto (81 instruções) quando comparado a outras máquinas CISC, mas é muito poderoso, com diversos recursos interessantes como: suporte a dados de 8 ou 16 bits, suporte a operações com 1 bit, instruções DSP (somente nos RL78/G14), diversos tipos de desvios relativos, absolutos, condicionais e incondicionais e tabela de desvios (CALLT).

Outra característica interessante é a presença de instruções de pulo condicional, que executam ou não a próxima instrução baseadas em algumas condições. Este tipo de instrução é comum em máquinas RISC, mas incomum em máquinas CISC.

Também está presente a instrução BTCLR (testa e, caso verdadeiro, apaga e desvia), que é especialmente útil em operações atômicas envolvendo semáforos.

Para facilitar o estudo do conjunto de instruções dos RL78, vamos dividí-lo em algumas categorias, conforme o tipo de operação realizada pela instrução.

3.2.1. Instruções de Manipulação de Dados

Permitem manipular dados, ou seja, transferir informação para os registradores do microcontrolador e entre os registradores e a memória.

MOV dst,fnt – copia um dado de 8 bits especificado pelo operando fonte (fnt) para o destino especificado (dst). Os flags do PSW não são alterados.

MOVW dst,fnt – copia um dado de 16 bits especificado pelo operando fonte (fnt) para o destino especificado (dst). Os flags do PSW não são alterados. Esta instrução pode ser utilizada para inicializar o SP com um valor imediato ou com o valor de AX e também pode ser utilizada para copiar SP para um dos pares de registradores (AX, BC, DE ou HL).

MOVS [HL+dsl],X ou MOVS ES:[HL+dsl],X– copia um dado de 8 bits especificado pelo operando fonte (registrador X) para o destino especificado (conteúdo de HL mais deslocamento dsl, opcionalmente com o uso do ES), altera os bits Z e CY no PSW de acordo com o resultado da operação.

XCH dst,fnt – permuta o conteúdo de 8 bits do operando fonte especificado (fnt) pelo conteúdo do operando destino (dst). Os flags do PSW não são alterados.

XCHW AX,fnt – permuta o conteúdo de 16 bits do operando fonte especificado (fnt) pelo conteúdo do operando destino (registrador AX). Os flags do PSW não são alterados.

ONEB dst – o operando especificado por dst recebe o valor 0x01. Os flags do PSW não são alterados.

ONEW dst – o operando especificado por dst recebe o valor 0x0001. Os flags do PSW não são alterados.

CLRB dst – o operando especificado por dst recebe o valor 0x00. Os flags do PSW não são alterados.

Microcontroladores RL78: Guia Básico 66

CLRW dst – o operando especificado por dst recebe o valor 0x0000. Os flags do PSW não são alterados.

3.2.2. Instruções Aritméticas, Lógicas e de Comparação

São as instruções utilizadas para efetuar cálculos (basicamente adição, subtração e multiplicação) de 8 ou 16 bits, além de operações lógicas bit a bit (AND, OR e XOR) e também a comparação de dados (comparação entre variáveis e de variáveis com zero). Os microcontroladores da linha G14 incluem também instruções DSP (multiplicação, divisão e multiplicação e acúmulo).

ADD dst,fnt – adiciona o conteúdo de 8 bits do operando fonte (fnt) ao conteúdo do operando de destino (dst). O resultado é armazenado no destino. Os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se o resultado é zero, CY é setado se o resultado é maior que 255 e AC é setado se houve transporte do bit 3 para o bit 4 na operação, nos demais casos os flags são apagados).

ADDC dst,fnt – adiciona o conteúdo de 8 bits do operando fonte (fnt) ao conteúdo do operando de destino (dst) mais o carry (CY). O resultado é armazenado no destino. Os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se o resultado é zero, CY é setado se o resultado é maior que 255 e AC é setado se houve transporte do bit 3 para o bit 4 na operação, nos demais casos os flags são apagados).

ADDW dst,fnt – adiciona o conteúdo de 16 bits do operando fonte (fnt) ao conteúdo do operando de destino (dst). O resultado é armazenado no destino. Os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se o resultado é zero, CY é setado se o resultado é maior que 65535, nos demais casos os flags são apagados, AC é indefinido). No caso especial onde dst é o registrador SP, o operando fnt somente pode ser um valor imediato de 8 bits e o PSW não é alterado.

SUB dst,fnt – subtrai o conteúdo de 8 bits do operando fonte (fnt) do conteúdo do operando de destino (dst). O resultado é armazenado no destino. Os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se o resultado é zero, CY é setado se houve empréstimo (dst era menor que fnt) e AC é setado se houve transporte do bit 3 para o bit 4 na operação, nos demais casos os flags são apagados).

SUBC dst,fnt – subtrai o conteúdo de 8 bits do operando fonte (fnt) e do carry (CY) do conteúdo do operando de destino (dst). O resultado é armazenado no destino. Os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se o resultado é zero, CY é setado se houve empréstimo (dst era menor que fnt) e AC é setado se houve empréstimo do bit 4 para o bit 3 na operação, nos demais casos os flags são apagados).

SUBW dst,fnt – subtrai o conteúdo de 16 bits do operando fonte (fnt) do conteúdo do operando de destino (dst). O resultado é armazenado no destino. Os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se o resultado é zero, CY é setado se houve empréstimo (dst era menor que fnt), nos demais casos os flags são apagados, AC é indefinido). No caso especial onde dst é o registrador SP, o operando fnt somente pode ser um valor imediato de 8 bits e o PSW não é alterado.

Arquitetura e Modelo de Programação 67

MULU X – multiplicação sem sinal de 8 bits do conteúdo do registrador X pelo conteúdo do registrador A, armazenando o resultado de 16 bits em AX. Os flags do PSW não são alterados.

AND dst,fnt – realiza a operação lógica AND entre os 8 bits do operando fonte (fnt) e os 8 bits do operando destino (dst), armazenando o resultado no destino. O bit Z no PSW é alterado (setado se o resultado for zero, caso contrário é apagado).

OR dst,fnt – realiza a operação lógica OR entre os 8 bits do operando fonte (fnt) e os 8 bits do operando destino (dst), armazenando o resultado no destino. O bit Z no PSW é alterado (setado se o resultado for zero, caso contrário é apagado).

XOR dst,fnt – realiza a operação lógica XOR entre os 8 bits do operando fonte (fnt) e os 8 bits do operando destino (dst), armazenando o resultado no destino. O bit Z no PSW é alterado (setado se o resultado for zero, caso contrário é apagado).

CMP dst,fnt – compara o conteúdo de 8 bits do operando fonte (fnt) com o conteúdo do operando destino (dst), subtraindo fnt de dst. O resultado é descartado e os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se os dois valores são iguais, CY é setado se dst é menor que fnt e AC é setado se houve empréstimo do bit 4 para o bit 3 na operação, nos demais casos os flags são apagados).

CMP0 dst – compara o conteúdo de 8 bits do operando destino (dst) com zero, subtraindo 0 de dst. O resultado é descartado e os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se dst é igual a zero, CY é setado se dst é menor que zero e AC é setado se houve empréstimo do bit 4 para o bit 3 na operação, nos demais casos os flags são apagados).

CMPS dst,fnt – compara o conteúdo de 8 bits do operando fonte (fnt) com o conteúdo do operando destino (dst), subtraindo fnt de dst. O resultado é descartado e os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se os dois valores são iguais, CY é setado se A=0, X=0 ou se os valores são diferentes e AC é setado se houve empréstimo do bit 4 para o bit 3 na operação, nos demais casos os flags são apagados).

CMPW dst,fnt – compara o conteúdo de 16 bits do operando fonte (fnt) com o conteúdo do operando destino (dst), subtraindo fnt de dst. Os bits Z, CY e AC no PSW são alterados de acordo com o resultado da operação (Z é setado se os dois valores são iguais, CY é setado se dst é menor que, nos demais casos os flags são apagados, AC é indefinido).

Instruções de divisão, multiplicação e multiplicação e acúmulo (exclusivas dos RL78/G14):

MULHU – multiplicação sem sinal de 16 bits do conteúdo do registrador BC pelo conteúdo do registrador AX, armazenando o resultado de 32 bits em BC (parte alta) e AX (parte baixa). Os flags do PSW não são alterados.

MULH – multiplicação de 16 bits com sinal do conteúdo do registrador BC pelo conteúdo do registrador AX, armazenando o resultado de 32 bits em BC (parte alta) e AX (parte baixa). Os flags do PSW não são alterados.

DIVHU – divisão sem sinal de 16 bits do conteúdo do registrador AX pelo conteúdo do registrador DE, armazenando o resultado de 16 bits em AX e o resto da divisão em DE. Os flags do PSW não são alterados.

Microcontroladores RL78: Guia Básico 68

DIVWU – divisão sem sinal de 32 bits do conteúdo dos registradores BCAX pelo conteúdo dos registradores HLDE, armazenando o resultado de 32 bits em BCAX e o resto da divisão em HLDE. Os flags do PSW não são alterados.

MACHU – multiplicação de 16 bits e acúmulo, sem sinal, do conteúdo do registrador BC pelo conteúdo do registrador AX, somando o resultado ao registrador de 32 bits MACR. Os flags CY e AC do PSW são alterados: AC é sempre apagado e CY é setado quando a soma ao MACR ultrapassa a capacidade do mesmo (overflow).

MACH – multiplicação de 16 bits e acúmulo, com sinal, do conteúdo do registrador BC pelo conteúdo do registrador AX, somando o resultado ao registrador de 32 bits MACR. Os flags CY e AC do PSW são alterados: CY é setado quando a soma ao MACR ultrapassa a capacidade do mesmo (overflow), ou seja, quando o resultado é maior que 0x7FFFFFFF (limite positivo) ou menor que 0x80000000 (limite negativo), AC é setado quando o resultado acumulado é negativo e apagado quando o resultado acumulado é positivo.

3.2.3. Instruções de Incremento e Decremento

Estas instruções são utilizadas para realizar o incremento (soma um) ou decremento (subtrai um) de registradores ou posições de memória.

INC dst – incrementa o conteúdo de 8 bits do destino (dst). Os flags Z e AC no PSW são alterados: Z é setado se o resultado for igual a zero, caso contrário é apagado, AC é setado caso ocorra um transporte do bit 3 para o bit 4, caso contrário é apagado.

INCW dst – incrementa o conteúdo de 16 bits do destino (dst). Os flags do PSW não são alterados.

DEC dst – decrementa o conteúdo de 8 bits do destino (dst). Os flags Z e AC no PSW são alterados: Z é setado se o resultado for igual a zero, caso contrário é apagado, AC é setado caso ocorra um empréstimo do bit 4 para o bit 3, caso contrário é apagado.

DECW dst – decrementa o conteúdo de 16 bits do destino (dst). Os flags do PSW não são alterados.

3.2.4. Instruções de Rotação e Deslocamento de Bits

As instruções de deslocamento de bits são utilizadas para deslocar um ou mais bits à esquerda ou à direita e implementam em assembly as mesmas operações dos operadores << e >> em C.

SHR dst,cnt – desloca o conteúdo de 8 bits especificado por dst em cnt posições à direita. O valor zero é inserido na posição mais significativa e o bit excedente é armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. Esta operação equivale ao operador >> e cada posição deslocada equivale a uma divisão inteira (sem sinal) por 2. O operando cnt pode ter qualquer valor entre 1 e 7.

Arquitetura e Modelo de Programação 69

SHRW dst,cnt – desloca o conteúdo de 16 bits especificado por dst em cnt posições à direita. O valor zero é inserido na posição mais significativa e o bit excedente é armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. Esta operação equivale ao operador >> e cada posição deslocada equivale a uma divisão inteira (sem sinal) por 2. O operando cnt pode ter qualquer valor entre 1 e 15.

SHL dst,cnt – desloca o conteúdo de 8 bits especificado por dst em cnt posições à esquerda. O valor zero é inserido na posição menos significativa e o bit excedente é armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. Esta operação equivale ao operador << e cada posição deslocada equivale a uma multiplicação inteira (sem sinal) por 2. O operando cnt pode ter qualquer valor entre 1 e 7.

SHLW dst,cnt – desloca o conteúdo de 16 bits especificado por dst em cnt posições à esquerda. O valor zero é inserido na posição menos significativa e o bit excedente é armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. Esta operação equivale ao operador << e cada posição deslocada equivale a uma multiplicação inteira (sem sinal) por 2. O operando cnt pode ter qualquer valor entre 1 e 15.

SAR dst,cnt – desloca o conteúdo de 8 bits especificado por dst em cnt posições à direita. O estado do bit 7 (sinal) é mantido na posição mais significativa e propagado à direita a cada posição deslocada e o bit excedente é armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. Cada posição deslocada equivale a uma divisão inteira (com sinal) por 2. O operando cnt pode ter qualquer valor entre 1 e 7.

SARW dst,cnt – desloca o conteúdo de 16 bits especificado por dst em cnt posições à direita. O estado do bit 15 (sinal) é mantido na posição mais significativa e propagado à direita a cada posição deslocada e o bit excedente é armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. Cada posição deslocada equivale a uma divisão inteira (com sinal) por 2. O operando cnt pode ter qualquer valor entre 1 e 15.

Microcontroladores RL78: Guia Básico 70

As instruções de rotação de bits operam de forma semelhante às de deslocamento, porém o bit excedente é realimentado, formando uma malha fechada ou anel, por isso o termo rotação.

ROR dst,cnt – rotaciona o conteúdo de 8 bits especificado por dst em cnt posições à direita. O bit excedente é realimentado na parte mais significativa (bit 7) e também armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. O operando cnt pode ter qualquer valor entre 1 e 7.

ROL dst,cnt – rotaciona o conteúdo de 8 bits especificado por dst em cnt posições à esquerda. O bit excedente é realimentado na parte menos significativa (bit 0) e também armazenado em CY (registrador PSW). Os demais flags do PSW não são alterados. O operando cnt pode ter qualquer valor entre 1 e 7.

RORC dst,cnt – rotaciona através do carry o conteúdo de 8 bits especificado por dst em cnt posições à direita. O bit excedente é armazenado em CY (PSW) e o conteúdo prévio de CY é deslocado para a parte mais significativa (bit 7). Os demais flags do PSW não são alterados. O operando cnt pode ter qualquer valor entre 1 e 7.

ROLC dst,cnt – rotaciona através do carry o conteúdo de 8 bits especificado por dst em cnt posições à esquerda. O bit excedente é armazenado em CY (PSW) e o conteúdo prévio de CY é deslocado para a parte menos significativa (bit 0). Os demais flags do PSW não são alterados. O operando cnt pode ter qualquer valor entre 1 e 7.

Arquitetura e Modelo de Programação 71

ROLWC dst,cnt – rotaciona através do carry o conteúdo de 16 bits especificado por dst em cnt posições à esquerda. O bit excedente é armazenado em CY (PSW) e o conteúdo prévio de CY é deslocado para a parte menos significativa (bit 0). Os demais flags do PSW não são alterados. O operando cnt pode ter qualquer valor entre 1 e 15.

3.2.5. Instruções de Manipulação e Processamento de Bits

Nesta categoria encontramos as instruções específicas para manipulação e operação (AND, OR, XOR, NOT) com dados de 1 bit.

MOV1 dst,fnt – copia o bit do operando fonte (fnt) para o operando destino (dst). Um dos operandos deverá sempre ser o bit CY do registrador PSW.

AND1 CY,fnt – realiza a operação lógica AND entre o bit especificado por fnt e CY, armazenando o resultado em CY. Os demais flags do PSW não são alterados.

OR1 CY,fnt – realiza a operação lógica OR entre o bit especificado por fnt e CY, armazenando o resultado em CY. Os demais flags do PSW não são alterados.

XOR1 CY,fnt – realiza a operação lógica XOR entre o bit especificado por fnt e CY, armazenando o resultado em CY. Os demais flags do PSW não são alterados.

NOT1 CY – inverte o estado de CY. Os demais flags do PSW não são alterados.

SET1 fnt – seta o bit especificado por fnt. Não altera o PSW (a não ser que ele seja alvo da instrução).

CLR1 fnt – apaga o bit especificado por fnt. Não altera o PSW (a não ser que ele seja alvo da instrução).

3.2.6. Instruções de Desvio

Provocam o desvio do programa para outro endereço de memória. O assembler utiliza os seguintes símbolos para especificar endereços:

$ – endereços relativos de 8 bits (o destino pode estar até 127 bytes a frente ou 128 bytes atrás da instrução seguinte ao desvio);

$! – endereços relativos de 16 bits (o destino pode estar até 32767 bytes a frente ou 32768 bytes atrás da instrução seguinte ao desvio);

! – endereços absolutos de 16 bits (os 4 bits mais significativos do PC são mantidos em zero), o destino deve estar na mesma página de 64KiB da instrução;

!! – endereços absolutos de 20 bits;

Microcontroladores RL78: Guia Básico 72

BR dst – desvio incondicional para o destino especificado por dst. O destino pode ser o conteúdo do registrador AX (em conjunto com o registrador CS), um endereço relativo de 8 ou 16 bits, ou um endereço absoluto de 16 ou 20 bits. Esta instrução não altera o PSW.

BC dst – desvio relativo para dst caso tenha havido transporte (CY = 1). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BNC dst – desvio relativo para dst caso não tenha havido transporte (CY = 0). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BZ dst – desvio relativo para dst caso zero (Z = 1). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BNZ dst – desvio relativo para dst caso diferente de zero (Z = 0). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BH dst – desvio relativo para dst caso “maior que” (OU lógico de Z e CY igual a 0). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BNH dst – desvio relativo para dst caso “menor ou igual” (OU lógico de Z e CY igual a 1). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BT bit,dst – desvio relativo para dst caso o operando especificado por bit seja verdadeiro (igual a 1). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BF bit,dst – desvio relativo para dst caso o operando especificado por bit seja falso (igual a 0). Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

BTCLR bit,dst – desvio relativo para dst caso o operando especificado por bit seja verdadeiro (igual a 1), o bit testado é apagado caso esteja setado. Esta instrução suporta somente endereçamento relativo de 8 bits e não altera o PSW.

3.2.7. Instruções para Sub-rotinas e Funções

Nesta categoria encontramos as instruções projetadas para implementação de chamadas e retorno de sub-rotinas, funções e interrupções. Além disso, estão inclusas nesta categoria as instruções para manipulação da pilha, normalmente utilizadas dentro das sub-rotinas e funções. Os mesmos símbolos para endereçamento vistos nas instruções de desvio são válidos para estas instruções.

CALL dst – chamada de sub-rotina/função no destino especificado por dst. O endereço de 20 bits da instrução seguinte ao CALL é salvo na pilha, o SP é decrementado em 4 e o programa é desviado. O destino pode ser o conteúdo de um dos pares de registradores (AX, BC, DE ou HL), um endereço relativo de 16 bits, ou um endereço absoluto de 16 ou 20 bits. Esta instrução não altera o PSW.

CALLT dst – chamada de sub-rotina/função no destino especificado por dst. O endereço de 20 bits da instrução seguinte ao CALLT é salvo na pilha, o SP é decrementado em 4 e o programa é desviado. O destino especifica um dos endereços de 16 bits na tabela CALLT. Esta instrução não altera o PSW.

Arquitetura e Modelo de Programação 73

BRK – interrupção por software. O conteúdo do PSW e o endereço de 20 bits da instrução seguinte ao BRK são salvos na pilha, o SP é decrementado em 4 e o programa é desviado para o endereço especificado pelo vetor de interrupção por software. O bit IE é apagado e os demais bits do PSW não são alterados.

RET – retorno de sub-rotina/função. O endereço de 20 bits salvo na pilha é carregado no PC, o SP é incrementado em 4 e o programa é desviado. Esta instrução não altera o PSW.

RETI – retorno de interrupção (exceto BRK). O conteúdo do PSW é recuperado da pilha e o endereço de 20 bits salvo na pilha é carregado no PC, o SP é incrementado em 4 e o programa é desviado.

RETB – retorno de interrupção por software (BRK). O conteúdo do PSW é recuperado da pilha e o endereço de 20 bits salvo na pilha é carregado no PC, o SP é incrementado em 4 e o programa é desviado.

PUSH reg – salva um dos registradores (PSW, AX, BC, DE ou HL) na pilha. O SP é decrementado em 2. Esta instrução não altera o PSW.

POP reg – recupera um dos registradores (PSW, AX, BC, DE ou HL) da pilha. O SP é decrementado em 2. Esta instrução não altera o PSW (exceto quando ele é alvo da instrução).

3.2.8. Instruções de Pulo Condicional

Estas instruções funcionam de forma semelhante aos desvios condicionais, no entanto, ao invés de provocar um desvio estas instruções apenas pulam a instrução seguinte caso a condição seja verdadeira (na verdade, ao invés de pular, a instrução seguinte é executada como um NOP e não produz qualquer resultado).

SKC – pula a próxima instrução se tiver ocorrido transporte (CY = 1). O PSW não é afetado.

SKNC – pula a próxima instrução se não tiver ocorrido transporte (CY = 0). O registrador PSW não é afetado.

SKZ – pula a próxima instrução se zero (Z = 1). O PSW não é afetado.

SKNZ – pula a próxima instrução se diferente de zero (Z = 0). O PSW não é afetado.

SKH – pula a próxima instrução se “maior que” (OU lógico de Z e CY igual a 0). O PSW não é afetado.

SKNH – pula a próxima instrução se “menor ou igual” (OU lógico de Z e CY igual a 1). O PSW não é afetado.

3.2.9. Instruções de Controle da CPU

Estas instruções controlam algumas funcionalidades e modos de operação de CPU RL78.

SEL RBx – seleciona um dos bancos de registradores (RB0, RB1, RB2 ou RB3). O registrador PSW não é afetado.

NOP – nenhuma operação é executada pela CPU. O registrador PSW não é afetado.

Microcontroladores RL78: Guia Básico 74

EI – habilita as interrupções (seta o bit IE no registrador PSW). Somente o bit IE do PSW é alterado.

DI – habilita as interrupções (apaga o bit IE no registrador PSW). Somente o bit IE do PSW é alterado.

HALT – entra em modo halt de baixo consumo de energia (o clock de CPU é paralisado, os periféricos continuam operando normalmente). O registrador PSW não é afetado.

STOP – entra em modo stop de baixo consumo de energia (o clock de CPU e dos periféricos é paralisado, somente alguns periféricos podem continuar operando neste modo). O registrador PSW não é afetado.

3.2.10. Temporização das Instruções

Graças ao pipeline de três estágios (busca, decodificação e acesso a memória), a CPU RL78 é muito rápida. De fato, a maioria das instruções (56%) é executada em apenas um ciclo de clock e 86% das instruções são executadas em até 2 ciclos de clock!

Algumas instruções e alguns modos de endereçamento podem fazer com que sejam necessários mais ciclos de clock para se completar a execução.

Instruções que desviam o fluxo do programa (e por isso necessitam esvaziar o pipeline) também necessitam de mais ciclos (3 ou mais, conforme a instrução).

Outro fator que influencia na velocidade de execução é a origem dos dados: utilizar dados armazenados em RAM é substancialmente mais rápido que utilizar dados armazenados na memória flash.

A tabela 5.5 do manual de software dos RL78 (R01US0015EJ0100) apresenta as temporizações para todas as instruções e variações de modos de endereçamento.

3.3. Módulo OCD e Código de Segurança (Security ID)

Todos os modelos de microcontroladores RL78 incluem um módulo de gravação e depuração integrado, chamado de OCD (On Chip Debug). Ele é responsável pela comunicação entre o chip e o hardware externo de depuração (TK, E1, E20, etc.).

O E1, por ser um hardware genérico e que atende a outros microcontroladores Renesas além do RL78, utiliza um conector de comunicação de quatorze vias. No entanto, uma das grandes vantagens dos RL78 é que o seu OCD comunica-se através de apenas um fio, por isso, é possível utilizar um adaptador como o mostrado na figura 3.4, de forma a converter o conector de quatorze pinos do E1 em um conector de apenas quatro pinos!

Arquitetura e Modelo de Programação 75

Figura 3.4

A figura 3.5 mostra a conexão do RL78 ao conector de depuração de quatro pinos mostrado na figura 3.4.

Figura 3.5

Outra funcionalidade muito importante em qualquer microcontrolador é a proteção da propriedade intelectual do programa gravado na memória do mesmo. Sem esta proteção, qualquer pessoa ou empresa poderia ser acesso ao programa, podendo estudá-lo ou copiá-lo quantas vezes desejasse.

Para prevenir este tipo de situação o módulo OCD possui um mecanismo de segurança que impede a leitura da memória flash caso não seja fornecida a senha correta. Esta senha é composta de 10 bytes e é gravada juntamente com a aplicação na memória flash do microcontrolador (endereços 0x000C4 a 0x000CD).

Para aumentar ainda mais a segurança, é possível configurar o chip para apagar a memória caso a senha fornecida seja incorreta (veja mais detalhes nos bytes de configuração no próximo tópico). A configuração do código de segurança (security ID) pode ser feita conforme

mostra a listagem 3.1. Os valores dentro da array senha devem ser substituídos

por valores definidos pelo programador!/* Security ID */

#pragma location = “SECUID”

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

Listagem 3.1

É importante declarar o security ID com o modificador __far, especialmente nos modelos G10 e G12 com 8KiB ou menos de flash e quando se utiliza o modelo near para o armazenamento de código. Caso __far não seja utilizado, o compilador armazenará o security ID na RAM ao invés da flash, resultando em mal funcionamento. O modificador __far permite contornar este problema, além disso, o seu uso com modelo de memória far ou com outros modelos de chip não provoca nenhum efeito colateral!

Microcontroladores RL78: Guia Básico 76

3.4. Configurações do Chip

Os microcontroladores RL78, possuem algumas configurações internas que devem ser inicializadas antes de sua operação. Para essa finalidade, o fabricante incluiu quatro bytes de configuração localizados na área da memória flash do microcontrolador (endereços 0x000C0 a 0x000C3), também chamados opbyte0 a opbyte3. A seguir apresentamos a função de cada um dos bytes de configuração.

Lembre-se de que quando utilizar a facilidade de bloco duplo de boot será necessário gravar os bytes de configuração nos dois blocos de boot, ou seja, nos endereços 0x000C0 a 0x000C3 e 0x010C0 a 0x010C3!

Endereço BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura 0x000C0

Escrita WDTINIT WINDOW1 WINDOW0 WDTON WDCS2 WDCS1 WDCS0 WDSTBYON

Nome do Bit Descrição Símbolo C

WDTINIT

Habilitação da interrupção do watchdog: 0 – interrupção desativada 1 – interrupção habilitada (gera interrupção quando a contagem do watchdog chega a 75% do tempo de estouro)

bWDTINIT

Seleção do período de janela aberta do watchdog:

00 – proibido -

01 – 50% WDT_WINDOW50

10 – 75% WDT_WINDOW75

WINDOW1 WINDOW0

11 – 100% WDT_WINDOW100

WDTON Controle de operação do watchdog: 0 – watchdog desativado 1– watchdog ativado

bWDTON

Tempo de estouro do watchdog (considerando a frequência fIL=17,25kHz)

000 – 26/fIL (±3,71ms) WDT_3ms

001 – 27/fIL (±7,42ms) WDT_7ms

010 – 28/fIL (±14,84ms) WDT_14ms

011 – 29/fIL (±29,68ms) WDT_29ms

100 – 211/fIL (±118,72ms) WDT_118ms

101 – 213/fIL (±474,90ms) WDT_474ms

110 – 214/fIL (±0,9498s) WDT_949ms

WDCS2 WDCS1 WDCS0

111 – 216/fIL (±3,79919s) WDT_3799ms

WDSTBYON Operação do watchdog nos modos halt ou stop: 0 – watchdog parado 1 – watchdog operacional

bWDSTBYON

Utilize o símbolo WDT_OFF (definido em myRL78.h) para desativar o watchdog!

Arquitetura e Modelo de Programação 77

Endereço BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura 0x000C1

Escrita VPOC2 VPOC1 VPOC0 1 LVIS1 LVIS0 LVIMDS1 LVIMDS0

Nome do Bit Descrição Símbolo C Seleção do modo de operação do detector de baixa tensão (LVD):

00 – proibido -

01 – modo interrupção LVD_INT_MODE

10 – modo de interrupção e reset LVD_INTRES_MODE

LVIMDS1 LVIMDS0

11 – modo de reset LVD_RESET_MODE

VPOC2 VPOC1 VPOC0 LVIS1 LVIS0

Veja a tabela abaixo: Veja a tabela abaixo

VLVD/VLVDH VLVDL

Subida Descida Descida*1 VPOC2 VPOC1 VPOC0 LVIS1 LVIS0 Símbolo C

1,67V*2 1,63V - 0 0 0 1 1 LVD_VMODE0

1,77V 1,73V 1,63V 0 0 0 1 0 LVD_VMODE1

1,88V*2 1,84V - 0 0 1 1 1 LVD_VMODE2

1,88V 1,84V 1,63V 0 0 0 0 1 LVD_VMODE3

1,98V 1,94V 1,84V 0 0 1 1 0 LVD_VMODE4

2,09V 2.04V 1,84V 0 0 1 0 1 LVD_VMODE5

2,50V*2 2,45V - 0 1 0 1 1 LVD_VMODE6

2,61V 2,55V 2,45V 0 1 0 1 0 LVD_VMODE7

2,71V 2,65V 2,45V 0 1 0 0 1 LVD_VMODE8

2,81V*2 2,75V - 0 1 1 1 1 LVD_VMODE9

2,92V 2,86V 1,63V 0 0 0 0 0 LVD_VMODE10

2,92V 2,86V 2,75V 0 1 1 1 0 LVD_VMODE11

3,02V 2,96V 2,75V 0 1 1 0 1 LVD_VMODE12

3,13V 3,06V 1,84V 0 0 1 0 0 LVD_VMODE13

3,75V 3,67V 2,45V 0 1 0 0 0 LVD_VMODE14

4,06V 3,98V 2,75V 0 1 1 0 0 LVD_VMODE15

*1 VLVDL é a tensão de reset no modo de interrupção e reset *2 Configuração não permitida quando o LVD opera em modo de interrupção e reset

Para desativar o LVD, basta configurar VPOC2=1 no modo de interrupção ou no modo de reset (também é possível utilizar o símbolo C LVD_OFF definido em myRL78.h).

Microcontroladores RL78: Guia Básico 78

Endereço BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura 0x000C2

Escrita CMODE1 CMODE0 1 FRQSEL4 FRQSEL3 FRQSEL2 FRQSEL1 FRQSEL0

Nome do Bit Descrição Símbolo C Seleção do modo de operação da memória flash:

00 – baixa tensão (LV) (1 a 4MHz, tensão de alimentação de 1,6 a 5,5V) FLASH_LV

01 – configuração não permitida -

10 – baixa velocidade (LS) (1 a 8MHz, tensão de alimentação de 1,8 a 5,5V)

FLASH_LS

CMODE1 CMODE0

11 – alta velocidade (HS) (1 a 16MHz, tensão de alimentação de 2,4 a 5,5V, ou até 32MHz para tensões >=2,7V) FLASH_HS

Frequência de operação do oscilador interno de alta velocidade:

11000 – 64MHz (CPU a 32MHz)* CLK_64MHZ

10000 – 48MHz (CPU a 24MHz)* CLK_48MHZ

01000 – 32MHz CLK_32MHZ

00000 – 24MHz CLK_24MHZ

01001 – 16MHz CLK_16MHZ

00001 – 12MHz CLK_12MHZ

01010 – 8MHz CLK_8MHZ

01011 – 4MHz CLK_4MHZ

FRQSEL4 FRQSEL3 FRQSEL2 FRQSEL1 FRQSEL0

01101 – 1MHz CLK_1MHZ

* Apenas nos modelos G14

Endereço BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura 0x000C3

Escrita OCDENSET 0 0 0 0 1 0 OCDERSD

Nome do Bit Descrição Símbolo C Seleção do modo de operação do depurador interno (OCD):

00 – OCD desativado DEBUG_OFF

01 – configuração não permitida -

10 – OCD ativado, apaga a flash em caso de falha na autenticação do security ID (modo seguro)

DEBUG_ON_ERASE

OCDENSET OCDERSD

11 – OCD ativado, não apaga a flash em caso de falha na autenticação do security ID (modo inseguro)

DEBUG_ON_NO_ERASE

A programação dos bytes de configuração pode ser feita, em linguagem C, utilizando-se #pragmas: #include "myRL78.h"

// Configuração dos registradores de opção (OPTION BYTES)

// Watchdog desligado

Arquitetura e Modelo de Programação 79

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Detector de baixa tensão desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador HS 4MHz

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = CLK_HS | CLK_4MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

Listagem 3.2

É importante declarar os bytes de configuração com o modificador __far, especialmente nos modelos G12 com 8KiB ou menos de flash e quando se utiliza o modelo near para o armazenamento de código. Nestes casos, o compilador armazenará os bytes de configuração e security ID na RAM ao invés da flash, resultando em mal funcionamento. O uso do modificador __far permite contornar este problema, além disso, o seu uso com modelo de memória far ou com outros modelos de chip não provoca nenhum efeito colateral!

Atenção: ao programar um chip através do ambiente IAR, o byte de configuração 3 é sempre alterado automaticamente pelo compilador de forma a ativar o OCD (no modo erase, que apaga a flash caso o security ID falhe). Caso seja necessário desativar totalmente o OCD, é necessário gerar um arquivo HEX e gravá-lo através do RFP (Renesas Flash Programmer) ou outra ferramenta de gravação!

Microcontroladores RL78: Guia Básico 80

Suporte à CPU 81

4

Suporte à CPU 4. Suporte à CPU

Neste capítulo estudaremos os módulos internos que dão suporte ao funcionamento da CPU RL78.

Dentre estes módulos podemos destacar: sistema de reset, sistema de clock, detector de tensão e cão de guarda.

4.1. Reset

Todo circuito digital sequencial necessita de um sinal de controle capaz de colocá-lo em um estado inicial conhecido. Este sinal é normalmente chamado de reset em eletrônica digital.

Os circuitos de reset constituem um elemento importante nos microcontroladores e microprocessadores, pois garantem que os seus circuitos internos sejam corretamente inicializados após a energização do mesmo.

Os microcontroladores RL78, assim como a maioria dos seus concorrentes, incluem um circuito interno de reset e um pino externo com esta função.

O circuito de reset inicializa a máquina de estados responsável pela busca e decodificação de instruções, configura a direção dos pinos de E/S (no reset os pinos são configurados como entradas, exceto o P130), inicializa os registradores SFR dos periféricos internos do microcontrolador (todos os periféricos, com exceção daqueles configurados pelos bytes de configuração, são desativados após um reset).

Observe que o conteúdo da memória RAM, dos registradores GPR, do apontador da pilha (SP) e do registrador do oscilador interno (HOCODIV) não é alterado por um reset!

O reset também provoca o desvio do programa para o endereço apontado pelo vetor de reset (endereços de memória 0x0000 e 0x0001).

Existem sete diferentes fontes de reset nos RL78, ou seja, sete diferentes maneiras de se provocar a reinicialização do chip:

1. RESET : um nível lógico baixo (0) neste pino provoca o reset do chip. Isto permite que um circuito de reset externo provoque a reinicialização do microcontrolador, uma facilidade útil em sistemas com outros circuitos digitais além do microcontrolador;

2. POR - reset interno de energização: os RL78 incluem um circuito de reset POR (Power On Reset) que monitora a tensão de alimentação do chip, mantendo-o em

Microcontroladores RL78: Guia Básico 82

reset quando a tensão de alimentação é menor que aproximadamente 1,5V (parâmetro VPDR). Esta facilidade permite que, na maioria das aplicações, seja desnecessário incluir um circuito de reset externo;

3. LVD - reset por detecção de baixa tensão: um circuito interno chamado LVD (Low Voltage Detector) pode ser configurado para gerar um reset quando a tensão de alimentação cai abaixo de um valor programado (veremos que o LVD pode também gerar uma interrupção). Esta funcionalidade pode ser utilizada para, por exemplo, salvar variáveis importantes quando uma queda de alimentação é detectada;

4. WDT - reset provocado pelo watchdog: os RL78 incluem um circuito cão de guarda (watchdog) que consiste num temporizador que, ao atingir uma marca de tempo programada, provoca o reset do chip;

5. TRAP - reset por execução de opcode ilegal: este reset é gerado quando a CPU tenta executar um opcode iniciado por 0xFF. Nos RL78 não há opcodes iniciados por 0xFF e, por isso, este código é considerado ilegal (mas é perfeitamente possível utilizar 0xFF como operando e como dado);

6. IAW - reset provocado pelo acesso a um endereço ilegal: como já vimos no tópico 3.1.2, o acesso a áreas de memória não implementadas ou acessos não permitidos (como, por exemplo, tentar executar código na área de registradores SFR ou GPR), pode gerar um reset IAW caso esta opção esteja habilitada. Esta característica de segurança será vista em maiores detalhes no tópico 10.2;

7. RPE - reset provocado por falha de paridade na RAM: os RL78 incluem um circuito detector de erros baseado em bits de paridade. Cada posição da memória RAM destes microcontroladores inclui um bit adicional para controle de paridade. Nas operações de escrita na RAM, os bits de paridade são atualizados e nas operações de leitura estes bits são checados. Caso seja detectado um erro entre a paridade calculada e a paridade lida, um reset pode ser gerado. Esta característica de segurança será vista em maiores detalhes no tópico 10.2.

O módulo LVD e o watchdog serão vistos em maiores detalhes mais a frente neste capítulo.

Após um reset, é possível consultar o registrador RESF para identificar qual a fonte causadora do mesmo. Repare que estes flags, uma vez setados, assim permanecerão até que ocorra um reset externo (via pino RESET ), um reset interno (POR), ou ocorra a leitura do registrador.

Repare que a leitura do RESF apaga TODOS os flags simultaneamente, por esta razão, o valor do mesmo deve ser lido para uma variável temporária e só então os flags devem ser analisados um a um!

Durante o reset, o pino P130 (disponível nos modelos com 48 pinos ou mais) é configurado como saída e mantido em nível lógico baixo, permitindo que o microcontrolador promova o reset de outros circuitos externos conectados a ele.

Suporte à CPU 83

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura TRAP WDTRF RPERF IAWRF LVIRF

Escrita - 0 0

- 0

- - - RESF

Reset * 0 0 * 0 * * *

* Estes bits são apagados após a leitura do registrador RESF e após um reset POR ou pelo pino de reset.

Nome do Bit Descrição Símbolo C

TRAP

Indicador de reset provocado pela tentativa de execução de opcode ilegal:

0 – não houve evento de reset por TRAP

1 – um reset foi provocado por TRAP

bTRAP

WDTRF Indicador de reset causado pelo watchdog:

0 – o watchdog não causou reset

1 – o watchdog provocou um reset

bWDTRF

RPERF Indicador de reset provocado por erro de paridade da RAM:

0 – não houve reset por erro de paridade

1 – um reset foi provocado por erro de paridade bRPERF

IAWRF Indicador de reset provocado por acesso ilegal à memória:

0 – não houve reset IAW

1 – um reset foi provocado por IAW

bIAWRF

LVIRF Indicador de reset provocado por baixa tensão:

0 – não houve reset por baixa tensão

1 – um reset foi provocado por baixa tensão bLVIRF

4.2. Sistema de Clock

O sistema de clock dos microcontroladores RL78 é dividido em duas categorias: o sistema principal e o sistema secundário.

No sistema de clock principal, temos dois sinais de clock, derivados de dois módulos osciladores:

1. fMX, derivado do oscilador de alta frequência, também chamado de X1 e capaz de operar a até 20MHz;

2. fIH, derivado do oscilador interno de alta frequência, também chamado de HOCO e capaz de operar a até 32MHz (64MHz nos modelos G14).

A seleção entre os dois osciladores é realizada por meio do bit MCM0 do registrador CKC: com MCM0 = 0 seleciona-se o sinal fIH e com MCM0 = 1, seleciona-se o sinal fMX. O sinal selecionado passa então a ser chamado fMAIN e poderá alimentar a CPU, timers TAU, módulos de comunicação serial e conversor A/D.

No sistema de clock secundário, também temos dois sinais de clock derivados de dois módulos osciladores:

Microcontroladores RL78: Guia Básico 84

1. fSUB, derivado do oscilador de clock de subsistema, também chamado de XT1 e projetado para utilizar cristais de 32,768kHz (este oscilador não está disponível nos modelos com 36 pinos ou menos);

2. fIL, derivado do oscilador interno de baixa frequência, também chamado de LOCO e que opera tipicamente em 15kHz.

A finalidade básica do clock secundário é suprir o clock de três módulos: o watchdog, o timer de intervalo e o RTC.

Nas aplicações onde se necessita medir tempo com precisão, recomenda-se utilizar o oscilador XT1 e um cristal externo de 32,768kHz. Desta forma, o sinal fSUB pode fornecer a base de tempo para o RTC, permitindo que se construa relógios e calendários de alta precisão.

O sinal de clock global que efetivamente alimenta a CPU, unidades TAU, periféricos de comunicação e o conversor A/D é chamado de fCLK. Este sinal pode ser derivado do clock principal fMAIN ou do clock secundário fSUB. Esta funcionalidade é controlada pelo bit CSS no registrador CKC: com CSS = 0 o fCLK é derivado do sinal fMAIN e com CSS = 1, o fCLK é derivado do sinal fSUB.

Após um reset, o RL78 opera sempre utilizando o oscilador interno de alta frequência, conforme a configuração dos bytes de opção. Caso a aplicação utilize outra fonte de clock, ela deverá ser configurada e selecionada na inicialização do programa (ou em outro momento, se assim for desejado).

4.2.1. Oscilador X1

O oscilador principal dos RL78 possui dois pinos externos: X1/P121 e X2/P122. A eles podem ser conectados cristais ou ressonadores cerâmicos, com frequências de 1 a 20MHz. O pino X2 também pode operar como uma entrada para clock externo (EXCLK), podendo operar em frequências de 1 a 20MHz.

O registrador CMC (Clock Mode Control) deve ser utilizado para configurar a operação do oscilador X1: quando o bit OSCSEL = 1 o oscilador pode operar e os pinos P121 e P122 são controlados pelo oscilador, quando OSCSEL = 0, os pinos P121 e P122 podem ser utilizados como entradas digitais.

Quando OSCSEL = 1, o bit EXCLK permite configurar a utilização de um oscilador externo: quando EXCLK = 1, o pino X2/P122 opera como entrada de clock externo EXCLK e o pino P121 passa a ser uma entrada digital de uso geral, quando EXCLK = 0, o oscilador necessita de um cristal ou ressonador cerâmico. Ainda no registrador CMC, o bit AMPH permite configurar o nível de consumo do oscilador e a faixa de frequências que ele pode operar.

Quando o oscilador X1 está ativo, a sua operação é controlada através do bit MSTOP no registrador CSC: quando MSTOP = 0, o oscilador pode operar normalmente e quando MSTOP = 1, o oscilador é paralisado, reduzindo o consumo de energia.

Este oscilador inclui uma funcionalidade adicional que consiste num temporizador de estabilização, que pode ser utilizado para fazer com que o sinal fMX permaneça inativo até que um tempo de estabilização seja atingido, quando então o sinal de clock é liberado.

Suporte à CPU 85

O tempo de estabilização pode ser configurado através do registrador OSTS, variando de 28 até 218 ciclos de clock do oscilador. A contagem deste temporizador pode ser lida através do registrador OSTC.

Para utilizar o oscilador X1 como fonte de clock para a CPU é necessário configurá-lo conforme descrito acima, em seguida, o programa deve aguardar a estabilização do oscilador (monitorando o registrador OSTC) e uma vez estável, deve-se comutar o clock principal, setando-se o bit MCS no registrador CKC.

Lembre-se de que os bits CMODE1 e CMODE0 (byte de configuração 0x000C2) devem ser configurados de acordo com a velocidade de operação da CPU!

As conexões do oscilador X1 são vistas na figura 4.1. Para garantir maior estabilidade e precisão, é importante utilizar trilhas curtas, um bom plano de terra e evitar a passagem de trilhas com sinais de alta corrente ou alta frequência passem próximas aos elementos do circuito oscilador.

Figura 4.1

4.2.2. Oscilador XT1

O oscilador secundário dos RL78, também chamado XT1 possui dois pinos externos: XT1/P123 e XT2/P124. A eles pode ser conectado um cristal de frequência igual a 32,768kHz. O pino XT2 também pode operar como uma entrada para clock externo (EXTCLK), podendo operar em frequências de 32 a 35kHz.

Este oscilador não está presente nos chips com encapsulamentos de 36 pinos ou menos.

O registrador CMC (Clock Mode Control) deve ser utilizado para configurar a operação do oscilador XT1: quando o bit OSCSELS = 1 o oscilador pode operar e os pinos P123 e P124 são controlados pelo oscilador, quando OSCSELS = 0, os pinos P123 e P124 podem ser utilizados como entradas digitais. Quando OSCSELS = 1, o bit EXCLKS permite configurar a utilização de um oscilador externo: quando EXCLKS = 1, o pino XT2/P124 opera como entrada de clock externo EXCLKS e o pino P123 passa a ser uma entrada digital de uso geral, quando EXCLKS = 0, o oscilador necessita de um cristal externo.

Este oscilador pode operar em três modos: normal, baixo consumo e ultra baixo consumo. A seleção entre os modos é feita através dos bits AMPHS1 e AMPHS0 (registrador CMC). Após um reset o modo selecionado é o de baixo consumo.

Lembre-se de que ao selecionar o modo de ultra baixo consumo, as características do circuito, distância de trilhas, qualidade dos componentes e interferências externas passam a ser substancialmente significantes, por isso, este modo deve ser utilizado apenas após cuidadoso projeto e ensaios!

Microcontroladores RL78: Guia Básico 86

Quando o oscilador XT1 está ativo, a sua operação é controlada através do bit XTSTOP no registrador CSC: quando XTSTOP = 0, o oscilador pode operar normalmente e quando XTSTOP = 1, o oscilador é paralisado, reduzindo o consumo de energia.

Para selecionar o oscilador XT1 como fonte de clock para a CPU e os periféricos basta setar o bit CSS (registrador CKC).

As conexões do oscilador XT1 são vistas na figura 4.2. As mesmas recomendações sugeridas para o oscilador X1 valem para o XT1, mas no caso dele, por tratarem-se de sinais de potência ainda menor e de um circuito mais sensível, o projeto deve ser ainda mais criterioso!

Figura 4.2

4.2.3. Oscilador Interno de Alta Frequência

Como já vimos, os RL78 incluem um oscilador interno de alta frequência (também chamado de HOCO) capaz de operar a até 32MHz (64MHz nos modelos G14). Este oscilador apresenta também uma elevada estabilidade de frequência e precisão na ordem de 1%.

O HOCO é configurado inicialmente através do byte de configuração em 0x000C2 e é sempre selecionado como fonte de clock da CPU após um reset.

A frequência de operação do HOCO pode ser reconfigurada em tempo de execução, utilizando-se o registrador HOCODIV e também é possível efetuar um ajuste fino da mesma utilizando-se o registrador HIOTRM.

Lembre-se de que os bits CMODE1 e CMODE0 (byte de configuração 0x000C2) devem ser configurados de acordo com a velocidade de operação da CPU!

A operação do HOCO é controlada pelo bit HIOSTOP no registrador CSC: quando HIOSTOP = 0, o oscilador pode operar normalmente e quando HIOSTOP = 1, o oscilador é paralisado, reduzindo o consumo de energia.

Note que, no caso dos modelos G14, a frequência máxima da CPU ainda é 32MHz, mas o oscilador pode trabalhar a até 64MHz. Nos modos 48 ou 64MHz, a frequência de oscilador alimenta o timer RD e é dividida por dois antes de alimentar a CPU, desta forma a CPU opera dentro dos limites especificados.

A nota de aplicação AN1084 (R01AN1084EG0100) demonstra o procedimento de calibração do oscilador HOCO utilizando uma referência de clock externa. Através deste procedimento é possível obter uma precisão de ±0,1% na frequência do oscilador interno!

Suporte à CPU 87

4.2.4. Oscilador Interno de Baixa Frequência

Este oscilador, que chamaremos de LOCO, opera numa frequência nominal típica de 15kHz e possui precisão de ±15%. Ele é utilizado basicamente como fonte de clock para o watchdog e opcionalmente, pode também fornecer clock para o timer de intervalo e para o RTC interno.

Como este oscilador possui baixa precisão e não pode ser ajustado, o seu uso como fonte de clock para os timers deve ser considerado apenas nas aplicações em que a medição de tempo não necessita de precisão.

O LOCO está sempre em operação e não pode ser desativado diretamente pelo programa, mas é desligado no modo stop quando o watchdog está desligado e não está sendo utilizado como fonte de clock pelos timers.

Para selecionar o LOCO como fonte de clock do timer de intervalo e do RTC, basta setar o bit WUTMMCK0 (registrador OSMC).

Não é possível utilizar o LOCO como fonte de clock para a CPU!

4.2.5. Registradores do Sistema de Clock

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura CLS MCS

Escrita - CSS

- MCM0 0 0 0 0

CKC

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

CLS Status do clock da CPU e periféricos:

0 – Clock principal (X1 ou HOCO)

1 – Clock secundário (XT1) bCLS

CSS Seleção da fonte do clock da CPU e periféricos (fCLK):

0 – Clock principal (X1 ou HOCO)

1 – Clock secundário (XT1)

bCSS

MCS Status do clock principal:

0 – Oscilador interno (HOCO)

1 – Oscilador X1 bMCS

MCM0

Seleção da fonte do clock principal:

0 – Oscilador interno (HOCO)

1 – Oscilador X1 * Este bit somente pode ser alterado quando CSS=1

bMCM0

Microcontroladores RL78: Guia Básico 88

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita EXCLK OSCSEL EXCLKS OSCSELS 0 AMPHS1 AMPHS0 AMPH

CMC

Reset 0 0 0 0 0 0 0 0

Atenção: o registrador CMC é do tipo write-once, ou seja, após o reset ele somente pode ser configurado uma única vez e através de uma operação de 8 bits. Caso não seja necessário alterar o conteúdo do mesmo, o programa deve escrever 0x00 no mesmo, de forma a garantir que ele não seja alterado por algum erro no programa!

Nome do Bit Descrição Símbolo C Seleção da configuração de operação do oscilador X1:

00 – oscilador desativado (pinos P121 e P122 como entradas digitais) OSC_X1_OFF

01 – oscilador operando com cristal ou ressonador externo conectado aos pinos X1/P121 e X2/P122

OSC_X1_OSC

10 – oscilador desativado (pinos P121 e P122 como entradas digitais) -

EXCLK OSCSEL

11 – entrada de clock externo via P122, pino P121 opera como entrada digital

OSC_X1_EXT

Seleção da configuração de operação do oscilador XT1:

00 – oscilador desativado (pinos P123 e P124 como entradas digitais) OSC_XT1_OFF

01 – oscilador operando com cristal ou ressonador externo conectado aos pinos X1/P123 e X2/P124

OSC_XT1_OSC

10 – oscilador desativado (pinos P123 e P124 como entradas digitais) -

EXCLKS OSCSELS

11 – entrada de clock externo via P124, pino P123 opera como entrada digital

OSC_XT1_EXT

Seleção do modo de operação do oscilador XT1:

00 – modo de baixa potência OSC_XT1_LP

01 – modo normal OSC_XT1_STD

10 – modo ultra baixa potência OSC_XT1_ULP

AMPHS1 AMPHS0

11 – modo não permitido -

AMPH Seleção da faixa de frequência de operação do oscilador X1: 0 – 1 a 10 MHz 1 – 10,1 a 20MHz bAMPH

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita MSTOP XTSTOP 0 0 0 0 0 HIOSTOP

CSC

Reset 1 1 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

MSTOP Operação do oscilador X1: 0 – Oscilador pode operar 1 – Oscilador parado

bMSTOP

XTSTOP Operação do oscilador XT1: 0 – Oscilador pode operar 1 – Oscilador parado bXTSTOP

HIOSTOP Operação do oscilador HOCO: 0 – Oscilador operando 1 – Oscilador parado bHIOSTOP

Suporte à CPU 89

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura Estado do contador de estabilização

Escrita - OSTC

Reset 0 0 0 0 0 0 0 0

O valor lido neste registrador mostra o estado do contador de estabilização:

0x00 – tempo mínimo não transcorrido 0x80 – 28 contagens transcorridas 0xC0 – 29 contagens transcorridas 0xE0 – 210 contagens transcorridas 0xF0 – 211 contagens transcorridas 0xF8 – 213 contagens transcorridas 0xFC – 215 contagens transcorridas 0xFE – 217 contagens transcorridas 0xFF – 218 contagens transcorridas

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 OSTS2 OSTS1 OSTS0

OSTS

Reset 0 0 0 0 0 1 1 1

Nome do Bit Descrição Símbolo C Seleção do número de ciclos de estabilização do oscilador X1:

000 - 256 ciclos do oscilador OSTS_256

001 – 512 ciclos do oscilador OSTS_512

010 – 1024 ciclos do oscilador OSTS_1k

011 – 2048 ciclos do oscilador OSTS_2k

100 – 8192 ciclos do oscilador OSTS_8k

101 – 32768 ciclos do oscilador OSTS_32k

110 – 131072 ciclos do oscilador OSTS_131k

OSTS2 OSTS1 OSTS0

111 – 262144 ciclos do oscilador OSTS_262k

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita RTCLPC 0 0 WUTMMCK0 0 0 0 0

OSMC

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

RTCLPC

Comportamento do clock secundário em modo stop e halt quando utilizado como fonte de clock da CPU: 0 – O clock secundário continua a suprir os periféricos nos modos halt e stop 1 – O clock secundário é paralisado nos modos halt e stop (exceto para o RTC e timer de intervalo)

bRTCLPC

WUTMMCK0 Seleção da fonte de clock do RTC e do timer de intervalo: 0 – Oscilador XT1 1 – Oscilador LOCO bWUTMMCK0

Microcontroladores RL78: Guia Básico 90

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 DIV2 DIV1 DIV0

HOCODIV

Reset 0 0 0 0 0 ? ? ?

Nome do Bit Descrição Símbolo C Seleção da frequência de operação do oscilador HOCO (quando o bit FRQSEL3 = 1 no byte de configuração):

000 – 32MHz HOCO_32MHZ

001 – 16MHz HOCO_16MHZ

010 – 8MHz HOCO_8MHz

011 – 4MHz HOCO_4MHZ

100 – 2MHz HOCO_2MHZ

101 – 1MHz HOCO_1MHz

Seleção da frequência de operação do oscilador HOCO (quando o bit FRQSEL3 = 0 no byte de configuração):

000 – 24MHz HOCO_24MHZ

001 – 12MHz HOCO_12MHZ

010 – 6MHz HOCO_6MHz

DIV2 DIV1 DIV0

011 – 3MHz HOCO_3MHZ

Outras configurações são inválidas.

O oscilador interno HOCO é configurado inicialmente pelo conteúdo do byte de configuração:

Endereço BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura 0x000C2

Escrita CMODE1 CMODE0 1 FRQSEL4 FRQSEL3 FRQSEL2 FRQSEL1 FRQSEL0

Nome do Bit Descrição Símbolo C Frequência de operação do oscilador interno de alta velocidade:

11000 – 64MHz (CPU a 32MHz)* CLK_64MHZ

10000 – 48MHz (CPU a 24MHz)* CLK_48MHZ

01000 – 32MHz CLK_32MHZ

00000 – 24MHz CLK_24MHZ

01001 – 16MHz CLK_16MHZ

00001 – 12MHz CLK_12MHZ

01010 – 8MHz CLK_8MHZ

01011 – 4MHz CLK_4MHZ

FRQSEL4 FRQSEL3 FRQSEL2 FRQSEL1 FRQSEL0

01101 – 1MHz CLK_1MHZ

* Apenas nos modelos G14

Suporte à CPU 91

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura Ajuste fino do oscilador HOCO

Escrita - HIOTRM

Reset Varia conforme a calibração de fábrica

O valor carregado neste registrador é utilizado para ajustar o oscilador HOCO:

0 – frequência mínima ... 255 – frequência máxima

4.2.6. Exemplo

O exemplo a seguir mostra como o oscilador interno HOCO pode ser configurado “on the fly” durante a execução do programa. Trata-se de um simples pisca led que alterna 10 piscadas do led operando com frequência de 32MHz e 10 piscadas com a CPU operando a 8MHz. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED_D2 P7_bit.no7

void pisca(void)

unsigned char cnt;

unsigned long int temp;

for (cnt=10;cnt;cnt--)

LED_D2 = 0;

for (temp=100000;temp;temp--);

LED_D2 = 1;

for (temp=100000;temp;temp--);

void main( void )

PM7_bit.no7 = 0; // porta P77 como saída

CMC = 0; // desativa osciladores X1 e XT1

while (1)

pisca();

Microcontroladores RL78: Guia Básico 92

HOCODIV = HOCO_8MHZ; // oscilador a 8MHz

pisca();

HOCODIV = HOCO_32MHZ; // oscilador a 32MHz

Exemplo 4.1

4.3. Gerenciamento de Energia

Um dos diferenciais de projeto dos microcontroladores RL78 é o quesito consumo de energia. Como já dissemos anteriormente, o projeto destes chips levou em consideração um baixo consumo aliado a uma alta velocidade de operação, o que se traduz em alta eficiência computacional.

Para se ter uma idéia, um microcontrolador RL78 consome cerca de 4,6mA quando operando com alimentação de 5V e utilizando o oscilador interno operando a 32MHz. Isto significa que o chip consume aproximadamente 23mW quando operando em velocidade máxima.

Apesar de este ser um número excelente, muitas aplicações de microcontroladores são operadas a bateria ou pilha, neste caso, um consumo de 23mW pode esgotar rapidamente estas fontes de energia tão limitadas.

Por esta razão, os RL78 possuem modos especiais de operação que reduzem drasticamente o consumo de energia.

Além do modo totalmente operacional (o modo run, que é o modo padrão), temos o modo halt, no qual o clock da CPU é paralisado, com o restante dos periféricos podendo operar normalmente e o modo stop, no qual praticamente todas as fontes de clock do microcontrolador são paralisadas, juntamente com a CPU e os periféricos (apenas alguns poucos periféricos podem continuar operando neste modo).

Lembre-se de que nos modos halt e stop o clock da CPU é paralisado e por isso, nenhum programa é executado! No entanto, se analisarmos cuidadosamente, poderemos perceber que praticamente qualquer aplicação pode se beneficiar em algum momento de um destes modos de baixo consumo. Vejamos alguns exemplos típicos do uso destes modos de economia de energia:

1. A aplicação está aguardando uma temporização ser completada. Neste caso, é possível entrar em modo halt enquanto se aguarda um timer gerar uma interrupção. Caso se utilize o RTC ou timer de intervalo, é possível inclusive utilizar o modo stop nesta situação!

2. Utilizar o modo stop para manter o equipamento em modo “desligado” e, através de teclas conectadas a pinos de interrupção retorna-se ao modo operacional quando o usuário pressiona uma delas.

3. O microcontrolador permanece em modo snooze aguardando a recepção de um dado pela porta serial ou uma conversão A/D ser completada.

O conteúdo da memória RAM, o estado das portas de E/S e dos periféricos é mantido enquanto o chip permanece nos modos halt, stop e snooze.

Suporte à CPU 93

4.3.1. Modo Halt

O modo halt permite reduzir significativamente o consumo de energia do microcontrolador, pois ao paralisar o clock da CPU, apenas os periféricos que permanecem operando continuam a consumir corrente significativa.

Lembre-se de que estes microcontroladores utilizam circuitos CMOS. Neste tipo de circuito, quanto maior a frequência de comutação, maior a corrente consumida. Ao desativar o clock da CPU, seus MOSFETs passam a permanecer em modo estático, com um consumo extremamente baixo de energia (basicamente a corrente de fuga dos gates dos MOSFETs)!

Como já vimos, um RL78 (R5F100LE) operando a 32MHz consome cerca de 4,6mA quando operando com alimentação de 5V. Se nas mesmas condições o microcontrolador entrar em modo halt, o consumo de energia é reduzido para cerca de 540µA! Ou seja, no modo halt o RL78 reduz o seu consumo para cerca de 11,7% do consumo em modo totalmente operacional!

Lembre-se de que o consumo total do microcontrolador irá depender de quais periféricos estão operando!

O bit RTCLPC (registrador OSMC) permite selecionar o comportamento dos periféricos quando o oscilador XT1 é utilizado como fonte de clock da CPU e dos periféricos: quando RTCLPC = 0, os periféricos podem continuar operando em modo halt e quando RTCLPC = 1, os periféricos são paralisados no modo halt.

Tudo o que é necessário fazer para se entrar neste modo de operação é executar a instrução assembly HALT ou uma chamada a função __halt() em linguagem C.

Para utilizar a função __halt(), é necessário incluir o arquivo “intrinsics.h”!

Uma vez em modo halt, a CPU permanecerá inativa até que ocorra uma interrupção ou reset.

Caso as interrupções globais estejam desabilitadas (IE = 0 no PSW), ainda assim, uma interrupção de periférico poderá provocar a saída do modo halt, porém, neste caso particular, não ocorrerá desvio para o vetor de interrupção e o programa seguirá da instrução seguinte a HALT.

4.3.2. Modo Stop

O modo stop garante um consumo de energia substancialmente menor que o modo halt, pois, além da CPU, praticamente todos os periféricos são paralisados. Neste modo de operação, somente os seguintes periféricos ou módulos podem continuar operando:

• Oscilador secundário XT1 (desde que habilitado);

• Oscilador interno de baixa frequência (desde que utilizado com o RTC, timer de intervalo ou watchdog);

• Detector de baixa tensão (LVD);

Microcontroladores RL78: Guia Básico 94

• Saída de clock (desde que operando com o clock de subsistema);

• Interrupção externa e de teclado;

• Watchdog (desde que habilitado para operar no modo stop);

• Timer de intervalo (quando utilizando como fonte de clock o oscilador interno de baixa frequência);

• RTC.

Neste modo de operação, a corrente consumida pelo mesmo microcontrolador (R5F100LE) é reduzida tipicamente para cerca de 230nA, ou seja, no modo stop o microcontrolador consume cerca de 0,04% da corrente consumida no modo halt ou 0,005% do consumo no modo run!

O bit RTCLPC (registrador OSMC) permite selecionar o comportamento dos periféricos quando o oscilador XT1 é utilizado como fonte de clock da CPU e dos periféricos: quando RTCLPC = 0, os periféricos podem continuar operando em modo stop e quando RTCLPC = 1, os periféricos são paralisados no modo stop.

A entrada neste modo de operação é provocada pela execução da instrução assembly STOP ou pela chamada da função __stop() em linguagem C.

Para utilizar a função __stop(), é necessário incluir o arquivo “intrinsics.h”!

Uma vez em modo stop, a CPU permanecerá inativa até que ocorra uma interrupção ou reset.

Caso as interrupções globais estejam desabilitadas (IE = 0 no PSW), ainda assim, uma interrupção de periférico poderá provocar a saída do modo stop, porém, neste caso particular, não ocorrerá desvio para o vetor de interrupção e o programa seguirá da instrução seguinte a STOP.

Atenção: ao programar um chip através do ambiente IAR, o byte de configuração 3 é sempre alterado (pelo compilador) para ativar o OCD (no modo erase, que apaga a flash caso o security ID falhe). Caso seja necessário desativar totalmente o OCD, é necessário gerar um arquivo HEX e gravá-lo através do RFP (Renesas Flash Programmer) ou outra ferramenta de gravação! Lembre-se de que o OCD, caso ativado no byte de configuração, aumenta consideravelmente o consumo em modo stop (cerca de 250µA)!

4.3.3. Modo Snooze

Este modo é uma variação do modo stop, onde o oscilador interno de alta velocidade é mantido operando, permitindo que alguns periféricos continuem a funcionar, podendo gerar uma interrupção e o consequente retorno ao modo run.

O conversor A/D e os módulos seriais CSI e UART podem ser configurados para continuar operando neste modo.

No modo snooze, após a execução da instrução assembly STOP, a CPU e a maioria dos periféricos é paralisada. Caso o conversor A/D esteja configurado para operar em modo snooze (registrador ADM2), ele permanecerá operando e realizando conversões, ao completar

Suporte à CPU 95

conversões o A/D gera uma interrupção que provoca o retorno da CPU ao modo run. No caso das interfaces seriais CSI e UART, elas permanecerão ativas desde que configuradas para operar no neste modo (registrador SSCm). Ao receber ou enviar um dado, estes módulos gerarão uma interrupção que fará com que a CPU retorne ao modo run.

4.3.4. Gerenciamento de Clock

Outra funcionalidade importante no gerenciamento do consumo de energia dos RL78 é o gerenciamento de clock e energia. Através dele é possível controlar quais periféricos podem operar e quais são desligados. O controle é feito por meio do registrador PER0.

Os periféricos controlados são: conversor A/D, timers TAU, interfaces seriais (SAU e I2C) e o relógio de tempo real (RTC).

Após um reset todos os periféricos mencionados são desativados e devem ser ativados através do registrador PER0 antes de serem utilizados!

Atenção: quando os periféricos estão desativados os seus registradores SFR não operam e por isso não devem ser utilizados. Qualquer escrita nos mesmos é descartada.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita RTCEN IICA1EN ADCEN IICA0EN SAU1EN SAU0EN TAU1EN TAU0EN

PER0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

RTCEN Controle do clock do RTC e do timer de intervalo: 0 – Clock desativado 1 – Clock ativado

bRTCEN

IICA1EN Controle do clock da interface I2C1: 0 – Clock desativado 1 – Clock ativado bIICA1EN

ADCEN Controle do clock da conversor A/D: 0 – Clock desativado 1 – Clock ativado

bADCEN

IICA0EN Controle do clock da interface I2C0: 0 – Clock desativado 1 – Clock ativado

bIICA0EN

SAU1EN Controle do clock do módulo serial SAU1: 0 – Clock desativado 1 – Clock ativado bSAU1EN

SAU0EN Controle do clock do módulo serial SAU0: 0 – Clock desativado 1 – Clock ativado bSAU0EN

TAU1EN Controle do clock da unidade de timers TAU1: 0 – Clock desativado 1 – Clock ativado

bTAU1EN

TAU0EN Controle do clock da unidade de timers TAU0: 0 – Clock desativado 1 – Clock ativado

bTAU0EN

Microcontroladores RL78: Guia Básico 96

4.3.5. Dicas para Reduzir o Consumo de Energia

A entrada em modo stop reduz grandemente o consumo de energia do microcontrolador, mas para garantir o menor consumo possível devemos observar alguns detalhes importantes:

1. Desative os periféricos que não serão utilizados: lembre-se de que o watchdog, o LVD, o RTC, o timer de intervalo e o oscilador XT1 podem continuar operando no modo stop. Além disso, as interfaces seriais e o ADC também podem operar em modo snooze. Por isso, antes de entrar em modo stop, certifique-se de que todos os periféricos não utilizados estejam devidamente desligados. A tabela 4.1 ilustra o consumo típico de alguns destes módulos:

Módulo Consumo (µA)

ADC (5V) 1300

Referência interna 1,45V 75

Sensor de temperatura 75

Oscilador XT1 0,57

Watchdog* 0,22

RTC 0,02

Timer de intervalo 0,02

LVD 0,08

* Inclui o consumo do oscilador LOCO (15kHz)

Tabela 4.1

2. Desative o OCD: o circuito de depuração interno consume algumas centenas de microampéres quando está habilitado no byte de configuração opbyte3. Na fase de desenvolvimento pode ser interessante deixá-lo desta forma, mas para produção é importante desativar o OCD para garantir um menor consumo de energia;

3. Não deixe pinos de entrada flutuando: pinos de entrada podem gastar energia desnecessária quando são deixados flutuando. Neste caso é uma boa idéia configurar como saída todos os pinos não utilizados e colocá-los em um nível lógico seguro (normalmente zero);

4. Lembre-se de que o pino P4.0/TOOL0 deve possuir um resistor externo de pull-up. Para reduzir o consumo de energia, configure este pino como entrada ou, se configurado como saída, mantenha-o em nível lógico alto antes de entrar em um modo de baixo consumo.

4.3.6. Exemplo

O exemplo a seguir demonstra a utilização do modo stop. Ao ser ligada a alimentação o led D2 da placa de promoção do RL78/G13 irá piscar brevemente e em seguida a CPU irá entrar em modo stop, com o consumo reduzido para cerca de 230nA. A saída desde modo é realizada por meio do pino P5.0 que é configurado para operação como fonte de interrupção externa INTP1 com o seu resistor interno de pull-up ativado (uma tecla deve ser conectada entre este pino e o GND).

Suporte à CPU 97

Uma transição negativa no pino (do nível “1” para nível “0”) provoca a saída do modo stop e o retorno ao modo normal de execução. Observe que o flag da interrupção é apagado por software (PIF1 = 0). Isto é necessário porque a aplicação não está com as interrupções habilitadas (IE = 0) e por isso não há uma ISR para o tratamento da mesma (o flag seria apagado automaticamente quando o programa fosse desviado para a ISR).

Para a correta operação do exemplo, alguns passos devem ser observados:

1. A aplicação deve ser compilada com o depurador interno (OCD) desativado no byte de opção número 3;

2. O projeto deve ser compilado no modo “Release” dentro do ambiente EWRL78. Lembre-se de configurar as opções de projeto da mesma forma que no modo “Debug”. O linker deve ser configurado para gerar um arquivo .hex, necessário para a gravação através da ferramenta RFP, conforme mostrado no tópico 2.1.4;

3. Após a gravação do arquivo .hex gerado no passo 2, basta remover o jumper J9 para que o microcontrolador saia do reset e execute a aplicação. Para medição da corrente consumida, basta conectar um multímetro ou microamperímetro no local do jumper J3.

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 4MHz flash low speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em casa de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_OFF;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED_D2 P7_bit.no7

void pisca(void)

unsigned char cnt;

unsigned long int temp;

for (cnt=10;cnt;cnt--)

LED_D2 = 0;

for (temp=100000;temp;temp--);

LED_D2 = 1;

for (temp=100000;temp;temp--);

Microcontroladores RL78: Guia Básico 98

void main (void)

P0=P1=P2=P3=P4=P5=P6=P7=P12=P14=0;

// configura todos os pinos como saídas

PM0=PM1=PM2=PM3=PM4=PM5=PM6=PM7=PM12=PM14=0;

// configura pinos analógicos para modo digital

ADPC = 1;

PMC0=PMC12=PMC14=0;

CMC = 0; // desativa osciladores X1 e XT1

PM5_bit.no0 = 1; // pino P5.0 como entrada

PU5_bit.no0 = 1; // liga pull-up do pino P5.0

EGN0 = BIT1; // interrupção INTP1 na borda de descida

PIF1 = 0; // limpa o flag da interrupção INTP1

PMK1 = 0; // habilita a interrupção INTP1

while(1)

pisca(); // pisca 10 vezes o led

__stop(); // entra em modo stop

// ocorreu um sinal de wake-up

PIF1 = 0; // limpa o flag da interrupção

Exemplo 4.2

4.4. Clock/Buzzer Output

Os microcontroladores RL78 incluem até dois módulos capazes de gerar sinais de onda quadrada através de pinos do chip. Os sinais gerados pelos módulos podem ser utilizados para controlar buzzers ou alto-falantes externos, fornecer referências externas de clock, etc.

Estes módulos consistem em divisores de frequência capazes de dividir um dos sinais internos de clock (principal ou do oscilador XT1) por um fator fixo configurável (8 seleções para cada fonte de clock).

Os sinais de saída (PCLBUZ0 e PCLBUZ1) podem ainda ser controlados (ligados ou desligados) de forma que se pode modulá-los conforme desejado.

Note que nos microcontroladores com encapsulamentos de 24 ou 25 pinos, apenas um módulo está disponível (saída PCLBUZ0) e nos modelos com 20 pinos, nenhum dos módulos está presente.

O sinal PCLBUZ0 está normalmente associado ao pino P140 (ou P31 quando há redirecionamento de E/S) e o pino PCLBUZ1 está normalmente associado ao pino P141 (ou P55 quando há redirecionamento de E/S).

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0 Leitura Escrita

PCLOEn 0 0 0 CSELn CCSn2 CCSn1 CCSn0 CKS1 CKS0

Reset 0 0 0 0 0 0 0 0

O bit PCLOEn controla a saída do módulo: em “0” a saída está desativada e em “1” a saída é controlada pelo módulo.

Suporte à CPU 99

As tabelas a seguir mostram os valores típicos de frequências de saída para as diversas configurações dos módulos.

CSELn = 0 (clock primário) f/1 f/2 f/4 f/8 f/16 f/2048 f/4096 f/8192 CCSn2 0 0 0 0 1 1 1 1 CCSn1 0 0 1 1 0 0 1 1 CCSn0 0 1 0 1 0 1 0 1

1M 1M 500k 250k 125k 62,5k 488,28 244,14 122,07 2M 2M 1M 500k 250k 125k 976,56 488,28 244,14 3M 3M 1,5M 750k 375k 187,5k 1.464,84 732,42 366,21 4M 4M 2M 1M 500k 250k 1.953,13 976,56 488,28 5M 5M 2,5M 1,25M 625k 312,5k 2.441,41 1.220,70 610,35 6M 6M 3M 1,5M 750k 375k 2.929,69 1.464,84 732,42 8M 8M 4M 2M 1M 500k 3.906,25 1.953,13 976,56

10M 10M 5M 2,5M 1,25M 625k 4.882,81 2.441,41 1.220,70 12M 12M 6M 3M 1,5M 750k 5.859,38 2.929,69 1.464,84 16M 16M 8M 4M 2M 1M 7.812,5 3.906,25 1.953,13 20M * 10M 5M 2,5M 1,25M 9.765,63 4.882,81 2.441,41 24M * 12M 6M 3M 1,5M 11.718,75 5.859,38 2.929,69

Clo

ck p

rinc

ipal

(H

z)

32M * 16M 8M 4M 2M 15.625 7.812,5 3.906,25

* A frequência de saída não deve ultrapassar 16MHz!!!

Tabela 4.2

CSELn=1 (clock secundário XT1) f/1 f/2 f/4 f/8 f/16 f/32 f/64 f/128

CCSn2 0 0 0 0 1 1 1 1 CCSn1 0 0 1 1 0 0 1 1 CCSn0 0 1 0 1 0 1 0 1 Saída 32.768 16.384 8.192 4.096 2.048 1.024 512 256

Tabela 4.3

4.4.1. Exemplo

O exemplo a seguir demonstra como utilizar a saída PCLBUZ0 disponível no RL78/G13. O programa configura o pino P14.0 como saída e ajusta a saída PCLBUZ0 para operar com uma frequência de saída igual a 3.906,25Hz (com o clock da CPU proveniente do HOCO operando a 32MHz). #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 4MHz flash low speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em casa de falha de autenticação

Microcontroladores RL78: Guia Básico 100

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_OFF;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

void main (void)

CMC = 0; // desativa osciladores X1 e XT1

PM14_bit.no0 = 0; // pino P14.0 como saída

CKS0 = bPCLOE | 7; // ativa a saída PCLBUZ0 com clock = 3,9kHz

while (1);

Exemplo 4.3

4.5. Detector de Baixa Tensão

O detector de baixa tensão ou LVD é um circuito comparador de tensão integrado ao RL78 e que monitora a tensão de alimentação do chip.

O LVD pode operar em três modos distintos:

• Reset: neste modo o LVD provoca o reset do chip quando a tensão de alimentação cai abaixo do valor configurado;

• Interrupção: o LVD gera uma interrupção quando a tensão de alimentação cai abaixo do valor configurado;

• Interrupção e reset: é um misto dos dois modos anteriores. O LVD gera uma interrupção quando a tensão de alimentação cai abaixo de um limite configurado e provoca o reset caso ela ultrapasse um limite mínimo também especificado.

O módulo LVD pode ser desativado (através do byte de configuração), mas isso normalmente não deve ser realizado, já que ele garante a correta operação do microcontrolador nas flutuações de tensão e o seu consumo é muito reduzido (cerca de 80nA).

Vejamos agora os detalhes de cada modo de operação do LVD.

4.5.1. Modo Reset

Neste modo, o LVD provoca o reset do chip quando a tensão de alimentação cai abaixo do valor de disparo (valor de descida da coluna VLVD na tabela 4.4). Ao mesmo tempo, os bits LVIRF (registrador RESF) e LVIF (registrador LVIM) são setados.

Enquanto esta situação perdurar, o sinal de reset do LVD é mantido, sendo liberado somente quando a tensão ultrapassa o valor de subida da coluna VLVD na mesma tabela. Quando isso acontece, o bit LVIF é apagado (mas o LVIRF é mantido setado).

Note que, caso a tensão de alimentação caia abaixo do valor VPOR, um reset de energização é desencadeado (o bit LVIRF é apagado).

Suporte à CPU 101

4.5.2. Modo Interrupção

Neste modo, o módulo LVD gera interrupções tanto quando a tensão de alimentação cai abaixo do valor de disparo (valor de descida da coluna VLVD na tabela 4.4), quanto quando a tensão de alimentação ultrapassa o valor de subida da coluna VLVD na mesma tabela.

Em qualquer dos casos o bit LVIF é setado, juntamente com o flag de interrupção LVIIF e, caso a máscara de interrupção do LVD esteja desativada (LVIMK = 0), uma interrupção será gerada.

4.5.3. Modo Interrupção e Reset

Neste modo, o LVD opera inicialmente no modo de interrupção. Quando a tensão de alimentação cai abaixo do valor VLVDH, um evento de interrupção é disparado e simultaneamente o módulo passa a operar no modo reset (no registrador LVIS, os bits de seleção de modo LVIMD e de seleção de limiar LVILV são setados, selecionando o modo de reset com limiar VLVDL).

Dentro da ISR a aplicação deve seguir os seguintes passos:

1. Setar o bit LVISEN no registrador LVIM. Isto é necessário para modificar o bit LVILV no próximo passo;

2. Apagar o bit LVILV no registrador LVIS;

3. Apagar o bit LVISEN no registrador LVIM;

4. Aguardar que a estabilização do LVD seja completada (bit LVIOMSK=0 no registrador LVIM;

5. Após a estabilização, caso a tensão de alimentação esteja abaixo de VLVDH, um reset é gerado, caso contrário a aplicação deve seguir para o próximo passo;

6. O bit LVISEN (registrador LVIM) deve ser setado novamente. Isto é necessário para alterar o bit LVIMD;

7. O bit LVIMD (registrador LVIS) deve ser apagado (seleciona o modo de interrupção);

8. O bit LVISEN deve ser apagado e a aplicação retorna ao estado normal de operação, um novo evento de queda de tensão irá gerar uma nova interrupção LVD.

Neste modo de operação, o parâmetro VLVDH pode ser considerado como o limiar de interrupção e o parâmetro VLVDL pode ser considerado como o limiar de reset.

Após um reset neste modo a aplicação deve sempre verificar a origem do reset (registrador RESF) e caso verifique que o reset foi provocado pelo LVD (bit LVIRF = 1), ela deve obrigatoriamente seguir os seguintes passos:

1. Setar o bit LVISEN (registrador LVIM) de forma a poder modificar o bit LVIMD;

2. Aguardar um tempo mínimo de 400µs;

3. Apagar o bit LVIMD no registrador LVIS (selecionando o modo de interrupção);

Microcontroladores RL78: Guia Básico 102

4. Apagar o bit LVISEN e iniciar a operação normal do microcontrolador.

4.5.4. Registradores do LVD

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura LVIOMSK LVIF

Escrita LVISEN 0 0 0 0 0

0 0 LVIM

Reset 0* 0 0 0 0 0 0* 0*

* Após um reset LVD este registrador não é alterado.

Nome do Bit Descrição Bit C Símbolo C

LVISEN Controle de escrita no registrador LVIS: 0 – escrita desabilitada (não produz efeito) 1 – escrita habilitada

LVISEN bLVISEN

LVIOMSK

Máscara de estado do LVD: 0 – LVD operando normalmente 1 – LVD em estabilização (nenhum evento será gerado nesta situação)

LVIOMSK bLVIOMSK

LVIF

Indicador de status do LVD: 0 – LVD desligado ou tensão (VDD) ≥ valor configurado (VLVD) 1 – tensão (VDD) < valor configurado (VLVD)

LVIF bLVIF

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita LVIMD 0 0 0 0 0 0 LVILV

LVIS

Reset * 0 0 0 0 0 0 *

* O valor após o reset depende da configuração do LVD no byte de configuração: 0x81 no modo reset, 0x01 no modo interrupção e 0x00 no modo interrupção e reset.

Atenção: somente é possível escrever no registrador LVIS quando o bit LVISEN = 1 no LVIM!

Nome do Bit Descrição Bit C Símbolo C

LVIMD

Modo de operação do LVD: 0 – modo de interrupção 1 – modo de reset * somente é possível escrever 0 quando o LVD opera no modo interrupção e reset!

LVIMD bLVIMD

LVILV Nível de detecção do LVD: 0 – Nível alto (VLVDH) 1 – Nível baixo (VLVDL)

LVILV bLVILV

Suporte à CPU 103

Endereço BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura 0x000C1

Escrita VPOC2 VPOC1 VPOC0 1 LVIS1 LVIS0 LVIMDS1 LVIMDS0

Nome do Bit Descrição Símbolo C Seleção do modo de operação do detector de baixa tensão (LVD):

00 – proibido -

01 – modo interrupção LVD_INT_MODE

10 – modo de interrupção e reset LVD_INTRES_MODE

LVIMDS1 LVIMDS0

11 – modo de reset LVD_RESET_MODE

VPOC2 VPOC1 VPOC0 LVIS1 LVIS0

Veja a tabela abaixo: Veja a tabela abaixo

VLVD/VLVDH VLVDL

Subida Descida Descida*1 VPOC2 VPOC1 VPOC0 LVIS1 LVIS0 Símbolo C

1,67V*2 1,63V - 0 0 0 1 1 LVD_VMODE0

1,77V 1,73V 1,63V 0 0 0 1 0 LVD_VMODE1

1,88V*2 1,84V - 0 0 1 1 1 LVD_VMODE2

1,88V 1,84V 1,63V 0 0 0 0 1 LVD_VMODE3

1,98V 1,94V 1,84V 0 0 1 1 0 LVD_VMODE4

2,09V 2.04V 1,84V 0 0 1 0 1 LVD_VMODE5

2,50V*2 2,45V - 0 1 0 1 1 LVD_VMODE6

2,61V 2,55V 2,45V 0 1 0 1 0 LVD_VMODE7

2,71V 2,65V 2,45V 0 1 0 0 1 LVD_VMODE8

2,81V*2 2,75V - 0 1 1 1 1 LVD_VMODE9

2,92V 2,86V 1,63V 0 0 0 0 0 LVD_VMODE10

2,92V 2,86V 2,75V 0 1 1 1 0 LVD_VMODE11

3,02V 2,96V 2,75V 0 1 1 0 1 LVD_VMODE12

3,13V 3,06V 1,84V 0 0 1 0 0 LVD_VMODE13

3,75V 3,67V 2,45V 0 1 0 0 0 LVD_VMODE14

4,06V 3,98V 2,75V 0 1 1 0 0 LVD_VMODE15

*1 VLVDL é a tensão de reset no modo de interrupção e reset *2 Configuração não permitida quando o LVD opera no modo de interrupção e reset

Tabela 4.4

Microcontroladores RL78: Guia Básico 104

4.6. Watchdog (WDT)

O watchdog ou cão de guarda é um elemento de segurança que visa garantir a correta operação da aplicação.

Ele consiste num temporizador que, ao atingir o tempo máximo (também chamado de estouro de temporização), provoca o reset do microcontrolador.

Para evitar que isso ocorra, inserem-se alguns comandos especiais dentro de determinadas partes do programa. Estes comandos especiais apagam e reiniciam a contagem do watchdog, impedindo que o mesmo estoure e provoque o reset do chip. A idéia é que, caso o programa entre em um estado de erro ou loop, ele deixa de executar os comandos de reinício do watchdog, fazendo com que o mesmo estoure a sua contagem e provoque o reset do microcontrolador.

É claro que existem situações onde um watchdog comum pode não conseguir prevenir uma falha, como por exemplo, se a aplicação entrar em loop num trecho de código que contenha um comando para apagamento do watchdog.

A solução para amenizar este problema é um watchdog com janela de tempo, como o utilizado nos RL78. Neste tipo de dispositivo, o apagamento ou reinício da contagem do watchdog é possível apenas dentro de uma faixa de tempo específica (janela de tempo), a tentativa de executar esta operação fora da janela de tempo provoca o reset do chip.

O watchdog é um dispositivo cujo uso deve ser muito bem avaliado pelo projetista ou programador. A segurança oriunda do seu uso somente terá validade se ele for corretamente configurado.

A quantidade de comandos para reinício do watchdog é também tema para longas e fervorosas discussões. Por um lado poucos comandos para reinício do watchdog podem resultar em resets inesperados, sem que exista uma falha real no software. Comandos em excesso podem resultar na perda da eficácia do dispositivo, permitindo que, mesmo com falhas, o programa continue a ser executado.

Lembre-se: muitas falhas de programas são causadas pelo mal uso do watchdog!

O watchdog utilizado nos RL78 consiste num contador binário de 17 bits alimentado pelo oscilador LOCO (de 15kHz), além de alguns circuitos lógicos que controlam a janela de tempo e as condições de operação do módulo.

As circunstâncias em que o watchdog pode ser ressetado são muito específicas: é necessário escrever o valor 0xAC no registrador WDTE (numa operação de 8 bits) enquanto a janela de escrita está aberta. A escrita de qualquer outro valor ou do valor correto no momento errado provoca o reset do microcontrolador.

A janela de escrita no registrador WDTE pode ser configurada em três diferentes aberturas: 50%, 75% ou 100%. A seleção é feita através dos bits WINDOW1 e WINDOW0 do byte de configuração em 0x000C0. A figura 4.3 mostra a relação entre os bits e a abertura da janela.

Suporte à CPU 105

WINDOW1 WINDOW0 25% 50% 75% 100%

0 1 Fechada Aberta

1 0 Fechada Aberta

1 1 Aberta

Legenda:

Janela fechada (escrita de qualquer valor no WDTE causa reset)

Janela aberta (escrita de 0xAC no WDTE reinicia a contagem do watchdog)

Figura 4.3

Note que, quando é selecionada uma abertura de janela igual a 100%, a funcionalidade de janela do watchdog é desativada, permitindo que ele receba comandos de reinício a qualquer momento.

A temporização do watchdog pode ser configurada através dos bits WDCS2, WDCS1 e WDCS0, variando de aproximadamente 3,71ms até 3,79 segundos.

Opcionalmente é possível também configurar o watchdog para gerar uma interrupção quando ele atinge 75% da sua contagem, desta forma, é possível garantir que os tempos de janela aberta sejam atendidos.

A leitura do registrador WDTE pode retornar dois valores diferentes após o reset, dependendo da configuração do bit WDTON: quando WDTON = 0, o valor de reset do WDTE é igual a 0x1A e quando WDTON = 1, o valor de reset do WDTE é igual a 0x9A!

O watchdog também pode continuar operando quando a CPU entra em um dos modos de baixo consumo de energia (halt, stop ou snooze). Para isso, o bit WDSTBYON deve ser setado no byte de configuração. Caso WDSTBYON = 0, o watchdog é paralisado ao entrar num modo de baixo consumo e a sua contagem reinicia de zero quanto o chio retorna ao modo run.

Quando se utiliza o watchdog é uma boa idéia verificar o registrador RESF no início do programa. O bit WDTRF setado, indicará que o watchdog provocou um reset. Esta informação pode ser utilizada para fornecer algum aviso de falha ao usuário, ou ser registrada na memória flash do microcontrolador para avaliação futura.

A nota de aplicação R01AN0603ED0100 traz muitas informações e detalhes sobre o funcionamento e utilização do watchdog!

Observe que toda a configuração de operação é controlada pelo byte de configuração em 0x000C0, o que significa que, uma vez configurado e ativado, o watchdog não pode ser desativado pela aplicação.

Microcontroladores RL78: Guia Básico 106

Endereço BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura 0x000C0

Escrita WDTINIT WINDOW1 WINDOW0 WDTON WDCS2 WDCS1 WDCS0 WDSTBYON

Nome do Bit Descrição Símbolo C

WDTINIT

Habilitação da interrupção do watchdog: 0 – interrupção desativada 1 – interrupção habilitada (gera interrupção quando a contagem do watchdog chega a 75% do tempo de estouro)

bWDTINIT

Seleção do período de janela aberta do watchdog:

00 – proibido -

01 – 50% WDT_WINDOW50

10 – 75% WDT_WINDOW75

WINDOW1 WINDOW0

11 – 100% WDT_WINDOW100

WDTON Controle de operação do watchdog: 0 – watchdog desativado 1– watchdog ativado

bWDTON

Tempo de estouro do watchdog (considerando a frequência máxima de fIL=17,25kHz)

000 – 26/fIL (±3,71ms) WDT_3ms

001 – 27/fIL (±7,42ms) WDT_7ms

010 – 28/fIL (±14,84ms) WDT_14ms

011 – 29/fIL (±29,68ms) WDT_29ms

100 – 211/fIL (±118,72ms) WDT_118ms

101 – 213/fIL (±474,90ms) WDT_474ms

110 – 214/fIL (±0,9498s) WDT_949ms

WDCS2 WDCS1 WDCS0

111 – 216/fIL (±3,79919s) WDT_3799ms

WDSTBYON Operação do watchdog nos modos halt ou stop: 0 – watchdog parado 1 – watchdog operacional bWDSTBYON

Utilize o símbolo WDT_OFF (definido em myRL78.h) para desativar o watchdog!

4.6.1. Exemplo

O programa a seguir demonstra a utilização do watchdog e da interrupção dele. Na verdade nós não utilizamos a interrupção propriamente dita, mas apenas monitoramos o flag da mesma (um processo chamado de pooling). Quando o programa detecta, no loop principal, que o flag do watchdog (WDTIIF) está setado, ele apaga a contagem do watchdog e o flag, impedindo que o cão de guarda ressete o chip.

Mas quando o usuário pressiona uma tecla ligada ao pino P1.0, aterrando o mesmo, o programa entra num loop de espera, deixando de tratar o watchdog, o que leva o mesmo a estourar e ressetar o chip.

O if no início do programa monitora o estado do bit WDTRF e acende o led quando o reset foi causado pelo watchdog!

Suporte à CPU 107

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog

#pragma location = "OPTBYTE"

__root __far const char config0 = bWDTON|bWDTINIT|WDT_WINDOW50|WDT_3799ms;

// Configura detector de baixa tensão

#pragma location = "OPTBYTE"

__root __far const char config1 = LVD_RESET_MODE | LVD_VMODE15;

// oscilador 4MHz flash low speed

#pragma location = "OPTBYTE"

__root __far const char config2 = FLASH_LS | CLK_4MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char config3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P7_bit.no7

#define TCL P1_bit.no0

unsigned char temp;

void main(void)

CMC = 0; // desativa osciladores X1 e XT1

PM7_bit.no7 = 0; // configura LED como saída

PU1_bit.no0 = 1; // liga pull up do pino P1.0

// faz a leitura do registrador RESF e salva em uma variável temporária

temp = RESF;

// se WDTRF = 1 liga o led, senão apaga

if (temp && bWDTRF) LED = 0; else LED = 1;

while(1)

// caso o flag de interrupção do WDT esteja setado

if (WDTIIF)

WDTE = 0xAC; // apaga o watchdog

WDTIIF = 0; // apaga o flag

while (!TCL); // se a tecla for pressionada, fica em loop

Exemplo 4.4

Microcontroladores RL78: Guia Básico 108

4.7. Regulador Interno de Tensão

Os microcontroladores RL78 incluem um regulador de tensão integrado ao chip. Este regulador fornece uma tensão de saída estabilizada para a CPU e todos os periféricos internos, reduzindo o consumo de energia e reduzindo também a emissão eletromagnética (EMI).

O regulador pode operar em dois modos:

• Baixa potência: neste modo o regulador fornece uma tensão de saída de 2,1V. O regulador entra neste modo quando a memória flash opera em modo HS (alta velocidade) e a CPU está em modo run. Este modo também é selecionado sempre que o depurador (OCD) está em uso;

• Super baixa potência: neste modo o regulador fornece uma tensão de saída de 1,8V. O regulador entra neste modo quando a memória flash opera em modo LV (baixa potência) ou LS (baixa velocidade). Este modo também é selecionado quando a CPU entra em modo stop ou quando a CPU opera com clock secundário e os osciladores X1 e HOCO estão parados.

Para operar corretamente, o regulador interno necessita que um capacitor externo (470nF a 1µF) seja conectado ao pino REGC, conforme mostra a figura 4.4.

Figura 4.4

Alguns modelos não possuem o pino REGC e dispensam o capacitor externo!

Portas de Entrada e Saída 109

5

Portas de Entrada e Saída 5. Portas de Entrada e Saída

As portas de entrada e saída (E/S ou em inglês I/O) são o meio pelo qual a CPU do microcontrolador pode se comunicar com o mundo exterior, controlando circuitos ou dispositivos, lendo informações, etc.

Os microcontroladores RL78 possuem um conjunto de portas de E/S muito interessante, com diversas funções e capacidades integradas.

Uma das características interessantes das portas de E/S destes chips é que elas permitem interface com diferentes níveis de tensão, ou seja, um microcontrolador alimentado por 5V pode se comunicar perfeitamente com um circuito alimentado por 3V.

Esta funcionalidade está disponível primariamente nos chips com pino de alimentação EVDD. Nestes chips os circuitos internos dos pinos P20 a P27, P121 a P124, P137 e P150 a P156 são alimentados pela fonte conectada ao EVDD, desta forma, conecta-se o pino VDD do chip ao potencial de 5V e o pino EVDD ao potencial desejado (1,8 a 5V).

Muitos pinos possuem também sensibilidade selecionável (níveis CMOS ou TTL) e saída configurável (complementar ou dreno aberto), o que também facilita a interconexão com circuitos alimentados por potenciais diferentes daquele do microcontrolador.

Praticamente todos os pinos possuem circuitos Schmitt trigger nas suas entradas, o que garante maior imunidade a ruídos. Lembre-se de que neste tipo de entrada, a comutação de nível lógico ocorre somente quando a tensão de entrada ultrapassa os limiares de comutação. Na zona de indeterminação, o nível lógico anterior é mantido.

Todos os pinos (exceto P60 a P63 e P137) possuem diodos de proteção (clamp) para VDD e VSS que limitam a tensão máxima nas entradas do microcontrolador. Os pinos P60 a P63 possuem somente diodos para VSS. A tabela 5.1 mostra os valores de corrente injetada máxima e média por pino e os valores globais (para todos os pinos).

I máxima por pino I média por pino I média global Tipo de entrada

VIN>VDD VIN<VSS VIN>VDD VIN<VSS

I máxima global VIN>VDD

Pinos digitais 5mA 5mA 400µA 400µA 20mA 4mA

Pinos analógicos 2mA 150µA 150µA 20µA 4mA 1mA

Tabela 5.1

A maioria dos pinos de E/S do RL78 podem fornecer uma corrente individual de 10mA e drenar uma corrente individual de até 20mA (os pinos P20 a P27 e P150 a P156 podem fornecer até 100µA e drenar até 400µA). Este valor de corrente depende da tensão EVDD0 e cai com o

Microcontroladores RL78: Guia Básico 110

decréscimo desta. Note, entretanto, que há um limite global para os pinos: cerca de 135mA de fornecimento e 150mA de drenagem (alguns grupos de pinos possuem valores conjuntos diferentes, consulte o manual de hardware para maiores detalhes).

5.1. Registradores das Portas de E/S

As portas de E/S dos RL78 possuem largura de oito bits e cada uma possui um conjunto de registradores responsáveis pelo controle da sua operação:

• Px – responsável por ler ou escrever nos pinos. A leitura da porta ou de um pino irá retornar, nos pinos configurados como entrada, o nível lógico externo, nos pinos configurados como saída, o valor lido será o último escrito no pino ou porta. A escrita na porta ou num pino irá alterar o estado dos pinos configurados como saída. Nos pinos configurados como entrada, o valor escrito é armazenado no registrador da porta apenas;

• PMx – responsável por controlar a direção de cada pino da porta:

0 – o pino é uma saída digital; 1 – o pino é uma entrada digital;

• PUx – responsável pelo controle dos pull-ups internos (tipicamente 20kΩ, apenas algumas portas possuem resistores de pull-up integrados, veja as tabelas 5.2 e 5.3). Os pull-ups somente podem ser ativados nos pinos configurados como entrada e quando o bit correspondente em POMx está em 0:

0 – pull-up desativado; 1 – pull-up ativado (desde que o bit correspondente em POMx esteja em 0);

Após um reset, o pull-up do pino P40/TOOL0 é ativado, os demais são desativados! Note que o pino P40/TOOL0 seleciona o modo de operação do chip após um reset: quando em nível “0” ele seleciona o modo de gravação/depuração e quando em nível “1” ele seleciona o modo normal de operação.

• PIMx – responsável pela seleção da sensibilidade do buffer de entrada (CMOS ou TTL). Consulte as tabelas 5.2 e 5.3 para verificar quais pinos possuem esta capacidade:

0 – buffer de entrada sensível a níveis CMOS; 1 – buffer de entrada sensível a níveis TTL;

• POMx – responsável pela seleção do tipo de saída do pino (complementar ou dreno aberto). Consulte as tabelas 5.2 e 5.3 para verificar quais pinos possuem esta capacidade:

0 – saída complementar (apenas se o pino estiver configurado como saída); 1 – saída em dreno aberto (apenas se o pino estiver configurado como saída);

• PMCx – seleciona o modo de operação (digital ou analógico) das portas 0, 3, 10, 11, 12 e 14 (veja a tabela 5.5 para identificar os bits implementados):

0 – modo digital; 1 – modo analógico;

Portas de Entrada e Saída 111

• ADPC – seleciona o modo de operação (digital ou analógico) das portas 2 e 15 (veja a tabela 5.4);

• PIOR – controla o redirecionamento de algumas funções digitais;

• GDIDIS – controle global de desativação dos buffers de entrada.

As tabelas 5.2 e 5.3 apresentam os diversos pinos de E/S disponíveis nos modelos até 64 pinos da linha RL78/G13, bem como as funcionalidades presentes em cada um deles.

A coluna E/S mostra as direções possíveis para o pino, a coluna pull-up indica a presença ou não de pull-up interno, a coluna dreno aberto mostra se o pino possui capacidade de saída em dreno aberto (os pinos não marcados possuem apenas a saída complementar, enquanto que os marcados possuem saída complementar ou dreno aberto, selecionável por software).

A coluna TTL/CMOS indica o tipo de buffer de entrada disponível (CMOS, TTL ou ambos) e a coluna Schmitt trigger indica se a entrada possui este tipo de facilidade ou não, as demais colunas mostram as funções analógicas e digitais associadas ao pino, além da configuração padrão após um reset.

Pino E/S Pull-up Dreno Aberto

TTL/

CMOS Schmitt Trigger

Analógico Funções digitais alternativas Funções digitais redirecionadas

Após reset

P00 E/S X X C X ANI17* TI00 - P00 P01 E/S X - T/C X ANI16* TO00 - P01 P02 E/S X X C X ANI17 SO10/TXD1 - ANI17 P03 E/S X X T/C X ANI16 SI10/RXD1/SDA10 - ANI16 P04 E/S X X T/C X - SCK10/SCL10 - P04 P05 E/S X - C X - TI05/TO05 - P05 P06 E/S X - C X - TI06/TO06 - P06 P10 E/S X X T/C X - SCK00/SCL00 TI07/TO07 P10 P11 E/S X X T/C X - SI00/RXD0/TOOLRXD/SDA00 TI06/TO06 P11 P12 E/S X X C X - SO00/TXD0/TOOLTXD INTP5/TI05/TO05 P12 P13 E/S X X T/C X - TXD2/SO20 SDAA0/TI04/TO04 P13 P14 E/S X X T/C X - RXD2/SI20/SDA20 SCLA0/TI03/TO03 P14 P15 E/S X X T/C X - SCK20/SCL20 TI02/TO02 P15 P16 E/S X - T/C X - TI01/TO01/INTP5 SI00/RXD0 P16 P17 E/S X X T/C X - TI02/TO02 SO00/TXD0 P17 P20 E/S - - C - ANI0/AVREFP - - ANI0 P21 E/S - - C - ANI1/AVREFM - - ANI1 P22 E/S - - C - ANI2 - - ANI2 P23 E/S - - C - ANI3 - - ANI3 P24 E/S - - C - ANI4 - - ANI4 P25 E/S - - C - ANI5 - - ANI5 P26 E/S - - C - ANI6 - - ANI6 P27 E/S - - C - ANI7 - - ANI7 P30 E/S X - C X - INTP3/RTC1HZ/SCK11/SCL11 - P30 P31 E/S X - C X - TI03/TO03/INTP4 PCLBUZ0 P31 P40 E/S X - C X - TOOL0 - P40 P41 E/S X - C X - TI07/TO07 - P41 P42 E/S X - C X - TI04/TO04 - P42 P43 E/S X - C X - - - P43 P50 E/S X X C X - INTP1/SI11/SDA11 - P50 P51 E/S X - C X - INTP2/SO11 - P51 P52 E/S X - C X - - INTP10 P52

* Nos chips com 32 pinos ou menos, os pinos P00 e P01 possuem função analógica multiplexada. Nestes chips os pinos P02 e P03 não estão implementados.

Legenda: C=CMOS, T=TTL, T/C = TTL ou CMOS

Tabela 5.2

Microcontroladores RL78: Guia Básico 112

Pino E/S Pull-up Dreno Aberto

TTL/

CMOS Schmitt Trigger Analógico Funções digitais alternativas

Funções digitais redirecionadas

Após reset

P53 E/S X - C X - - INTP11 P53 P54 E/S X - C X - - - P54 P55 E/S X - T/C X - - PCLBUZ1/SCK00 P55 P60 E/S - X*1 C X - SCLA0 - P60 P61 E/S - X*1 C X - SDAA0 - P61 P62 E/S - X*1 C X - - - P62 P63 E/S - X*1 C X - - - P63 P70 E/S X - C X - KR0/SCK21/SCL21 - P70 P71 E/S X X C X - KR1/SI21/SDA21 - P71 P72 E/S X - C X - KR2/SO21 - P72 P73 E/S X - C X - KR3/SO01 - P73 P74 E/S X X C X - KR4/INTP8/SI01/SDA01 - P74 P75 E/S X - C X - KR5/INTP9/SCK01/SCL01 - P75 P76 E/S X - C X - KR6/INTP10 RXD2 P76 P77 E/S X - C X - KR7/INTP11 TXD2 P77 P120 E/S X - C X ANI19 - - ANI19 P121 E - - C X - X1 - P121 P122 E - - C X - X2/ECLK - P122 P123 E - - C X - XT1 - P123 P124 E - - C X - XT2/EXCLKS - P124 P130 S - - - - - *2 - P130 P137 E - - C X - INTP0 - P137 P140 E/S X - C X - PCLBUZ0/INTP6 - P140 P141 E/S X - C X - PCLBUZ1/INTP7 - P141 P146 E/S X - C X - - - P142 P147 E/S X - C X ANI18 - - ANI18

*1 Atenção: os pinos P60 a P63 quando configurados como saídas operam somente em modo dreno aberto!

*2 O pino P130 é mantido em nível lógico 0 durante um reset

Legenda: C=CMOS, T=TTL, T/C = TTL ou CMOS

Tabela 5.3

Lembre-se que os níveis de tensão para “0” e “1” nas portas CMOS e TTL são diferentes. Os pinos configurados como entradas nos RL78 respondem aos seguintes níveis:

Entradas Schmitt Trigger:

CMOS: nível “1” VIN≥80%VDD e nível “0” VIN≤20%VDD TTL (VDD entre 4 e 5,5V): nível “1” VIN≥2,2V e nível “0” VIN≤0,5V TTL (VDD entre 3,3 e 4V): nível “1” VIN≥2,0V e nível “0” VIN≤0,8V TTL (VDD entre 1,6 e 3,3V): nível “1” VIN≥1,5V e nível “0” VIN≤0,32V

Entradas Comuns:

CMOS: nível “1” VIN≥70%VDD e nível “0” VIN≤30%VDD

Vejamos alguns exemplos de configuração dos registradores das portas de E/S dos RL78:

1. Configurar os pinos P10, P11 e P12 como saídas e P13 a P17 como entradas: // Porta = 1, configuração = EEEEESSS ou 11111000 ou 0xF8

PM1 = 0xF8; // configura todos os bits de uma vez

Ou também é possível utilizar uma estrutura de campos de bits definida nos headers de todos os modelos de RL78. Esta estrutura mapeia os oito bits individualmente e permite acesso a qualquer SFR utilizando o seguinte formato: SFR_bit.noX, onde SFR é nome do registrador e X o número do bit (0 a 7).

Portas de Entrada e Saída 113

typedef struct

unsigned char no0:1;

unsigned char no1:1;

unsigned char no2:1;

unsigned char no3:1;

unsigned char no4:1;

unsigned char no5:1;

unsigned char no6:1;

unsigned char no7:1;

__BITS8;

Assim, utilizando a estrutura acima, podemos escrever: // Configura um pino de cada vez (código maior e mais lento):

PM1_bit.no0 = 0;

PM1_bit.no1 = 0;

PM1_bit.no2 = 0;

PM1_bit.no3 = 1;

PM1_bit.no4 = 1;

PM1_bit.no5 = 1;

PM1_bit.no6 = 1;

PM1_bit.no7 = 1;

2. Ligar os pull-ups das entradas P16 e P17 configuradas acima: // Porta = 1, configuração em PU1 = 11000000 ou 0xC0

POM1 = 0; // todas os pinos de P1 como saídas complementares

PU1 = 0xC0; // configura todos os bits de uma vez

3. Setar o pino P11 e apagar P10 e P12: // Podemos escrever bit por bit:

P1_bit.no0 = 0; // P10 = 0

P1_bit.no1 = 1; // P11 = 1

P1_bit.no2 = 0; // P12 = 0

Ou // Podemos escrever em toda a porta (somente os pinos configurados

// como saída serão alterados):

P1 = 2;

4. Ler o pino P17 e setar P11 caso P17 esteja setado: if (P1_bit.no7) P1_bit.no1 = 1;

5. Configurar toda a porta 7 como entrada, ler o seu estado e guardar em uma variável: PM7 = 0xFF; // todos os pinos de P7 como entradas

valor = P7; // lê P7 e guarda em “valor”

6. Configurar os pinos P11 a P13 como saídas (P13 como dreno aberto) e P10 e P14 a P17 como entradas (somente P16 com pull-up interno): // Porta = 1, configuração em PM1 = EEEESSSE ou 11110001 ou 0xF1

PM1 = 0xF1; // P11 a P13 como saídas, o restante como entradas

POM1 = BIT3; // somente P13 como dreno aberto

PU1 = BIT6; // liga pull-up de P16

Microcontroladores RL78: Guia Básico 114

Um cuidado especial deve ser dispensado aos pinos com função analógica multiplexada.

Após um reset, os pinos com função analógica multiplexada são sempre configurados como entradas analógicas! Caso deseje utilizá-los no modo digital, é necessário modificar o registrador relacionado ao mesmo (PMCx ou ADPC).

A seguir temos a configuração do registrador ADPC. Observe que o valor carregado neste registrador configura as entradas analógicas ANI0 a ANI14, conforme indicado na tabela 5.4.

Antes de utilizar as portas 2 e 15 do microcontrolador, é importante configurar este registrador de forma que os pinos sejam configurados para as suas devidas funções (analógicas ou digitais).

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 ADPC3 ADPC2 ADPC1 ADPC0

ADPC

Reset 0 0 0 0 0 0 0 0

Observe ainda que, conforme demonstra a tabela 5.4, não é possível utilizar aleatoriamente qualquer pino na função analógica. Assim, caso seja necessário utilizar, por exemplo, a entrada ANI12 (pino P22) no modo analógico, os pinos P20 e P21 deverão obrigatoriamente operar também na função analógica!

Valor em ADPC

AN

I14/

P15

6

AN

I13/

P15

5

AN

I12/

P15

4

AN

I11/

P15

3

AN

I10/

P15

2

AN

I9/P

151

AN

I8/P

150

AN

I7/P

27

AN

I6/P

26

AN

I5/P

25

AN

I4/P

24

AN

I3/P

23

AN

I2/P

22

AN

I1/P

21

AN

I0/P

20

0 A A A A A A A A A A A A A A A 1 D D D D D D D D D D D D D D D 2 D D D D D D D D D D D D D D A 3 D D D D D D D D D D D D D A A 4 D D D D D D D D D D D D A A A 5 D D D D D D D D D D D A A A A 6 D D D D D D D D D D A A A A A 7 D D D D D D D D D A A A A A A 8 D D D D D D D D A A A A A A A 9 D D D D D D D A A A A A A A A

10 D D D D D D A A A A A A A A A 11 D D D D D A A A A A A A A A A 12 D D D D A A A A A A A A A A A 13 D D D A A A A A A A A A A A A 14 D D A A A A A A A A A A A A A 15 D A A A A A A A A A A A A A A

Tabela 5.4

Os demais pinos analógicos são controlados pelos registradores PMCx, conforme a tabela a seguir. Note que os demais bits dos registradores não estão implementados e devem ser mantidos em 1. Além disso, os registradores PMCx são carregados com o valor 0xFF após um reset.

Portas de Entrada e Saída 115

Bits Implementados Encapsulamento (número de pinos) Porta 14 Porta 12 Porta 11 Porta 10 Porta 3 Porta 0

20 a 25 PMC147 - - - - PMC00 PMC01

30 a 32 PMC147 PMC120 - - - PMC00 PMC01

36 a 48 PMC147 PMC120 - - - -

52 a 64 PMC147 PMC120 - - - PMC02 PMC03

80 a 100 PMC147 PMC120 - PMC100 - PMC02 PMC03

128 PMC147 PMC120 PMC115 PMC116 PMC117

PMC100 PMC35 PMC36 PMC37

PMC02 PMC03

Tabela 5.5

Vejamos mais alguns exemplos de configuração dos registradores das portas de E/S dos RL78:

1. Uma aplicação vai utilizar um RL78 de 20 pinos e necessita de quatro entradas analógicas. Optou-se por utilizar as entradas ANI0 a ANI2 (pinos P20 a P22) e também ANI18 (pino P147) no modo analógico, os demais pinos em modo digital: // Selecionar os pinos P20 a P22 no modo analógico:

ADPC = 4;

// Pino P147 no modo analógico

PMC14_bit.no7 = 1;

// Pinos P00 e P01 no modo digital

PMC0_bit.no0 = 0;

PMC0_bit.no1 = 0;

2. Configurar apenas os pinos P20 a P24 no modo analógico (chip de 64 pinos): // Configura o ADPC

ADPC = 6;

// Configura os demais pinos para o modo analógico

PMC0 = 0xF3 // Pinos P02 e P03 no modo digital

PMC12_bit.no0 = 0; // Pino P120 no modo digital

PMC14_bit.no7 = 0; // Pino P147 no modo digital

3. Configurar todos os pinos para modo digital (chip de 64 pinos): // Configura o ADPC

ADPC = 1;

// Configura os demais pinos para o modo analógico

PMC0 = 0xF3 // Pinos P02 e P03 no modo digital

PMC12_bit.no0 = 0; // Pino P120 no modo digital

PMC14_bit.no7 = 0; // Pino P147 no modo digital

Antes de prosseguirmos, é importante conhecer a função do registrador GDIDIS: ele é utilizado nos casos em que a tensão de alimentação das portas de E/S (através do pino EVDD) pode ser desligada de forma independente da tensão VDD (que alimenta o restante do chip). Assim, as aplicações que podem controlar esta fonte externa de energia devem desativar o GDIDIS (fazendo GDIDIS = 1) após a desativação da alimentação do pino EVDD. Este procedimento evita que flua corrente através dos buffers de entrada neste tipo de situação, nos outros casos, GDIDIS deve estar apagado (GDIDIS = 0).

Microcontroladores RL78: Guia Básico 116

5.2. Redirecionamento de Funções

Outra funcionalidade interessante disponível nos RL78 é a capacidade de redirecionar algumas funções periféricas para diferentes pinos de E/S.

Isto permite que se otimize a disposição de componentes em uma placa de circuito impresso e garante uma maior flexibilidade e liberdade de projeto.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 PIOR5 PIOR4 PIOR3 PIOR2 PIOR1 PIOR0

PIOR

Reset 0 0 0 0 0 0 0 0

As tabelas a seguir mostram as configurações de redirecionamento disponíveis para cada bit do registrador PIOR (os modelos de 20 e 25 pinos não possuem esta função e neles este registrador não está implementado):

128/100 pinos 80 pinos 64 pinos 52 pinos 48 pinos 44 pinos 30 a 40 pinos

Estado do bit PIOR0 Função

0 1 0 1 0 1 0 1 0 1 0 1 0 1 TI02/TO02 P17 P15 P17 P15 P17 P15 P17 P15 P17 P15 P17 P15 P17 P15 TI03/TO03 P31 P14 P31 P14 P31 P14 P31 P14 P31 P14 P31 P14 P31 P14 TI04/TO04 P42 P13 P42 P13 P42 P13 - P13 - P13 - P13 - P13 TI05/TO05 P46 P12 P05 P12 P05 P12 - P12 - P12 - P12 - P12 TI06/TO06 P102 P11 P06 P11 P06 P11 - P11 - P11 - P11 - P11 TI07/TO07 P145 P10 P41 P10 P41 P10 P41 P10 P41 P10 P41 P10 - P10

Tabela 5.6

128/100 pinos 80 pinos 64 pinos 52 pinos 48 pinos 44 pinos 30 a 40 pinos

Estado do bit PIOR1 Função

0 1 0 1 0 1 0 1 0 1 0 1 0 1 INTP10 P76 P110 P76 P110 P76 P52 P76 - - - - - - - INTP11 P77 P111 P77 P111 P77 P53 P77 - - - - - - - TXD2 P13 P77 P13 P77 P13 P77 P13 P77 P13 - P13 - P13 - RXD2 P14 P76 P14 P76 P14 P76 P14 P76 P14 - P14 - P14 - SCL20 P15 - P15 - P15 - P15 - P15 - P15 - P15 - SDA20 P14 - P14 - P14 - P14 - P14 - P14 - P14 -

SI20 P14 - P14 - P14 - P14 - P14 - P14 - P14 - SO20 P13 - P13 - P13 - P13 - P13 - P13 - P13 -

SCK20 P15 - P15 - P15 - P15 - P15 - P15 - P15 - TXD0 P12 P17 P12 P17 P12 P17 P12 P17 P12 P17 P12 P17 P12 P17 RXD0 P11 P16 P11 P16 P11 P16 P11 P16 P11 P16 P11 P16 P11 P16 SCL00 P10 - P10 - P10 - P10 - P10 - P10 - P10 - SDA00 P11 - P11 - P11 - P11 - P11 - P11 - P11 -

SI00 P11 P16 P11 P16 P11 P16 P11 - P11 - P11 - P11 - SO00 P12 P17 P12 P17 P12 P17 P12 - P12 - P12 - P12 -

SCK00 P10 P55 P10 P55 P10 P55 P10 - P10 - P10 - P10 -

Tabela 5.7

Portas de Entrada e Saída 117

128/100 pinos 80 pinos 64 pinos 52 pinos 48 pinos 44 pinos 30 a 40 pinos

Estado do bit PIOR2 Função

0 1 0 1 0 1 0 1 0 1 0 1 0 1 SCLA0 P60 P14 P60 P14 P60 P14 P60 P14 P60 P14 P60 P14 P60 P14 SDAA0 P61 P13 P61 P13 P61 P13 P61 P13 P61 P13 P61 P13 P61 P13

Tabela 5.8

128/100 pinos 80 pinos 64 pinos 52 pinos 48 pinos

Estado do bit PIOR3 Função

0 1 0 1 0 1 0 1 0 1 PCLBUZ0 P140 P31 P140 P31 P140 P31 P140 P31 P140 P31

Tabela 5.9

128/100 pinos 80 pinos 64 pinos

Estado do bit PIOR4 Função

0 1 0 1 0 1 PCLBUZ1 P141 P55 P141 P55 P141 P55

INTP5 P16 P12 P16 P12 P16 P12

Tabela 5.10

128/100 pinos

Estado do bit PIOR5 Função

0 1 INTP1 P46 P56 INTP2 P30 P57 INTP4 P31 P146 INTP6 P140 P84 INTP7 P141 P85 INTP8 P74 P86 INTP9 P75 P87 TXD1 P02 P82 RXD1 P03 P81 SCL10 P04 P80 SDA10 P03 P81

SI10 P03 P81 SO10 P02 P82

SCK10 P04 P80

Tabela 5.11

5.3. Exemplo

O exemplo a seguir mostra como efetuar a leitura de uma tecla conectada ao pino P5.0, ativando o led conectado ao pino P5.2. Na placa utilizada para testes (RSK do RL78/G13) a chave SW1 está conectada ao pino P5.0 e o led D0 está conectado ao pino P5.2.

No caso da placa RSK não é necessário utilizar os resistor de pull-up interno do pino P5.0 pois já existe um resistor externo com esta função.

Microcontroladores RL78: Guia Básico 118

A figura 5.1 mostra o diagrama parcial da placa RSK do RL78/G13.

Figura 5.1

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog

Portas de Entrada e Saída 119

#pragma location = "OPTBYTE"

__root __far const char config0 = WDT_OFF;

// Configura detector de baixa tensão

#pragma location = "OPTBYTE"

__root __far const char config1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char config2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char config3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P5_bit.no2 /* LED no pino P5.2 */

#define SW1 P5_bit.no0 /* tecla no pino P5.0 */

void main(void)

CMC = 0; // desativa osciladores X1 e XT1

PM5_bit.no2 = 0; // configura LED (P5.2) como saída

while (1)

// se SW1 estiver em "0" (fechada) liga o led, caso contrário desliga

if (!SW1) LED=0; else LED=1;

Exemplo 5.1

Microcontroladores RL78: Guia Básico 120

6

Sistema de Interrupções 6. Sistema de Interrupções

Já vimos que um programa é uma sequência de instruções cuja ordem de execução é basicamente a mesma. Apesar de ser possível modificar o fluxo do programa, ou seja, fazer com que determinadas partes do programa sejam executadas ou não, a comunicação entre o ambiente externo ao programa e o programa ocorre sempre em momentos definidos pelo programador (o chamado pooling).

Embora este método funcione razoavelmente bem, há situações onde o programa necessita tomar conhecimento de um evento imediatamente após a sua ocorrência. Interfaces de comunicação serial são exemplos típicos: suponha uma comunicação ocorrendo a uma taxa de 1Mbps. Isto equivale a 125.000 bytes por segundo, ou um byte a cada 8µs! Isto significa que a aplicação tem este tempo para detectar a chegada do novo dado e fazer a leitura do mesmo, antes da chegada de um novo!

Para permitir um rápido tratamento de eventos como este é que existem as interrupções. Uma interrupção consiste basicamente em um evento externo ao programa que provoca o desvio do mesmo para uma sub-rotina ou função especificada pelo programador.

Interrupções são muito similares a chamadas de função em C, de fato, podemos considerar interrupções como chamadas de função executadas pelo hardware, porém, diferentemente de uma função normal, uma função de interrupção não deve ser chamada diretamente pela aplicação.

Outro exemplo interessante de aplicação de interrupções é na temporização, vamos supor que em uma aplicação, deseja-se fazer com que um led pisque a 1Hz para indicar uma condição de erro.

Na abordagem tradicional de programação, as piscadas do led são controladas através de loops do programa, conforme demonstra o fluxograma da figura 6.1. Nele, os blocos “Aguarda 500ms” consistem em loops programados de forma que a sua execução completa ocorra em 500ms.

Este algoritmo deve funcionar perfeitamente e fazer o led piscar como desejado, mas há um problema: a maior parte do tempo útil da CPU é gasto nos dois blocos “Aguarda 500ms”, responsáveis pela temporização do led. De fato, se considerarmos que as operações de ligar e desligar o led são executadas cada uma em 1µs, podemos concluir facilmente que para cada 1 segundo de operação, a CPU passa cerca de 999,998ms (desconsiderando o desvio para o início do loop principal) apenas aguardando a passagem do tempo, sem executar nenhuma tarefa útil.

Sistema de Interrupções 121

Figura 6.1 – Fluxograma de um pisca led

Desta forma conclui-se que a utilização de loops de programa para temporização não é uma saída razoável e pode causar grandes impactos na aplicação.

Existem algumas soluções para este problema: uma delas consiste em utilizar um sistema operacional multitarefa (um RTOS - Real Time Operating System), capaz de executar várias tarefas através da divisão do tempo da CPU. Desta forma um algoritmo como o descrito pode ser executado livremente, ao mesmo tempo em que outras tarefas são executadas “simultaneamente”.

É claro que a adoção de um RTOS não é uma tarefa simples, a maioria deles requer uma boa quantidade de memória flash e RAM para operar. Além disso, RTOSs possuem curvas de aprendizado longas e necessitam de investimento para que possam ser efetivamente utilizados.

Outra opção substancialmente mais simples e econômica para se permitir que se aproveite melhor o tempo da CPU é o uso de interrupções.

Interrupções resolvem questões como a do algoritmo mostrado na figura 6.1 ao permitir que o programa principal possa permanecer executando e seja interrompido num determinado instante (a passagem de 500ms).

É claro que interrupções somente possuem utilidade se tiverem periféricos atrelados a elas. Os RL78 possuem diversos periféricos capazes de gerar diferentes interrupções: os timers podem interromper a CPU para sinalizar a passagem de tempo, captura de um pulso, etc., as interfaces de comunicação podem interromper a CPU ao receber ou enviar um dado, o conversor A/D pode interromper a CPU ao terminar de fazer uma conversão, etc.

Ainda com relação ao algoritmo da figura 6.1, através de um timer e do uso de interrupções, seria possível fazer toda a temporização de piscagem do led dentro de uma ISR (rotina de tratamento de interrupção), fazendo com que a CPU permanecesse liberada para outros usos cerca de 99,999% do tempo!

Início

Liga led

Aguarda 500ms

Desliga led

Aguarda 500ms

Microcontroladores RL78: Guia Básico 122

6.1. Categorias de Interrupções

Podemos classificar as interrupções em duas categorias básicas: mascaráveis e não mascaráveis. Interrupções mascaráveis são aquelas que podem ser desativadas ou ignoradas pela CPU, ao passo que as não mascaráveis não podem ser desativadas e nunca são ignoradas pela CPU.

Também podemos classificar as interrupções em externas e internas: internas são as interrupções geradas pelos periféricos internos do microcontrolador e externas são aquelas geradas por eventos externos e recebidas normalmente através de pinos de interrupção.

Existe também uma categoria especial de interrupção chamada de interrupção por software. Nesta categoria a origem da interrupção não é um periférico ou pino de hardware, mas uma instrução assembly especial.

Interrupções por software são especialmente úteis na implementação de chamadas de sistema em sistemas operacionais.

6.2. Sistema de Interrupções do RL78

Os microcontroladores RL78 possuem um sistema de interrupções bastante poderoso e similar ao existente em modelos de 32 bits existentes no mercado. Ele é composto por um sistema de vetores (a maioria das interrupções possuem vetores individuais para onde o programa é desviado no caso da ocorrência de uma interrupção) e cada fonte de interrupção possui prioridade programável.

É possível selecionar um entre quatro níveis de prioridade (0 a 3) para cada interrupção, sendo que o nível 0 é o de maior prioridade e o nível 3 o de menor prioridade.

O sistema de múltiplas prioridades permite que, caso duas interrupções aconteçam simultaneamente, a de maior prioridade tenha preferência a de menor prioridade. Também é possível que uma interrupção de maior prioridade interrompa uma interrupção de menor prioridade que se encontre em tratamento.

O sistema de interrupções dos RL78 é similar ao dos seus concorrentes: temos um controle global de interrupções (bit IE no registrador PSW), controles individuais de mascaramento de interrupção (bits MK nos registradores MKxL e MKxH) e flags de interrupção (bits IF nos registradores IFxL e IFxH). A figura 6.2 mostra um diagrama funcional simplificado do controle de interrupções dos RL78.

Os flags de interrupção (localizados nos registradores IFxL e IFxH) são setados automaticamente pelos eventos de interrupção dos periféricos, por exemplo, o flag PIF0 (registrador IF0L) é setado numa transição do pino INTP0, já o flag TMIF00 (registrador IF1L) é setado quando ocorre o estouro de contagem ou captura de sinal no canal 0 do timer TAU0.

Cada flag de interrupção de periférico é aplicado a uma porta AND responsável pelo mascaramento da interrupção. O bit de mascaramento (MK) é controlado por um dos

Sistema de Interrupções 123

registradores MKxL ou MKxH. Assim, nos exemplos acima, o controle de mascaramento da interrupção INTP0 é o PMK0, localizado no registrador MK0L e o controle de mascaramento da interrupção do canal 0 do TAU0 é o TMMK00, localizado no registrador MK1L.

Figura 6.2

Observe que quando o bit de mascaramento está setado (MK=1) a interrupção está mascarada (desabilitada), ao passo que quando o bit está apagado (MK=0) a interrupção não está mascarada e está habilitada! Este controle é invertido em relação aos controles de habilitação de interrupção disponíveis em microcontroladores de outros fabricantes.

As interrupções periféricas que não se encontrem mascaradas, somente poderão interromper a CPU caso o bit IE = 1 (registrador PSW). Quando IE = 0, a CPU não pode ser interrompida, exceto por uma interrupção por software (instrução BRK, que não pode ser mascarada). Além disso, uma interrupção somente será reconhecida se o nível de prioridade dela for maior ou igual ao nível de prioridade atual (configurado nos bits ISP0 e ISP1 do PSW).

Observe também que, conforme ilustra a figura 6.2, qualquer sinal de interrupção, mesmo quando IE = 0, faz com que o microcontrolador retorne ao modo ativo (run), caso a CPU se encontre em um modo de baixo consumo de energia (halt, stop ou snooze).

Uma vez reconhecida a interrupção, ocorre o salvamento do conteúdo do PSW e do PC na pilha, o bit IE é apagado (desabilitando novas interrupções), a prioridade da interrupção que foi reconhecida é salva nos bits ISP0 e ISP1 (registrador PSW), o programa é desviado para o endereço apontado pelo respectivo vetor e o flag da interrupção é automaticamente apagado.

A rotina de tratamento de interrupção (ISR) deve ser encerrada com uma instrução RETI (para as interrupções mascaráveis) ou RETB (para a interrupção por software BRK).

As tabelas 6.1 e 6.2 a seguir apresentam os vetores de interrupção disponíveis nos RL78/G13. São apresentados os nomes dos vetores, os flags de interrupção (com os respectivos registradores que os abrigam), bits de mascaramento de interrupção (e respectivos registradores), além da descrição da fonte de cada interrupção.

Microcontroladores RL78: Guia Básico 124

Número do Vetor Endereço Nome Flag Máscara Fonte

- 0x00000

RST POR LVD WDT TRAP IAW RPE

- -

RESF:LVIRF RESF:WDTRF RESF:TRAP

RESF:IAWRF RESF:RPERF

- - - - -

IAWCTL:IAWEN RPECTL:RPERDIS

Pino de reset POR LVD

Watchdog Opcode ilegal

Acesso ilegal a memória Erro de paridade da RAM

- 0x00002 DBG - - On chip debugger (OCD) 0 0x00004 INTWDTI IF0L:WDTIIF MK0L:WDTIMK Watchdog 1 0x00006 INTLVI IF0L:LVIIF MK0L:LVIMK Detecção de baixa tensão 2 0x00008 INTP0 IF0L:PIF0 MK0L:PMK0 Pino INTP0 3 0x0000A INTP1 IF0L:PIF1 MK0L:PMK1 Pino INTP1 4 0x0000C INTP2 IF0L:PIF2 MK0L:PMK2 Pino INTP2 5 0x0000E INTP3 IF0L:PIF3 MK0L:PMK3 Pino INTP3 6 0x00010 INTP4 IF0L:PIF4 MK0L:PMK4 Pino INTP4 7 0x00012 INTP5 IF0L:PIF5 MK0L:PMK5 Pino INTP5

8 0x00014 INTST2

INTCSI20 INTIIC20

IF0H:STIF2 IF0H:CSIIF20 IF0H:IICIF20

MK0H:STMK2 MK0H:CSIMK20 MK0H:IICMK20

TX UART2 Transferência CSI20 Transferência IIC20

9 0x00016 INTSR2

INTCSI21 INTIIC21

IF0H:SRIF2 IF0H:CSIIF21 IF0H:IICIF21

MK0H:SRMK2 MK0H:CSIMK21 MK0H:IICMK21

RX UART2 Transferência CSI21 Transferência IIC21

10 0x00018 INTSRE2

INTTM11H IF0H:SREIF2

IF0H:TMIF11H MK0H:SREMK2

MK0H:TMMK11H Erro RX UART2

Estouro ou captura no canal 1 do TAU1 (8 bits superiores) 11 0x0001A INTDMA0 IF0H:DMAIF0 MK0H:DMAMK0 Fim de transferência no DMA0 12 0x0001C INTDMA1 IF0H:DMAIF1 MK0H:DMAMK1 Fim de transferência no DMA1

13 0x0001E INTST0

INTCSI00 INTIIC00

IF0H:STIF0 IF0H:CSIIF00 IF0H:IICIF00

MK0H:STMK0 MK0H:CSIMK00 MK0H:IICMK00

TX UART0 Transferência CSI00 Transferência IIC00

14 0x00020 INTSR0

INTCSI01 INTIIC01

IF0H:SRIF0 IF0H:CSIIF01 IF0H:IICIF01

MK0H:SRMK0 MK0H:CSIMK01 MK0H:IICMK01

RX UART0 Transferência CSI01 Transferência IIC01

15 0x00022 INTSRE0

INTTM01H IF0H:SREIF0

IF0H:TMIF01H MK0H:SREMK0

MK0H:TMMK01H Erro RX UART0

Estouro ou captura no canal 1 do TAU0 (8 bits superiores)

16 0x00024 INTST1

INTCSI10 INTIIC10

IF1L:STIF1 IF1L:CSIIF10 IF1L:IICIF10

MK1L:STMK1 MK1L:CSIMK10 MK1L:IICMK10

TX UART1 Transferência CSI10 Transferência IIC10

17 0x00026 INTSR1

INTCSI11 INTIIC11

IF1L:SRIF1 IF1L:CSIIF11 IF1L:IICIF11

MK1L:SRMK1 MK1L:CSIMK11 MK1L:IICMK11

RX UART1 Transferência CSI11 Transferência IIC11

18 0x00028 INTSRE1

INTTM03H IF1L:SREIF1

IF1L:TMIF03H MK1L:SREMK1

MK1L:TMMK03H Erro RX UART1

Estouro ou captura no canal 3 do TAU0 (8 bits superiores) 19 0x0002A INTIICA0 IF1L:IICAIF0 MK1L:IICAMK0 Fim de comunicação em IICA0 20 0x0002C INTTM00 IF1L:TMIF00 MK1L:TMMK00 Estouro ou captura no canal 0 do TAU0 21 0x0002E INTTM01 IF1L:TMIF01 MK1L:TMMK01 Estouro ou captura no canal 1 do TAU0 22 0x00030 INTTM02 IF1L:TMIF02 MK1L:TMMK02 Estouro ou captura no canal 2 do TAU0 23 0x00032 INTTM03 IF1L:TMIF03 MK1L:TMMK03 Estouro ou captura no canal 3 do TAU0 24 0x00034 INTAD IF1H:ADIF MK1H:ADMK Fim de conversão no ADC 25 0x00036 INTRTC IF1H:RTCIF MK1H:RTCMK Alarme ou período do RTC 26 0x00038 INTIT IF1H:ITIF MK1H:ITMK Estouro do timer de intervalo 27 0x0003A INTKR IF1H:KRIF MK1H:KRMK Mudança de estado nas entradas KR

28 0x0003C INTST3

INTCSI30 INTIIC30

IF1H:STIF1 IF1H:CSIIF10 IF1H:IICIF10

MK1H:STMK1 MK1H:CSIMK10 MK1H:IICMK10

TX UART3 Transferência CSI30 Transferência IIC30

29 0x0003E INTSR3

INTCSI31 INTIIC31

IF1H:SRIF3 IF1H:CSIIF31 IF1H:IICIF31

MK1H:SRMK3 MK1H:CSIMK31 MK1H:IICMK31

RX UART3 Transferência CSI31 Transferência IIC31

30 0x00040 INTTM13 IF1H:TMIF13 MK1H:TMMK13 Estouro ou captura no canal 3 do TAU1 31 0x00042 INTTM04 IF1H:TMIF04 MK1H:TMMK04 Estouro ou captura no canal 4 do TAU0 32 0x00044 INTTM05 IF2L:TMIF05 MK2L:TMMK05 Estouro ou captura no canal 5 do TAU0 33 0x00046 INTTM06 IF2L:TMIF06 MK2L:TMMK06 Estouro ou captura no canal 6 do TAU0 34 0x00048 INTTM07 IF2L:TMIF07 MK2L:TMMK07 Estouro ou captura no canal 7 do TAU0 35 0x0004A INTP6 IF2L:PIF6 MK2L:PMK6 Pino INTP6 36 0x0004C INTP7 IF2L:PIF7 MK2L:PMK7 Pino INTP7 37 0x0004E INTP8 IF2L:PIF8 MK2L:PMK8 Pino INTP8 38 0x00050 INTP9 IF2L:PIF9 MK2L:PMK9 Pino INTP9

Tabela 6.1

Sistema de Interrupções 125

Número do Vetor Endereço Nome Flag Máscara Fonte

39 0x00052 INTP10 IF2L:PIF10 MK2L:PMK10 Pino INTP10 40 0x00054 INTP11 IF2H:PIF11 MK2H:PMK11 Pino INTP11 41 0x00056 INTTM10 IF2H:TMIF10 MK2H:TMMK10 Estouro ou captura no canal 0 do TAU1 42 0x00058 INTTM11 IF2H:TMIF11 MK2H:TMMK11 Estouro ou captura no canal 1 do TAU1 43 0x0005A INTTM12 IF2H:TMIF12 MK2H:TMMK12 Estouro ou captura no canal 2 do TAU1

44 0x0005C INTSRE3

INTTM13H IF2H:SREIF3

IF2H:TMIF13H MK2H:SREMK3

MK2H:TMMK13H Erro RX UART3

Estouro ou captura no canal 3 do TAU1 (8 bits superiores) 45 0x0005E INTMD IF2H:MDIF MK2H:MDMK Fim de divisão ou overflow 46 0x00060 INTIICA1 IF2H:IICAIF1 MK2H:IICAMK1 Fim de comunicação em IICA1 47 0x00062 INTFL IF2H:FLIF MK2H:FLMK Utilizada pela biblioteca FSL 48 0x00064 INTDMA2 IF3L:DMAIF2 MK3L:DMAMK2 Fim de transferência no DMA2 49 0x00066 INTDMA3 IF3L:DMAIF3 MK3L:DMAMK3 Fim de transferência no DMA3 50 0x00068 INTTM14 IF3L:TMIF14 MK3L:TMMK14 Estouro ou captura no canal 4 do TAU1 51 0x0006A INTTM15 IF3L:TMIF15 MK3L:TMMK15 Estouro ou captura no canal 5 do TAU1 52 0x0006C INTTM16 IF3L:TMIF16 MK3L:TMMK16 Estouro ou captura no canal 6 do TAU1 53 0x0006E INTTM17 IF3L:TMIF17 MK3L:TMMK17 Estouro ou captura no canal 7 do TAU1 - 0x0007E BRK - - Instrução BRK

Tabela 6.2

Observe que alguns vetores são compartilhados por mais de um periférico. Neste caso, somente um deles deve utilizar a sua função de interrupção!

A utilização das interrupções em C é muito simples. A declaração da ISR deve ser feita da seguinte forma:

#pragma vector = NOME_DO_VETOR

__interrupt void NOME_DA_FUNCAO(void)

// o código da ISR vai aqui

Observe que o #pragma vector antes da declaração da ISR instrui o compilador sobre qual o vetor de interrupção deve ser associado à função. Em NOME_DO_VETOR o programador deverá colocar o nome (conforme a coluna “nome” nas tabelas 6.1 e 6.2) seguido do sufixo _vect. Desta forma temos INTWDTI_vect para a interrupção do watchdog, INTP0_vect para a interrupção externa do pino INTP0, INTTM00_vect para a interrupção do canal 0 do TAU0 e assim por diante.

Os bits de mascaramento de interrupção podem ser configurados diretamente através dos seus nomes conforme mostrado nas tabelas 6.1 e 6.2. Assim, para habilitar a interrupção do canal 0 do TAU0 podemos escrever:

TMMK00 = 0; // habilita a interrupção do canal 0 do TAU0

E para desabilitar (mascarar) a mesma interrupção podemos escrever: TMMK00 = 1; // desabilita a interrupção do canal 0 do TAU0

A habilitação global das interrupções (bit IE no registrador PSW) pode ser controlada através de duas funções intrínsecas definidas no arquivo intrinsics.h:

__enable_interrupt(); // habilita interrupções (IE=1)

__disable_interrupt(); // desabilita interrupções (IE=0)

Microcontroladores RL78: Guia Básico 126

6.2.1. Sistema de Prioridades de Interrupção

Como já vimos, os RL78 possuem um sistema com quatro diferentes prioridades de interrupção. O nível de prioridade de cada fonte de interrupção é selecionado através de dois bits localizados cada um num dos registradores PR0xx e PR1xx, conforme as tabelas a seguir. Lembre-se de que, após um reset, todos os bits destes registradores são setados, fazendo com que todas as interrupções possuam prioridade 3 (a mais baixa).

Bit PR10L PR00L Prioridade de interrupção do 0 WDTIPR1 WDTIPR0 Watchdog 1 LVIPR1 LVIPR0 LVD 2 PPR10 PPR00 INTP0 3 PPR11 PPR01 INTP1 4 PPR12 PPR02 INTP2 5 PPR13 PPR03 INTP3 6 PPR14 PPR04 INTP4 7 PPR15 PPR05 INTP5

Bit PR10H PR00H Prioridade de interrupção do

0 STPR12

CSIPR120 IICPR120

STPR02 CSIPR020 IICPR020

TX UART2 CSI20 IIC20

1 SRPR12

CSIPR121 IICPR121

SRPR02 CSIPR021 IICPR021

RX UART2 CSI21 IIC21

2 SREPR12

TMPR111H SREPR02

TMPR011H Erro RX USART2

TAU1 canal 1 (8 bits MSB) 3 DMAPR10 DMAPR00 DMA0 4 DMAPR11 DMAPR01 DMA1

5 STPR10

CSIPR100 IICPR100

STPR00 CSIPR000 IICPR000

TX UART0 CSI00 IIC00

6 SRPR10

CSIPR101 IICPR101

SRPR00 CSIPR001 IICPR001

RX UART0 CSI01 IIC01

7 SREPR10

TMPR101H SREPR00

TMPR001H Erro RX USART0

TAU0 canal 1 (8 bits MSB) Bit PR11L PR01L Prioridade de interrupção do

0 STPR11

CSIPR110 IICPR110

STPR01 CSIPR010 IICPR010

TX UART1 CSI10 IIC10

1 SRPR11

CSIPR111 IICPR111

SRPR01 CSIPR011 IICPR011

RX UART1 CSI11 IIC11

2 SREPR11

TMPR103H SREPR01

TMPR003H Erro RX USART1

TAU0 canal 3 (8 bits MSB) 3 IICAPR10 IICAPR00 IICA0 4 TMPR100 TMPR000 TAU0 canal 0 5 TMPR101 TMPR001 TAU0 canal 1 6 TMPR102 TMPR002 TAU0 canal 2 7 TMPR103 TMPR003 TAU0 canal 3

Tabela 6.3

Sistema de Interrupções 127

Bit PR11H PR01H Prioridade de interrupção do 0 ADPR1 ADPR0 ADC 1 RTCPR1 RTCPR0 RTC 2 ITPR1 ITPR0 Timer de intervalo 3 KRPR1 KRPR0 Interrupção de teclado

4 STPR13

CSIPR130 IICPR130

STPR03 CSIPR030 IICPR030

TX UART3 CSI30 IIC30

5 SRPR13

CSIPR131 IICPR131

SRPR03 CSIPR031 IICPR031

RX UART3 CSI31 IIC31

6 TMPR113 TMPR013 TAU1 canal 3 7 TMPR104 TMPR004 TAU0 canal 4

Bit PR12L PR02L Prioridade de interrupção do 0 TMPR105 TMPR005 TAU0 canal 5 1 TMPR106 TMPR006 TAU0 canal 6 2 TMPR107 TMPR007 TAU0 canal 7 3 PPR16 PPR06 INTP6 4 PPR17 PPR07 INTP7 5 PPR18 PPR08 INTP8 6 PPR19 PPR09 INTP9 7 PPR110 PPR010 INTP10

Bit PR12H PR02H Prioridade de interrupção do 0 PPR111 PPR011 INTP11 1 TMPR110 TMPR010 TAU1 canal 0 2 TMPR111 TMPR011 TAU1 canal 1 3 TMPR112 TMPR012 TAU1 canal 2

4 SREPR13

TMPR113H SREPR03

TMPR013H Erro RX USART3

TAU1 canal 3 (8 bits MSB) 5 MDPR1 MDPR0 Multiplicador/divisor 6 IICAPR11 IICAPR01 IICA 7 FLPR1 FLPR0 Biblioteca FSL

Tabela 6.4

Vejamos como configurar a prioridade de interrupção do LVD para nível 1: LVIPR1 = 0;

LVIPR0 = 1;

Configurar interrupção do canal 2 do TAU1 para prioridade 0: TMPR112 = 0;

TMPR012 = 0;

Atenção: caso ocorram duas ou mais interrupções de mesma prioridade e ao mesmo tempo, a primeira a ser tratada é aquela com o menor número de vetor (primeira coluna das tabelas 6.1 e 6.2)! As demais interrupções pendentes serão tratadas cada uma após o término do tratamento da anterior.

A utilização de diferentes prioridades para as ISRs torna-se mais eficiente quando uma interrupção de maior prioridade pode interromper uma (ou mais) de menor prioridade. Para que isso seja possível nos RL78, basta habilitar as interrupções globais logo no início da(s) ISR(s) de baixa prioridade:

Microcontroladores RL78: Guia Básico 128

#pragma vector = XXXX_vect

__interrupt void trata_int_baixa_prioridade(void)

__enable_interrupt(); // esta ISR pode ser interrompida! // código da ISR

#pragma vector = XXXX_vect

__interrupt void trata_int_alta_prioridade(void)

// código da ISR

Lembre-se que uma interrupção com prioridade 3 pode ser interrompida por outras de prioridade 0, 1, 2 ou 3, uma interrupção de prioridade 2 pode ser interrompida por outras de prioridade 0, 1 ou 2 e assim por diante. As interrupções de mais alta prioridade (0) somente podem ser interrompidas por outras interrupção de alta prioridade!

6.2.2. Latência de Interrupção

Todo microcontrolador ou microprocessador necessita de um certo tempo entre a ocorrência do evento de interrupção e o efetivo processamento da primeira instrução útil da ISR. Este intervalo de tempo é chamado de latência de interrupção.

A latência de interrupção decorre de vários fatores:

1. O circuito de controle de interrupção precisa reconhecer a interrupção (verificar se a mesma está habilitada, decodificar seu vetor, etc.);

2. A CPU precisa completar a instrução em execução (salvo algumas máquinas e instruções especiais que podem ser interrompidas e retomadas posteriormente);

3. Deve ocorrer o salvamento básico de contexto (normalmente o contador e programa e registrador de status, PC e PSW no caso do RL78);

Nos RL78, a latência base de interrupção varia de 9 ciclos de clock (mínimo) a 14 ciclos de clock (máximo), conforme a instrução em execução e a instrução seguinte a mesma (algumas instruções bloqueiam temporariamente as interrupções).

A esta latência base, devemos considerar também o tempo necessário ao salvamento de contexto no caso (salvamento dos registradores de propósito geral da CPU), que pode acrescer de 1 a 4 ciclos de clock aos tempos supracitados.

Quanto menor a latência, mais rápida a resposta do microcontrolador aos eventos de interrupção!

Sistema de Interrupções 129

6.2.3. Utilizando os Bancos de Registradores dos RL78

Como já vimos no capítulo 3, a CPU RL78 possui quatro bancos de registradores de propósito geral, estes registradores são utilizados pelas operações cotidianas da aplicação e por isso, são sempre salvos automaticamente pelo compilador no início da ISR (salvamento de contexto) e restaurados antes do retorno da mesma (restauração de contexto).

Vejamos um exemplo: suponha a ISR a seguir.

#pragma vector = INTTM00_vect

__interrupt void trata_tau00(void)

teste *=3;

Ela gera o seguinte código assembly: PUSH AX PUSH BC

MOVW AX, N:teste

MOVW BC, #0x3

CALL N:?I_MUL_L02

MOVW N:teste, AX

POP BC POP AX RETI

Como o código da ISR altera os registradores AX e BC, o conteúdo prévio dos mesmos é salvo na pilha pelas duas primeiras instruções PUSH e restaurado pelas instruções POP antes de retornar da interrupção (RETI).

Estas quatro instruções são executadas cada uma em apenas um ciclo de clock, mas adicionam à latência de interrupção um atraso que pode ser significativo (no caso dos dois PUSH) e aumentam o tempo de execução da ISR.

Utilizando-se um banco alternativo de registradores, podemos fazer com que o compilador remova estas instruções, reduzindo a latência de interrupção e reduzindo o tempo de execução da ISR, o que se traduz em aumento da performance da aplicação. Para utilizar outro banco de registradores na ISR, basta utilizar a diretiva #pragma bank antes da declaração da mesma:

#pragma bank=1

#pragma vector = XXXXXX_vect

__interrupt void trata_int(void)

teste *=3;

Vejamos o código assembly gerado: SEL RB1 MOVW AX, N:teste

MOVW BC, #0x3

CALL N:?I_MUL_L02

MOVW N:teste, AX

RETI

Microcontroladores RL78: Guia Básico 130

É fácil perceber que as quatro instruções de salvamento e restauração dos GPRs foram substituídas por apenas uma instrução de seleção de banco (SEL RB1), que é executada em apenas um ciclo de clock. Isto significa redução de código e aumento de performance!

Veja que o banco 1 é selecionado por SEL RB1 no início da ISR, mas como o programa retorna ao banco 0 (ou o banco em que se encontrava) após a ISR? Simples: a instrução RETI restaura o PSW da pilha (ele foi salvo automaticamente pela interrupção). O banco de registradores utilizado antes da ISR está especificado nos bits RBS1 e RBS0 do PSW, fazendo com que o banco de registradores utilizado no momento da interrupção seja restaurado juntamente com o PSW!

Também é possível utilizar outros bancos (como o 2 e 3) para outras ISRs. Isto é especialmente útil quando temos ISRs de prioridades diferentes e encadeadas, onde uma ISR de alta prioridade pode interromper uma de baixa prioridade:

#pragma bank=1

#pragma vector = XXXX_vect

__interrupt void trata_int_baixa_prioridade(void)

__enable_interrupt(); // esta ISR pode ser interrompida!

// código da ISR

#pragma bank=2

#pragma vector = XXXX_vect

__interrupt void trata_int_alta_prioridade(void)

// código da ISR

6.3. Interrupções Externas

Os microcontroladores RL78 podem incluir até doze pinos de interrupção externa, batizados de INTP0 a INTP11. Cada pino pode ser configurado para gerar uma interrupção ao detectar uma borda de subida, de descida ou ambas as bordas. Além disso, cada pino possui um vetor de interrupção individual, permitindo o rápido processamento deste tipo de interrupção.

Pino Interrupção Externa

P137 INTP0

P50 INTP1

P51 INTP2

P30 INTP3

P31 INTP4

P16/(P12*) INTP5

P140 INTP6

P141 INTP7

P74 INTP8

P75 INTP9

P76/(P52*) INTP10

P77/(P53*) INTP11

* Pinos alternativos (via redirecionamento de função)

Tabela 6.5

Sistema de Interrupções 131

A configuração dos pinos de interrupção externa é muito simples: cada pino possui dois bits de controle, EGPx e EGNx, o bit EGPx, quando setado, ativa a sensibilidade positiva (borda de subida ou transição de “0” para “1”), enquanto que o bit EGNx, quando setado, ativa a sensibilidade negativa (borda de descida ou transição de “1” para “0”). Quando os dois bits estão apagados, a função de interrupção externa está desativada e quando os dois estão setados, ocorre interrupção em quaisquer das bordas.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura EGP0

Escrita EGP7 EGP6 EGP5 EGP4 EGP3 EGP2 EGP1 EGP0

Leitura EGN0

Escrita EGN7 EGN6 EGN5 EGN4 EGN3 EGN2 EGN1 EGN0

Reset 0 0 0 0 0 0 0 0

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura EGP1

Escrita 0 0 0 0 EGP11 EGP10 EGP9 EGP8

Leitura EGN1

Escrita 0 0 0 0 EGN11 EGN10 EGN9 EGN8

Reset 0 0 0 0 0 0 0 0

EGPx EGNx Modo de interrupção

0 0 Desabilitada 0 1 Borda de descida 1 0 Borda de subida 1 1 Ambas as bordas

Tabela 6.6

Para configurar a interrupção de borda de subida no pino INTP2, podemos escrever: EGP0 = 0x04; // seleciona a borda de subida no INTP2

PIF2 = 0; // apaga o flag de interrupção do INTP2

PMK2 = 0; // habilita a interrupção externa INTP2

Ou EGP0 = BIT2; // seleciona a borda de subida no INTP2

PIF2 = 0; // apaga o flag de interrupção do INTP2

PMK2 = 0; // habilita a interrupção externa INTP2

Lembre-se de que após configurar a borda de sensibilidade do pino, é importante apagar o flag da interrupção, que pode ter sido setado pela alteração da configuração do pino. Isto deve ser feito antes de se habilitar a interrupção externa!

Outro detalhe interessante acerca dos RL78: os pinos de interrupção externa podem operar neste modo inclusive quando estão configurados como saídas! Neste caso, uma interrupção externa poderá ser gerada quando um periférico ou o software alterar o estado daquele pino.

Para que uma transição seja detectada corretamente, é necessário que, após a mesma, o sinal no pino permaneça estável por um período mínimo de 1µs!

Microcontroladores RL78: Guia Básico 132

6.3.1. Exemplo

O exemplo a seguir demonstra como utilizar as interrupções externas INTP1 e INTP2. O estado do led 3 da placa RSK é controlado por meio de duas teclas: a tecla SW1 (conectada ao pino P5.0/INTP1) acende o led e a tecla SW2 (conectada ao pino P5.1/INTP2) apaga o mesmo. Os resistores internos de pull-up não foram utilizados porque a placa provê resistores externos para esta função (vide figura 5.1).

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P6_bit.no3

#pragma vector = INTP1_vect

__interrupt void trata_INTP1(void)

LED = 0; // acende led

#pragma vector = INTP2_vect

__interrupt void trata_INTP2(void)

LED = 1; // apaga led

void main(void)

PM6_bit.no3 = 0; // configura LED como saída

EGN0 = BIT2 | BIT1; // INTP1 e INTP2 na borda de descida

PIF1 = 0; // apaga flag da INTP1

PIF2 = 0; // apaga flag da INTP2

PMK1 = 0; // habilita INTP1

PMK2 = 0; // habilita INTP2

LED = 1; // led desligado

__enable_interrupt(); // habilita interrupções globais

while (1);

Exemplo 6.1

Sistema de Interrupções 133

6.4. Interrupção de Teclado

O módulo de interrupção de teclado (KR) é utilizado para gerar uma interrupção (KRIF) quando qualquer uma das suas oito entradas muda de estado (borda de descida, ou seja, mudança de nível lógico alto para nível lógico baixo).

Esta facilidade é especialmente útil para se detectar o pressionamento de teclas e provocar a saída de um modo de baixo consumo.

A operação do módulo KR é muito simples: cada bit do registrador KRM controla uma das entradas de interrupção. Quando o bit KRMx está apagado, o respectivo pino de E/S não gera interrupção KRIF, quando o bit KRMx está setado, então uma borda de descida no respectivo pino de E/S irá setar o flag KBIF.

A tabela a seguir mostra os pinos associados ao módulo de interrupção de teclado.

Pino Entrada

P70 KR0

P71 KR1

P72 KR2

P73 KR3

P74 KR4

P75 KR5

P76 KR6

P77 KR7

Tabela 6.7

A seguir temos o diagrama do registrador KRM, utilizado para controlar a operação das entradas de interrupção do módulo.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita KRM7 KRM6 KRM5 KRM4 KRM3 KRM2 KRM1 KRM0

KRM

Reset 0 0 0 0 0 0 0 0

É necessário que o sinal de entrada permaneça estável (em nível lógico “0”) por um período mínimo de 250ns (para tensões de alimentação superiores a 1,8V) ou 1µs (para tensões menores que 1,8V)!

6.4.1. Exemplo

O próximo exemplo mostra a implementação do exemplo 6.1 mas utilizando a interrupção de teclado ao invés das interrupções externas.

O exemplo foi escrito para a placa RPB do RL78/G13 e necessita que duas teclas sejam conectadas aos pinos P7.0 e P7.1 (de cada pino para o GND). Os pull-ups internos são ativados, de forma que apenas é necessário conectar teclas a placa RPB.

Microcontroladores RL78: Guia Básico 134

Observe que em razão de existir apenas um vetor de interrupção, é necessário testar, dentro da ISR, qual pino está em nível lógico baixo, de forma a determinar qual tecla foi pressionada. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P7_bit.no7

#define PIN_P70 P7_bit.no0

#define PIN_P71 P7_bit.no1

#pragma vector = INTKR_vect

__interrupt void trata_intkr(void)

if (!PIN_P70) LED = 0; // acende led

if (!PIN_P71) LED = 1; // apaga led

void main(void)

PM7_bit.no7 = 0; // configura LED como saída

PU7 = BIT1 | BIT0; // ativa pull-ups dos pinos P7.0 e P7.1

KRM = BIT1 | BIT0; // ativa entradas KR1 e KR0 no modo de interrupção

KRIF = 0; // apaga flag da interrupção de teclado

KRMK = 0; // habilita interrupção de teclado

LED = 1; // led desligado

__enable_interrupt(); // habilita interrupções globais

while (1);

Exemplo 6.2

Periféricos de Temporização 135

7

Periféricos de Temporização 7. Periféricos de Temporização

Neste capítulo estudaremos os periféricos de temporização encontrados nos RL78/G13. Os temporizadores ou timers formam a espinha dorsal de qualquer microcontrolador e podem ser utilizados para diversas tarefas tais como: geração de bases de tempo, medição de sinais, geração de sinais, etc.

Os RL78/G13 incluem três diferentes modelos de timers: o timer de intervalo, o relógio de tempo real com calendário (RTC) e a TAU.

O timer de intervalo destina-se a temporizações simples e pode ser utilizado para gerar base de tempo para uma aplicação (por exemplo, uma interrupção a cada 1ms), ele também pode ser utilizado para fazer com que o chip saia periodicamente de um modo de baixo consumo de energia.

O RTC (Real Time Clock ou relógio de tempo real) é um timer mais elaborado que pode ser utilizado para fornecer bases de tempo precisas em aplicações como relógios e semelhantes. Ele inclui funcionalidades como alarme e calendário, permitindo que se implemente aplicações de controle de tempo muito eficientes.

O último e mais completo timer dos RL78/G13 é a TAU (Timer Array Unit – Unidade conjunta de timers). Uma unidade TAU consiste num conjunto de 4 a 8 timers de 16 bits que podem operar de forma independente ou associados para operações complexas (como geração de sinais, inclusive PWM). Até 2 TAU de 8 canais podem estar presentes num mesmo chip (ou seja, até 16 timers de 16 bits).

Estes três timers são controlados primariamente pelo registrador PER0 (já visto quando falamos do gerenciamento de clock), por isso, antes de utilizá-los é necessário habilitá-los através dos respectivos bits do registrador.

Além dos timers mencionados acima, os microcontroladores da linha G14 incluem também outros timers que serão discutidos rapidamente no final deste capítulo.

Microcontroladores RL78: Guia Básico 136

Nome Bits 7 6 5 4 3 2 1 0

Leitura

Escrita RTCEN IICA1EN ADCEN IICA0EN SAU1EN SAU0EN TAU1EN TAU0EN

PER0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Bit C Símbolo C

RTCEN Controle do clock do RTC e do timer de intervalo: 0 – Clock desativado 1 – Clock ativado

RTCEN bRTCEN

TAU1EN Controle de clock e operação da unidade de timer TAU1: 0 – TAU1 desativada 1 – TAU1 ativada

TAU1EN bTAU1EN

TAU0EN Controle de clock e operação da unidade de timer TAU0: 0 – TAU0 desativada 1 – TAU0 ativada TAU0EN bTAU0EN

7.1. Timer de Intervalo (IT)

Este é o temporizador mais simples e básico dos RL78. Ele consiste num contador de 12 bits que pode receber clock do sistema secundário de clock, ou seja, do oscilador LOCO (fIL=15kHz) ou do oscilador secundário XT1 (fSUB=32,768kHz).

Figura 7.1

A sua operação é muito simples: o contador de 12 bits é incrementado a cada ciclo do clock secundário (fSUB ou fIL). Quando o contador atinge o valor programado nos bits 0 a 11 do registrador ITMC, a contagem volta a zero e o flag INTIT é setado.

O timer de intervalo (IT) possui também um bit de habilitação (RINTE) que deve ser setado para que o contador do timer possa efetivamente contar e gerar interrupção, quando RINTE está apagado a contagem do timer é mantida em zero.

A frequência de interrupção do timer de intervalo (fINTIT) pode ser calculada através da seguinte fórmula:

1VAL_ITMC

CLKfINTIT

+=

Onde CLK é a frequência da fonte de clock do timer (15kHz quando utilizado o LOCO ou 32,768kHz quando utilizado o oscilador XT1) e ITMC_VAL corresponde aos 12 bits menos

Periféricos de Temporização 137

significativos carregados no registrador ITMC. A seleção do clock é feita através do bit WUTMMCK0 localizado no registrador OSMC:

WUTMMCK0 Fonte de Clock do RTC/IT 0 Oscilador XT1 1 Oscilador LOCO (15kHz)

Tabela 7.1

A seguir mostramos a organização do registrador ITMC que configura o IT:

Nome Bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita RINTE 0 0 0 ITMC_VAL

ITMC

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Lembre-se que ITMC_VAL pode assumir valores entre 0 e 4095, o que significa que a menor frequência de interrupção do timer de intervalo é igual a 3,66Hz (quando operando com o LOCO em 15kHz) ou 8Hz (quando operando com o XT1 em 32,768kHz).

Caso a máscara de interrupção do timer (ITMK) esteja em zero e as interrupções estejam globalmente habilitadas (IE=1), a cada estouro do timer o flag ITIF será setado e o programa será desviado para o vetor INTIT.

Lembre-se de que antes de utilizar o timer de intervalo é necessário setar o bit RTCEN no registrador PER0! A escrita no registrador do ITMC é ignorada quando RTCEN = 0!

Note que o timer de intervalo pode operar normalmente nos modos halt, stop e snooze (desde que a sua fonte de clock permaneça ativa), permitindo que a CPU seja mantida parada e sendo periodicamente “acordada” pelo timer. Esta técnica é útil quando se necessita que a aplicação apresente um consumo muito baixo de energia, um exemplo típico é o de sensores inteligentes, onde o microcontrolador periodicamente verifica uma entrada, realiza algum processamento e então retorna para um modo de baixo consumo, aguardando uma nova amostragem.

7.1.1. Exemplo

O exemplo a seguir demonstra a utilização do timer de intervalo (IT). Ele faz com que o led D2 da placa de promoção do RL78 (YRPBRL78G13) pisque numa frequência de 5Hz.

Este exemplo utiliza o oscilador interno de 15kHz (LOCO) como fonte de clock do timer, mas também é possível utilizar o oscilador XT1 para se obter mais precisão.

A vantagem de se utilizar o LOCO é a redução de custo e de consumo de energia (já que o XT1 necessita de cristal externo e consome mais energia que o LOCO).

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

Microcontroladores RL78: Guia Básico 138

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P7_bit.no7

#pragma vector = INTIT_vect

__interrupt void trata_IT(void)

LED = !LED; // inverte o estado do led

void main(void)

PM7_bit.no7 = 0; // P7.7 como saída

LED = 1; // led desligado

CMC = 0; // desativa osciladores X1 e XT1

// configura o LOCO (15kHz) como fonte de clock do IT/RTC

OSMC = bWUTMMCK0;

// habilita o RTC e o IT

RTCEN = 1;

// Configura o IT para uma interrupção a cada 3000 contagens, ou seja:

// 3000/15000 = 200ms -> uma interrupção a cada 200ms

ITMC = bRINTE | 2999;

// habilita a interrupção do IT

ITMK = 0;

__enable_interrupt(); // habilita as interrupções do RL78

while (1);

Exemplo 7.1

7.2. RTC

O RTC (Real Time Clock – Relógio de tempo real) é um timer dedicado principalmente a implementação de relógios e bases de tempo de precisão. Ele inclui contadores de horas, minutos e segundos, além de calendário com marcação de dia, dia da semana, mês e ano e também alarme programável (dia da semana, hora e minuto).

Periféricos de Temporização 139

Figura 7.2

O núcleo do RTC é conjunto de contadores BCD (decimal codificado em binário) responsáveis por contar as unidades de tempo. O contador de mais baixa ordem (segundos) é impulsionado por um sinal de 1Hz derivado de um contador de 16 bits que divide o sinal fRTC (que por sua vez pode ser derivado do oscilador LOCO ou do oscilador XT1) por um fator normalmente igual a 32768 (ele pode sofrer pequenos ajustes como veremos adiante).

O RTC pode gerar dois tipos de interrupção: uma periódica e outra de alarme. A periódica pode ser disparada a cada 0,5 ou 1 segundo, ou ainda a cada minuto, hora, dia ou mês. A interrupção de alarme é disparada quando o valor de alarme (dia de semana, hora e minuto) coincide com o horário corrente do RTC.

É possível também fazer com que o sinal de clock de 1Hz do RTC seja disponibilizado através de um pino do chip (P30, que deve ser configurado como saída digital e apenas nos modelos com 40 pinos ou mais) para medição ou utilização por outros circuitos externos ao microcontrolador.

Há também uma interessante funcionalidade que é a de ajuste de precisão do timer. Através do registrador SUBCUD é possível ajustar o fator de divisão (32768) do contador de 16 bits do RTC, permitindo ajustar o clock em algumas partes por milhão (PPM), de forma a compensar erros e imprecisões do oscilador XT1.

Vale lembrar que o RTC pode operar normalmente nos modos halt, stop e snooze, permitindo que a aplicação mantenha um preciso controle de horário e calendário e sem a necessidade de retornar ao modo run para tarefas de manutenção de relógio (como acontece em microcontroladores sem RTCs ou mesmo com RTCs mais simples).

Microcontroladores RL78: Guia Básico 140

7.2.1. Configuração do RTC

Vejamos então como configurar e utilizar o RTC em uma aplicação: o primeiro passo é setar o bit RTCEN no registrador PER0!

Lembre-se de que antes de utilizar o RTC é necessário setar o bit RTCEN no registrador PER0! A escrita nos registradores do RTC é ignorada quando RTCEN = 0!

Também é importante selecionar o oscilador XT1 como fonte de clock para o RTC (e timer de intervalo). Isto é feito apagando-se o bit WUTMMCK0 no registrador OSMC. Caso este bit seja mantido setado, a fonte de clock do RTC e do timer de intervalo será o oscilador interno de baixa frequência (LOCO) e, segundo o fabricante, apenas a função de interrupção periódica pode ser utilizada neste caso, os contadores de tempo e alarme ficam desabilitados.

Devemos então configurar o RTC através dos registradores RTCC0 e RTCC1. No registrador RTCC0 encontramos o bit de habilitação do RTC (RTCE) que deve ser setado para que o timer possa operar. Há também um bit (AMPM) para seleção de modo de horário (12 ou 24 horas), outro para ativação da saída de clock de 1Hz (RCLOE1) e mais três bits (CT2, CT1 e CT0) para configuração da interrupção periódica do RTC.

No registrador RTCC1 encontramos os controles do alarme e de leitura ou escrita nos contadores do relógio. O bit WALE controla a ativação ou desativação do alarme, WALIE controla a interrupção do alarme e WAFG sinaliza que o alarme disparou. Temos também o bit RIFG que sinaliza a ocorrência de uma interrupção periódica do RTC.

O bit RWAIT deve ser utilizado sempre que é necessário escrever ou ler qualquer um dos registradores do relógio (SEC para segundos, MIN para minutos, HOUR para horas, DAY para dia, WEEK para dia da semana, MONTH para mês e YEAR para ano). Quando RWAIT é setado, um mecanismo de bloqueio impede que ocorra a propagação do sinal de relógio para os contadores de tempo. Este bloqueio necessita de no máximo um ciclo de clock do RTC (cerca de 30,5µs) para ser completado e a sua efetivação é indicada pelo bit RWST. Esta facilidade de bloqueio permite que a aplicação faça a leitura ou escrita dos registradores sem correr o risco de que ocorra um incremento durante a operação (o que poderia resultar em erros na leitura).

Sendo assim, uma vez setado o bit RWAIT a aplicação deve aguardar que RWST seja setado também antes de poder ler ou escrever nos registradores de tempo do relógio. Um detalhe importante é que a aplicação deve realizar a leitura ou escrita nos registradores do relógio em no máximo um segundo, devendo em seguida apagar RWAIT de forma que o clock do sistema seja restaurado. Deixar RWAIT setado por mais de um segundo pode provocar atrasos indesejados no relógio!

Jamais efetue o ciclo de espera pelo bit RWST dentro de uma ISR, pois isso causará a perda de outras interrupções que poderiam ocorrer neste intervalo!

O horário de alarme pode ser programado nos registradores ALARMWM (minuto), ALARMWH (hora) e ALARMWW (dia da semana). Para programar o alarme é importante seguir os procedimentos indicados pelo fabricante, que são:

1. Desativar o alarme (WALE=0);

Periféricos de Temporização 141

2. Habilitar a interrupção de alarme (WALIE=1);

3. Alterar os registradores de alarme (ALARMWM, ALARMWH e ALARMWW);

4. Habilitar o alarme (WALE=1).

A interrupção periódica do RTC e a interrupção de alarme compartilham o mesmo vetor de interrupção e setam o mesmo flag (RTCIF). A ISR do RTC (INTRTC) deve verificar a origem da interrupção no registrador RTCC1 (flag WAFG para o alarme e RIFG para a interrupção periódica).

7.2.2. Registradores do RTC

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita RTCE 0 RCLOE1 0 AMPM CT2 CT1 CT0

RTCC0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Bit C Símbolo C

RTCE Controle de operação do RTC: 0 – contadores parados 1 – contadores operando

RTCE bRTCE

RCLOE1 Controle da saída de 1Hz: 0 – saída desabilitada 1 – saída habilitada

RCLOE1 bRCLOE1

AMPM Seleção do modo 12 ou 24 horas: 0 – modo 12 horas 1 – modo 24 horas

- bAMPM

Seleção da interrupção periódica do RTC:

000 – desativada - INT_RTC_OFF

001 – intervalos de 0,5 segundos - INT_RTC_05S

010 – intervalos de 1 segundo - INT_RTC_1S

011 – intervalos de 1 minuto (quando SEC=0) INT_RTC_1MIN

100 – intervalos de 1 hora (quando SEC=MIN=0) - INT_RTC_1H

101 – intervalos de 1 dia (quando SEC=MIN= HOUR=0) - INT_RTC_1D

CT2 CT1 CT0

11x – intervalos e 1 mês (todo dia 1 as 00:00:00) - INT_RTC_1M

Atenção: é recomendado reescrever o bit AMPM após cada bloqueio de clock do RTC (via bit RWAIT no registrador RTCC1).

Após o mascaramento da interrupção do RTC (RTCMK=1) o fabricante recomenda reescrever o conteúdo dos bits CT2 a CT0 e apagar os flags RIFG e RTCIF.

Microcontroladores RL78: Guia Básico 142

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura WAFG RIFG RWST

Escrita WALE WALIE 0

0 0 0

- RWAIT

RTCC1

Reset 0 0 0 0 0 0 0 0

* RWST é um bit somente de leitura e não pode ser modificado pelo programa, WAFG e RIFG podem ser lidos e apagados ao se escrever “0” neles. A escrita de “1” não provoca nenhum efeito e não altera o seu estado.

Nome do Bit Descrição Bit C Símbolo C

WALE Controle de habilitação do alarme: 0 – alarme desabilitado 1 – alarme habilitado

WALE bWALE

WALIE Habilitação da interrupção de alarme do RTC: 0 – interrupção desabilitada 1 – interrupção habilitada

WALIE bWALIE

WAFG Sinalizador de interrupção do alarme do RTC: 0 – nenhuma interrupção pendente 1 – interrupção pendente

WAFG bWAFG

RIFG Sinalizador de interrupção periódica do RTC: 0 – nenhuma interrupção pendente 1 – interrupção pendente

RFIG bRIFG

RWST Indicador de bloqueio de clock do RTC: 0 – RTC operando sem bloqueio de clock 1 – clock bloqueado, RTC pode ser lido ou escrito

RWST bRWST

RWAIT Controle de bloqueio do clock do RTC: 0 – RTC opera normalmente 1 – solicita bloqueio do clock

RWAIT bRWAIT

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 SEC40 SEC20 SEC10 SEC8 SEC4 SEC2 SEC1

SEC

Reset 0 0 0 0 0 0 0 0

Este registrador contém o valor do contador de segundos do RTC. Ele opera com valores BCD, desta forma, o seu valor máximo é igual a 0x59. Repare que 10 segundos são representados como 0x10 e não como 0x0A.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 MIN40 MIN20 MIN10 MIN8 MIN4 MIN2 MIN1

MIN

Reset 0 0 0 0 0 0 0 0

Este registrador contém o valor do contador de minutos do RTC. Ele opera com valores BCD, desta forma, o seu valor máximo é igual a 0x59. Repare que 20 minutos são representados como 0x20 e não como 0x14.

Periféricos de Temporização 143

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0

HOUR20/

AMPM HOUR10 HOUR8 HOUR4 HOUR2 HOUR1

HOUR

Reset 0 0 0 0 0 0 0 0

Este registrador contém o valor do contador de horas do RTC. Ele opera com valores BCD, desta forma, o seu valor máximo (no modo 24 horas) é igual a 0x23. Quando o RTC opera em modo 12 horas o bit 5 passa a operar na função AMPM: em 0 para AM (antes do meio dia) e 1 para PM (depois do meio dia). Quando operando no modo 12 horas o valor máximo de horário é igual a 0x12 (bit 4 a bit 0).

Desta forma, 10 horas da manhã será representado como 0x10 nos dois modos e 10 horas da noite será representado como 0x22 no modo 24 horas e 0x30 no modo 12 horas.

Um exemplo de como ler este registrador no formato 12 horas: hora = HOUR & 0x1F;

if (HOUR && BIT5) LED_AMPM=1; else LED_AMPM=0;

Para escrever o horário no registrador: HOUR = hora;

if (bit_AMPM) HOUR |= BIT5;

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 DAY20 DAY10 DAY8 DAY4 DAY2 DAY1

DAY

Reset 0 0 0 0 0 0 0 1

Este registrador contém o valor do contador de dias do RTC. Ele opera com valores BCD, desta forma, o seu valor máximo é igual a 0x31. Após um reset ele é carregado com o valor 0x01, já que não existe dia 0!

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 WEEK4 WEEK2 WEEK1

WEEK

Reset 0 0 0 0 0 0 0 0

Este registrador contém o valor do contador de dia semana do RTC. Os valores representam os dias conforme a tabela a seguir.

WEEK Dia da semana 0 Domingo 1 Segunda-feira 2 Terça-feira 3 Quarta-feira 4 Quinta-feira 5 Sexta-feira 6 Sábado

Tabela 7.2

Microcontroladores RL78: Guia Básico 144

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 MONTH10 MONTH8 MONTH4 MONTH2 MONTH1

MONTH

Reset 0 0 0 0 0 0 0 1

Este registrador contém o valor do contador de meses do RTC. Os valores representam os meses de 1 a 12 em BCD (outubro é representado 0x10, novembro 0x11 e dezembro 0x12).

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita YEAR80 YEAR40 YEAR20 YEAR10 YEAR8 YEAR4 YEAR2 YEAR1

YEAR

Reset 0 0 0 0 0 0 0 0

Este registrador contém o valor do contador de anos do RTC. Os valores são armazenados em BCD, de 0x00 a 0x99. Para efeitos de cálculo de ano bissexto, o RTC considera que YEAR = 0x00 equivale ao ano 2000, que é um ano bissexto (fevereiro com 29 dias).

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita DEV F6 F5 F4 F3 F2 F1 F0

SUBCUD

Reset 0 0 0 0 0 0 0 0

Este registrador permite corrigir o relógio para reduzir imprecisões na contagem de tempo provocadas por desvios na frequência do oscilador XT1.

A correção efetuada pelo registrador SUBCUD consiste em adicionar ou subtrair um valor do fator de divisão padrão (32768) do contador de 16 bits do RTC. Esta correção é realizada a cada 20 segundos (bit DEV = 0) ou a cada minuto (bit DEV = 1).

O fator de correção é especificado pelos bits F0 a F5 e o bit F6 indica se fator de correção deve ser somando ou subtraído do valor base (32768). Observe que quando F6 = 0, o fator de correção consiste no valor binário carregado em F0 a F5, subtraído de 1 e multiplicado por 2. Quando F6 = 1, o fator de correção consiste no complemento de dois do conteúdo de F0 a F5 multiplicado por 2.

Através deste registrador é possível efetuar correções de ±63,1ppm (quando DEV = 1) até ±189,2ppm (quando DEV = 0)

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 WM40 WM20 WM10 WM8 WM4 WM2 WM1

ALARMWM

Reset 0 0 0 0 0 0 0 0

Este registrador armazena o minuto de alarme do RTC. Assim como o registrador de minutos, este registrador também utiliza o formato BCD e pode conter valores de 0x00 a 0x59.

Periféricos de Temporização 145

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 WH20 WH10 WH8 WH4 WH2 WH1

ALARMWH

Reset 0 0 0 1 0 0 1 0

Este registrador armazena a hora de alarme do RTC. Assim como o registrador de horas, este registrador também utiliza o formato BCD e pode conter valores de 0x00 a 0x23. No modo 12 horas o bit WH20 comporta-se como AMPM e indica se o horário de alarme é antes de meio dia (WH20 = 0) ou depois do meio dia (WH20 = 1).

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 WW6 WW5 WW4 WW3 WW2 WW1 WW0

ALARMWW

Reset 0 0 0 0 0 0 0 0

Este registrador controla os dias da semana onde o alarme deve ser disparado. WW0 para domingo, WW1 para segunda-feira, WW2 para terça-feira, WW3 para quarta-feira, WW4 para quinta-feira, WW5 para sexta-feira e WW6 para sábado.

7.2.3. Ajuste do RTC

Como já foi dito, o RTC inclui um mecanismo que permite realizar pequenos ajustes para compensar desvios de frequência no oscilador XT1. Este mecanismo utiliza o registrador SUBCUD e atua diretamente sobre o fator de divisão do contador de 16 bits, localizado no circuito gerador de clock do RTC e responsável por dividir o sinal do oscilador XT1 (fSUB) por 32.768, de forma a obter um sinal de 1Hz.

O circuito de correção modifica periodicamente (a cada 20 ou a cada 60 segundos) o fator de divisão padrão (32.768) adicionando ou subtraindo do mesmo um valor configurável. Desta forma, garante-se a precisão da contagem de tempo do RTC ao longo do tempo.

Para entendermos o conceito da correção, basta considerar que um oscilador de 32.768Hz gera 1.966.080 pulsos em um minuto de operação. Se o oscilador estiver operando fora da frequência, digamos 32.767Hz, o total de pulsos em um minuto será de 1.966.020, ou seja, 60 pulsos de clock a menos, o que significa que o relógio vai atrasar cerca 1 segundo a cada 546,13 segundos (ou cerca de um segundo a cada 9 minutos).

O valor de correção pode ser calculado da seguinte forma: Npulsosreal-Npulsos32768 = 1.966.020-1.966.080 = -60. Como o resultado é negativo, sabemos que F6 = 1 e o valor de F5 a F0 será igual a ~(60/2-1) = ~(30-1) = ~29 = 0xE2. Como apenas os seis bits menos significativos são utilizados, então o valor de F5 a F0 será igual a 0x22, F6 = 1 e DEV = 1 (já que o número de pulsos foi calculado para um minuto). O valor final de SUBCUD será igual a 0xE2.

Outro exemplo: considerando que o oscilador esteja operando a 32.771Hz. Neste caso, temos uma diferença de +180 pulsos (o relógio vai adiantar). O cálculo do valor de correção será Npulsosreal-Npulsos32768 = 1.966.260-1.966.080 = +180. Como o resultado é positivo, o bit F6 = 0 e o

Microcontroladores RL78: Guia Básico 146

valor a ser carregado em F5 a F0 será igual a (180/2)-1 = 90-1 = 89. No entanto, este valor é superior ao máximo que pode ser armazenado nos 6 bits menos significativos do SUBCUD. Isto significa que, neste caso, a correção não poderá ser feita a cada minuto e deverá ser feita a cada 20 segundos (DEV = 0).

Refazendo o cálculo do número de pulsos a cada 20 segundos chegamos a uma diferença de +60 pulsos (basta dividir o valor por 3 o valor obtido para um minuto). O valor a ser carregado em F5 a F0 será igual a (60/2)-1 = 30-1 = 29 ou 0x1D, com F6 = 0 e DEV = 0! O valor final de SUBCUD será igual a 0x1D.

Lembre-se de que para medir a frequência do oscilador XT1 deve ser ativada a saída de clock do RTC (RCLOE=1) através do pino P30. Não tente medir o sinal do oscilador diretamente nos pinos XT1 e XT2, pois qualquer carga adicional nestes pinos irá desestabilizar o oscilador, podendo causar erros de medição e até a parada de oscilação dele!

7.2.4. Exemplo

O exemplo a seguir demonstra como utilizar o RTC. A aplicação utiliza a interrupção periódica do RTC, configurada para intervalos de um segundo, para alternar o estado do led D2 na placa RPB do RL78/G13.

A mesma interrupção também realiza a atualização da estrutura “time” que armazena o horário atual e que também permite setar o horário do RTC.

O procedimento de configuração de horário do relógio deve obedecer aos seguintes passos:

1. A aplicação deve apagar o bit “time.update”, de forma a poder alterar os demais campos da estrutura “time”;

2. Após a configuração dos campos da estrutura, a aplicação deve setar o bit “time.set”. Isto fará com que o horário do RTC seja reconfigurado com os valores da estrutura “time”. Após esta operação a atualização do horário é automaticamente habilitada (o bit “time.set” é apagado e “time.update” é setado).

#include “ior5f100le.h”

#include “ior5f100le_ext.h”

#include “intrinsics.h”

#include “myRL78.h”

// Configura watchdog = desligado

#pragma location = “OPTBYTE”

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = “OPTBYTE”

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = “OPTBYTE”

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = “OPTBYTE”

__root __far const char opbyte3 = DEBUG_ON_ERASE;

Periféricos de Temporização 147

/* Configura security ID */

#pragma location = “SECUID”

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P7_bit.no7

struct

unsigned char hour, minute, second;

unsigned char year, month, week, day;

unsigned char set : 1;

unsigned char update : 1;

time;

#pragma vector = INTRTC_vect

__interrupt void trata_RTC(void)

LED = !LED; // inverte o estado do led

// solicita o bloqueio dos contadores caso a atualização esteja ativa

if (time.update) RWAIT = 1;

void main(void)

PM7_bit.no7 = 0; // P7.7 como saída

LED = 1; // led desligado

CMC = OSC_XT1_OSC; // oscilador XT1 ligado no modo de baixa potência

CSC = bMSTOP; // libera oscilador XT1 e mantém X1 parado

OSMC = 0; // configura o XT1 como fonte de clock do IT/RTC

RTCEN = 1; // habilita o RTC e o IT

// habilita o RTC, modo 24 horas, interrupção periódica de 1 segundo

RTCC0 = bRTCE | bAMPM | INT_RTC_1S;

RTCC1 = 0;

RTCMK = 0; // habilita a interrupção do RTC

time.set = 0;

time.update = 1;

__enable_interrupt(); // habilita as interrupções do RL78

while (1)

if (time.set)

// se houver requisição de atualização de horário do RTC

RWAIT = 1; // solicita bloqueio dos contadores

if (RWST)

// se o indicador de bloqueio dos contadores estiver setado

if (time.set)

// setar o horário do relógio

HOUR = time.hour;

MIN = time.minute;

SEC = time.second;

YEAR = time.year;

MONTH = time.month;

WEEK = time.week;

DAY = time.day;

time.set = 0; // apaga o indicador de atualização

else

// é uma atualização do mostrador

time.hour = HOUR;

time.minute = MIN;

Microcontroladores RL78: Guia Básico 148

time.second = SEC;

time.year = YEAR;

time.month = MONTH;

time.week = WEEK;

time.day = DAY;

RWAIT = 0; // desbloqueia o clock dos contadores do RTC

time.update = 1; // ativa a atualização do mostrador

Exemplo 7.2

A figura 7.3 mostra a janela “Live Watch” de uma sessão de depuração do IAR EWRL78. Utilizando esta janela é possível visualizar o horário do relógio sendo atualizado em tempo real!

Repare que, por padrão do depurador, o RTC continua operando, mesmo quando a execução do programa é paralisada!

Figura 7.3

7.3. TAU

A TAU (Timer Array Unit – unidade conjunta de timers) é a principal unidade de temporização dos RL78 e constitui um dos grandes atributos destes microcontroladores.

Uma unidade TAU é composta de até oito canais, cada um contendo um contador e um registrador de recarga/captura, ambos de 16 bits.

Cada canal pode operar nos seguintes modos:

• Gerador de interrupções periódicas ou de ondas quadradas;

• Captura de sinais externos (medição de período de sinais digitais);

• Medição de ciclo ativo ou inativo de sinais;

• Contador de eventos externos;

• Gerador de atraso ou disparo único (o contador dispara após um evento interno ou externo e gera uma interrupção após um atraso programável).

Os canais 1 e 3 também podem operar como timers de 8 bits, de forma que cada um destes canais opera como dois timers de 8 bits. Adicionalmente, na TAU0, o canal 0 pode operar como divisor de frequência e, nos modelos com 30 pinos ou mais, o canal 7 pode ser utilizado em conjunto com a UART2 para implementar comunicação LIN (Local Interconnect Network – rede de interconexão local).

Também é possível agrupar canais para realizar operações complexas tais como:

Periféricos de Temporização 149

• Geração de sinais PWM (Pulse Width Modulation – modulação por largura de pulso), onde um canal é responsável pela temporização do período do sinal (o canal mestre) e outros canais são responsáveis pelo ciclo ativo de cada sinal (os canais escravos);

• Geração de pulsos únicos (com intervalo e duração programáveis).

Uma característica muito importante e interessante da TAU é que cada canal comporta-se como um timer independente de 16 bits já que, diferentemente dos timers utilizados em outros microcontroladores, cada canal possui recarga independente e contador próprio, reduzindo drasticamente a necessidade de intervenção da CPU na geração de sinais e interrupções periódicas.

Nos timers comumente encontrados em outros microcontroladores, temos um contador principal, normalmente com módulo de contagem configurável e um ou mais registradores comparadores, um para cada canal. Assim, para gerar interrupções periódicas podemos utilizar duas alternativas: configurar o módulo de contagem do contador principal, o que faz com que todos os canais devam operar dentro do mesmo range do contador principal, ou carrega-se o período de contagem no registrador comparador a cada comparação, por exemplo: se o contador principal do timer incrementa a cada 1µs então, para gerar uma comparação a cada 1ms será necessário configurar o registrador de comparação para 1000 contagens e a cada comparação deveremos somar 1000 ao mesmo de forma a obter comparações periódicas de 1ms.

Como cada canal da TAU dos RL78 funciona como um timer independente, podemos configurar um canal qualquer para operar com módulo de contagem 1000 e ele gerará uma interrupção a cada 1ms, sem nenhuma necessidade de intervenção da CPU! Os demais canais podem realizar contagens em diferentes módulos sem que ocorra interferência ou dependência entre eles.

7.3.1. Visão Geral de uma Unidade TAU

Antes de estudarmos em mais detalhes os diversos modos de operação dos canais da TAU, vejamos alguns detalhes gerais acerca da sua operação.

Lembre-se de que antes de utilizar uma unidade TAU é necessário setar o bit TAU0EN (para a TAU0) ou TAU1EN (para a TAU1) no registrador PER0!

Primeiramente, é importante saber que existem quatro divisores de clock (prescalers) na TAU, batizados de CK0, CK1, CK2 e CK3. Cada um deles pode ser configurado para dividir o sinal de clock principal fCLK por fatores configurados através do registrador TPSm (onde m pode ser 0 para a unidade TAU0 ou 1 para a unidade TAU1). Estes sinais de clock podem ser utilizados como fonte de clock dos canais da TAU.

Como já foi dito, cada canal possui um contador (TCRmn onde m indica a unidade TAU, 0 ou 1, e n indica o número do canal, 0 a 7) e um registrador de captura ou comparação (TDRmn), ambos com 16 bits. A configuração do modo de operação de cada canal é realizada através dos registradores TMRmn. Observe que cada contador pode contar progressiva ou regressivamente, conforme o modo de operação do canal: nos modos de captura a contagem é progressiva e nos demais modos a contagem é regressiva.

Microcontroladores RL78: Guia Básico 150

É no registrador TMRmn que configuram-se facilidades como a operação de canais em conjunto (configurando-se um ou mais canais como mestres e outros como escravos) ou operação de canais independentes.

Cada canal pode ser individualmente habilitado (registrador TE0 para a TAU0 e TE1 para a TAU1) e a sua operação é iniciada setando-se o bit de partida (registrador TSm) e pode ser paralisada a qualquer tempo setando-se o bit de parada (registrador TTm). Quando o canal está parado o contador mantém o último valor de contagem.

Observe que os registradores TSm e TTm são do tipo write-only e por isso, a leitura deles retorna sempre o valor zero. A verificação do status de operação de um canal deve ser feita através do registrador TEm!

Adicionalmente, cada canal pode contar com um pino que pode operar como entrada (TImn), que pode ser utilizada como fonte de clock externo ou para medição de período ou ciclo ativo/inativo de sinais externos. O pino também pode operar como saída (TOmn) que pode ser utilizada para gerar sinais PWM, pulsos ou ondas quadradas.

As entradas podem ser configuradas para operar com filtros digitais de ruído (registradores NFEN1 e NFEN2). No caso das saídas, os registradores TOEm, TOm, TOLm e TOMm podem ser utilizados para configurar o modo como o canal interage com os pinos de E/S do microcontrolador.

Atenção: quando o filtro de ruído está desativado o pulso aplicado na entrada do canal

deverá ter uma duração mínima de 10nsf

1

MCLK+ para que possa ser corretamente

identificado pelo hardware da TAU. Quando o filtro está ativado, o pulso deve permanecer ativo por um período mínimo de 2 pulsos de clock do canal (fMCLK).

As tabelas a seguir mostram os pinos associados às unidades TAU dos RL78/G13. As células sombreadas indicam os canais disponíveis nos diversos encapsulamentos.

Pino de E/S utilizado pela TAU* TAU

Encapsulamento (pinos)

Unidade Canal Função 128 100 80 64 52 48,44 40 36,32,30 25,24 20

Pino Alternativo

0 TI00 P00 P00 P00 P00 P00 P00 P00 P00 P00 P00 -

0 TO00 P01 P01 P01 P01 P01 P01 P01 P01 P01 P01 -

1 TI01/TO01 P16 P16 P16 P16 P16 P16 P16 P16 P16 P16 -

2 TI02/TO02 P17 P17 P17 P17 P17 P17 P17 P17 P17 P17 -

3 TI03/TO03 P31 P31 P31 P31 P31 P31 P31 P31 P31 - -

4 TI04/TO04 P42 P42 P42 P42 - - - - - - P13

5 TI05/TO05 P46 P46 P05 P05 - - - - - - P12

6 TI06/TO06 P102 P102 P06 P06 - - - - - - P11

0

7 TI07/TO07 P145 P145 P41 P41 P41 P41 P41 - - - P10

* A disponibilidade de pinos e canais varia conforme o tamanho do encapsulamento

Tabela 7.3

Periféricos de Temporização 151

Pino de E/S utilizado pela TAU* TAU

Encapsulamento (pinos)

Unidade Canal Função 128 100 80 64 52 48,44 40 36,32,30 25,24 20

Pino Alternativo

0 TI10/TO10 P64 P64 P64 - - - - - - - -

1 TI11/TO11 P65 P65 P65 - - - - - - - -

2 TI12/TO12 P66 P66 P66 - - - - - - - -

3 TI13/TO13 P67 P67 P67 - - - - - - - -

4 TI14/TO14 P103 - - - - - - - - - -

5 TI15/TO15 P104 - - - - - - - - - -

6 TI16/TO16 P105 - - - - - - - - - -

1

7 TI17/TO17 P106 - - - - - - - - - -

* A disponibilidade de pinos e canais varia conforme o tamanho do encapsulamento

Tabela 7.4

Nos próximos tópicos veremos os diversos modos em que os canais das unidades TAU podem operar.

7.3.2. Operação em Modo Timer/Gerador de Onda Quadrada

Neste modo de operação o contador do canal (TCRmn) conta regressivamente, iniciando a contagem com o valor carregado no registrador TDRmn. A cada pulso de clock (CK0, CK1, CK2 ou CK3) a contagem é decrementada até atingir zero, quando então o respectivo flag de interrupção é setado (TMIFmn = 1) e caso a interrupção do canal esteja habilitada (TMMKmn = 0) e IE=1, o programa é desviado para o vetor do respectivo do canal (INTTMmn_vect).

No próximo pulso de clock o contador do canal é novamente carregado com o valor de TDRmn e o processo reinicia.

Para operar neste modo o registrador de controle do canal (TMRmn) deve ser configurado com os bits MD3 = 0, MD2 = 0 e MD1 = 0. O bit MD0 configura a geração de interrupção no disparo do canal (MD0 = 1) ou não (MD0 = 0). Também é possível (e recomendável) utilizar o símbolo TAU_MD_TIMER para configurar o canal no modo timer sem interrupção no disparo ou o símbolo TAU_MD_TIMER_TRIG_INT para configurar o canal no modo timer com interrupção no disparo. A fonte de clock (bit CCS) deve ser sempre o clock interno (CCS=0).

Observe que independentemente da configuração de interrupção no disparo, o canal irá gerar uma interrupção a cada recarga do contador!

O período de interrupção (em segundos) nesta modalidade de operação pode ser calculado através da seguinte fórmula:

CKx

1TDRmnTINT

+=

Onde: TDRmn é o valor carregado no registrador de comparação do canal e CKx é a frequência de clock do canal (sinal CK0, CK1, CK2 ou CK3, conforme selecionado no registrador de configuração do canal TMRmn).

Microcontroladores RL78: Guia Básico 152

Neste modo de operação, utiliza-se normalmente o disparo por software (bits STS0, STS1 e STS2 em 0) e a temporização tem início quando o canal é disparado (via registrador TSm) e é paralisada via registrador TTm.

A seguir temos um exemplo de configuração do canal 2 da TAU0 para geração de interrupções a cada 1ms. No exemplo utilizaremos o sinal CK0 como fonte de clock do canal e consideraremos que o chip utiliza clock interno de 32MHz.

// Primeiro configuramos os divisores de clock CKx no registrador TPS0

TPS0 = TAU_CK0_DIV1; // CK0=1MHz, CK1=1MHz, CK2=16MHz e CK3=125kHz

// Agora configuramos o canal, não utilizaremos interrupção no disparo

TMR02 = TAU_CK0 | TAU_MODE_TIMER;

// Carrega o valor de comparação (para 1ms o valor de recarga é 999)

TDR02 = 999;

// Agora disparamos o canal, setando o bit correspondente (2) no TS0:

TS0L = TAU_CH2; // é mais eficiente escrever na parte baixa do TS0!

// Para gerar interrupções, basta apagar a máscara de interrupção

// e habilitar as interrupções

TMMK02 = 0;

__enable_interrupt();

A ISR para tratamento da interrupção do canal deverá conter o código abaixo. Lembre-se de que ela será executada a cada 1ms! O símbolo INTTM02_vect é válido para o canal 2 da TAU 0, os demais canais possuem símbolos equivalentes (veja as tabelas 6.1 e 6.2).

#pragma vector = INTTM02_vect

__interrupt void trata_canal02(void)

// código de tratamento de interrupção aqui!

// lembre-se de que não é necessário apagar o flag de interrupção!

A qualquer momento é possível parar a contagem do canal, para isso basta setar o bit correspondente (bit 2) no registrador TT0:

// Paralisa a contagem no canal 2 da TAU0

TT0L = TAU_CH2; // é mais eficiente escrever na parte baixa do TT0

Adicionalmente, além da interrupção, é possível configurar o canal para alterar o estado do pino de saída do canal a cada evento de recarga. O sinal gerado será uma onda quadrada com ciclo ativo de 50%, ou seja, o sinal permanecerá 50% do período em nível 0 e 50% em nível 1.

O período do sinal poderá ser calculado através da seguinte fórmula:

CKx

2*)1TDRmn(TSINAL

+=

Onde: TDRmn é o valor carregado no registrador de comparação do canal e CKx é a frequência de clock do canal (sinal CK0, CK1, CK2 ou CK3, conforme selecionado no registrador de configuração do canal TMRmn).

Para que o sinal seja disponibilizado na saída do canal é necessário configurar o registrador de controle de saída do canal (TOEm), setando-se o bit do respectivo canal. No exemplo mostrado anteriormente, para ativar a saída do canal 2 da TAU0 poderíamos escrever:

// Configura o pino do canal (P17) para o modo de saída

PM1_bit.no7 = 0;

// Habilita a saída do canal 2 da TAU0

TOE0L = TAU_CH2; // é mais eficiente escrever na parte baixa do TOE0

Periféricos de Temporização 153

Após a configuração acima, o pino P17 passará a gerar um sinal de frequência igual a 500Hz.

A seguir temos um exemplo completo de configuração dos canais 0 e 1 da TAU0 para operação no modo temporizador. O pino P16 funciona como saída do canal 1, ao passo que o canal 0 somente gera interrupções no software (piscando o led D2 conectado ao pino P77 da Promotion Board do RL78/G13) #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P7_bit.no7

#pragma vector = INTTM00_vect

__interrupt void trata_TAU0_canal0(void)

LED = !LED; // inverte o estado do led

void main(void)

PM1_bit.no6 = 0; // P16 como saída (canal 1 da TAU0)

PM7_bit.no7 = 0; // P77 como saída

TAU0EN = 1; // habilita a TAU0

TPS0 = TAU_CK0_DIV32; // CK0=1MHz, CK1=32MHz, CK2=16MHz e CK3=125kHz

// configura os canais 0 e 1 da TAU0 no modo temporizador

TMR00 = TAU_CK0 | TAU_TRIG_SOFT | TAU_MD_TIMER;

TMR01 = TAU_CK0 | TAU_TRIG_SOFT | TAU_MD_TIMER;

TDR00 = 49999; // uma interrupção a cada 50ms no canal 0

TDR01 = 499; // sinal de 1kHz no canal 1

TOE0L = TAU_CH1; // habilita a saída do canal 1 da TAU0

TMMK00 = 0; // habilita a interrupção do canal 0 da TAU0

TS0L = TAU_CH0 | TAU_CH1; // Dispara os canais 0 e 1

__enable_interrupt(); // habilita as interrupções do RL78

while (1);

Exemplo 7.3

Microcontroladores RL78: Guia Básico 154

7.3.3. Operação no Modo Gerador de Atraso/Disparo Único

Neste modo de operação o canal da TAU é configurado para gerar um atraso programável após receber um sinal de disparo que pode vir através do pino de entrada do canal (TImn) ou do software (registrador TSm).

Após receber o sinal de disparo, o contador do canal é carregado com o conteúdo do registrador de comparação TMRmn e faz a contagem regressiva até atingir o valor zero, quando então é disparada a interrupção e o respectivo flag é setado (TMIFmn = 1).

O período de atraso (em segundos) é dado pela mesma fórmula do modo timer:

CKx

1TDRmnTINT

+=

Onde: TDRmn é o valor carregado no registrador de comparação do canal e CKx é a frequência de clock do canal (sinal CK0, CK1, CK2 ou CK3, conforme selecionado no registrador de configuração do canal TMRmn).

Para que o canal opere neste modo o registrador de controle (TMRmn) deve ser configurado com os bits MD3 = 1, MD2 = 0 e MD1 = 0. O bit MD0 configura o comportamento do canal ao receber um novo disparo durante a temporização. Quando MD0 = 0, um novo disparo é ignorado e não produz efeito. Quando MD0 = 1, um novo disparo (redisparo) provoca a recarga do contador e uma nova temporização tem início. A interrupção somente é disparada ao término da temporização. Também é possível (e recomendável) utilizar o símbolo TAU_MD_ONECOUNT para configurar o canal para operar neste modo (novos disparos ignorados) ou TAU_MD_ONECOUNT_TRIG para permitir o redisparo. A fonte de clock (bit CCS) deve ser sempre o clock interno (CCS=0).

O tipo de disparo é selecionado através dos bits STS2, STS1 e STS0, localizados no registrador TMRmn. Basicamente o disparo pode ocorrer por software ou pelo pino de entrada do canal TImn. A tabela 7.4 mostra as configurações possíveis dos bits STS2, STS1 e STS0.

STS2 STS1 STS0 Fonte de disparo Símbolo C (myRL78.h) 0 0 0 Software TAU_TRIG_SOFT* 0 0 1 Pino TAU_TRIG_VALID_EDGE

* o símbolo TAU_TRIG_SOFT pode ser omitido já que equivale ao valor 0.

Tabela 7.5

No disparo por sinal externo, o software deve armar o canal setando o bit de disparo correspondente no registrador TSm. Uma vez armado, somente ao ser detectada a borda no pino de entrada TImn é que a contagem do canal tem início.

No disparo por software, o software deve armar o canal setando o bit de disparo correspondente no registrador TSm e a contagem tem início imediatamente após o bit de disparo do canal ser setado no registrador TSm, ou seja, primeiro o canal é armado e depois disparado.

A configuração da borda de sensibilidade é feita através dos bits CIS1 e CIS0, localizados no registrador TMRmn. É possível configurar o canal para que o disparo ocorra na borda de descida, de subida ou em ambas as bordas do sinal aplicado ao pino TImn. A tabela 7.5 mostra as configurações possíveis para os bits CIS1 e CIS0.

Periféricos de Temporização 155

CIS1 CIS0 Borda de Sensibilidade Símbolo C (myRL78.h) 0 0 Descida TAU_EDGE_FALLING* 0 1 Subida TAU_EDGE_RISING 1 0 Ambas TAU_EDGE_BOTH

* o símbolo TAU_EDGE_FALLING pode ser omitido já que equivale ao valor 0.

Tabela 7.6

Quando se utiliza o disparo por transição no pino, é possível ativar o filtro interno de ruído, de forma a reduzir a interferência provocada pela presença eventual de ruídos. Os registradores NFEN1 e NFEN2 controlam a ativação/desativação do filtro em cada entrada das duas unidades TAU.

O exemplo a seguir utiliza o canal 1 para gerar atrasos de 25ms. Neste exemplo o canal 0 é configurado para operar como temporizador, gerando uma interrupção a cada 300ms. Na ISR do canal 0 o led D2 da Promotion Board do RL78/G13 é aceso e o canal 1 é disparado, gerando um atraso de 25ms. Após o atraso a ISR do canal 1 apaga o led e o canal permanece aguardando um novo disparo. O resultado final é que o led pisca em pulsos rápidos. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P7_bit.no7

#pragma vector = INTTM00_vect

__interrupt void trata_TAU0_canal0(void)

LED = 0; // liga o led

TS0L = TAU_CH1; // dispara o canal 1, inicia a temporização do atraso

#pragma vector = INTTM01_vect

__interrupt void trata_TAU0_canal1(void)

LED = 1; // desliga o led

void main(void)

PM7_bit.no7 = 0; // P77 como saída

Microcontroladores RL78: Guia Básico 156

TAU0EN = 1; // habilita a TAU0

// CK1=1MHz, CK2=16MHz e CK0=CK3=125kHz

TPS0 = TAU_CK0_DIV256 | TAU_CK1_DIV32;

// configura o canal 0 no modo temporizador

TMR00 = TAU_CK0 | TAU_TRIG_SOFT | TAU_MD_TIMER;

// configura o canal 1 no modo atraso/disparo único

TMR01 = TAU_CK1 | TAU_TRIG_SOFT | TAU_MD_ONECOUNT ;

TDR00 = 37499; // canal 0 gera uma interrupção a cada 300ms

TDR01 = 24999; // canal 1 gera um atraso de 25ms

TS0L = TAU_CH0; // dispara o canal 0

TMMK00 = 0; // habilita a interrupção do canal 0 da TAU0

TMMK01 = 0; // habilita a interrupção do canal 1 da TAU0

__enable_interrupt(); // habilita as interrupções do RL78

while (1);

Exemplo 7.4

7.3.4. Operação em Modo Contador de Eventos

Quando um canal da TAU está configurado no modo contador de eventos, o clock do contador do canal é derivado do pino de entrada do canal (TImn).

A cada borda de subida ou de descida (configurável por software) do sinal no pino (TImn), o contador do canal é decrementado em um. O valor inicial do contador é determinado pelo registrador de comparação TDRmn.

Quando a contagem do contador do canal atinge o valor zero, um evento de interrupção é disparado e o respectivo flag é setado (TMIFmn = 1). Ao mesmo tempo o contador é recarregado com o valor de TDRmn.

Caso o valor do registrador TDRmn seja alterado, ele somente irá afetar a contagem no início do próximo ciclo, ou seja, após a contagem atual chegar a zero.

O número de contagens para se gerar uma interrupção é igual a TDRmn + 1.

A seleção deste modo de operação é feita através do registrador de controle (TMRmn), que deve ser configurado com os bits MD3 = 0, MD2 = 1, MD1 = 1 e MD0 = 0. É possível utilizar o símbolo TAU_MD_EVENTCOUNT para configurar o canal para operação nesta modalidade. O bit CCS deve ser setado de forma a selecionar o pino TImn como fonte de clock e a origem de disparo deve ser o software (todos os bits STS em zero).

A configuração da borda de sensibilidade do sinal de clock é feita através dos bits CIS1 e CIS0, localizados no registrador TMRmn. É possível configurar o canal para que a contagem decremente a cada borda de descida, de subida ou com qualquer borda do sinal aplicado ao pino TImn. A tabela 7.5 mostra as configurações possíveis para os bits CIS1 e CIS0.

Para iniciar a operação de contagem, o software deve armar o canal setando o bit de disparo correspondente no registrador TSm, o contador do canal (TCRmn) é carregado com o valor inicial (lido do TDRmn) e o contador permanece parado. A cada borda válida no pino TImn, o contador será decrementado conforme descrito.

Periféricos de Temporização 157

Também é possível ativar o filtro interno de ruído, de forma a reduzir a interferência provocada pela presença eventual de ruídos. Os registradores NFEN1 e NFEN2 controlam a ativação/desativação do filtro em cada entrada das duas unidades TAU.

Atenção: A frequência máxima de entrada (com filtro de ruído desativado) é de aproximadamente 12MHz.

7.3.5. Operação como Divisor de Frequência

A operação como divisor de frequência é muito similar ao modo contador de eventos, com a diferença de que a saída do canal (P01/TO00) tem o seu estado invertido a cada recarga do contador, ou seja, a cada vez que o contador atinge o valor zero ele é recarregado com o valor de TDR00.

A configuração do registrador TMR00 deve ser feita da mesma forma mostrada para o modo contador de eventos. A tabela 7.5 mostra as configurações possíveis para os bits CIS1 e CIS0 que configuram a borda de sensibilidade válida para o pino TI00.

Quando o canal está configurado para operar somente com borda de descida ou somente com borda de subida, a frequência de saída em TO00 é dada pela seguinte fórmula:

2*)100TDR(

ff 00TI

00TO+

=

Quando o canal está configurado para decrementar em ambas as bordas, a frequência de saída em TO00 é dada pela seguinte fórmula:

100TDR

ff 00TI

00TO+

=

Neste caso, o período de saída do sinal em TO00 pode exibir um erro de ±1 ciclo de clock (o clock aplicado em TI00) em virtude de erros de amostragem.

Para iniciar a operação de contagem, o software deve armar o canal setando o bit de disparo (bit 0) no registrador TS0, o contador do canal (TCR00) é carregado com o valor inicial (lido do TDR00) e o contador permanece parado. A cada borda válida no pino TI00, o contador será decrementado conforme descrito e ao chegar a zero, o estado do pino TO00 é invertido e TCR00 é recarregado com o valor de TDR00.

Caso o valor do TDR00 seja alterado, ele somente irá afetar a contagem no início do próximo ciclo, ou seja, após a contagem atual chegar a zero.

Também é possível ativar o filtro interno de ruído, de forma a reduzir a interferência provocada pela presença eventual de ruídos. O bit 0 do registrador NFEN1 permite ativar a funcionalidade do filtro de entrada.

Atenção: A frequência máxima de entrada (sem filtro) é de aproximadamente 12MHz.

Microcontroladores RL78: Guia Básico 158

7.3.6. Operação no Modo de Captura de Período

Este modo de operação permite utilizar um canal qualquer da TAU para realizar a medição do período de um sinal digital aplicado ao pino de entrada do canal.

Nesta modalidade de operação o contador do canal opera em modo crescente, iniciando sua contagem de zero e incrementando a cada ciclo da fonte de clock selecionada (CK0, CK1, CK2 ou CK3, conforme os bits CKS1 e CKS0 do registrador TMRmn).

Ao ser detectada uma borda (selecionada através dos bits CIS1 e CIS0) a contagem atual do contador (TCRmn) é captura (armazenada) no registrador TDRmn. Ao mesmo tempo o bit OVF (registrador TSRmn) é atualizado, de forma a indicar se houve estouro da contagem antes da captura ou não), a contagem do TCRmn retorna a zero e o flag de interrupção do canal (TMIFmn) é setado.

O período do sinal capturado será igual a:

CKx

)1TDRmn(TSINAL

+=

Onde: TDRmn é o valor capturado pelo canal e CKx é a frequência de clock do canal (sinal CK0, CK1, CK2 ou CK3, conforme selecionado no registrador de configuração do canal TMRmn).

Apesar do manual do fabricante informar que é possível realizar a medição do período capturado com OVF=1 (quando o valor medido é igual a TDRmn + 0x10001), esta prática deve ser evitada, pois não há garantia de que apenas um overflow de contagem ocorreu durante a medição. De fato, OVF é setado sempre que ocorre um ou mais estouros da contagem do TCRmn!

De maneira geral o bit OVF deve ser utilizado apenas como um indicador de erro, sinalizando que o período do sinal foi maior que a capacidade de medição do canal. A aplicação deve então tomar as providências cabíveis como, por exemplo, reduzir a frequência de clock do canal (aumentando consequentemente a faixa de medição).

Para operar no modo de captura de período, o registrador TMRmn deve ter os seus bits de seleção de modo configurados para 0100 (MD3=0, MD2=1, MD1=0 e MD0=0). Observe que quando MD0=0, o sinal de interrupção é disparado a cada captura e quando MD0=1, o sinal de interrupção é disparado com a partida do contador e também a cada captura. O símbolo TAU_MD_CAPTURE pode ser utilizado para configurar o canal neste modo de operação (com MD0=0) ou TAU_MD_CAPTURE_TRIG_INT para selecionar o modo de captura com MD0=1. A fonte de clock (bit CCS) deve ser sempre o clock interno (CCS=0).

A seleção da borda de captura é realizada por meio dos bits CIS1 e CIS0, conforme a tabela 7.5. É possível selecionar a captura nas bordas de subida, descida ou ambas (neste caso mede-se os semiciclos de cada período continuamente).

Os bits de seleção do modo de disparo (STS2, STS1 e STS0) devem ser configurados para STS2=0, STS1=0 e STS0=1 (borda válida no pino TImn).

Depois de configurado o canal, a operação de captura é iniciada setando-se o respectivo bit de disparo do canal (registrador TSm). Esta operação provoca a carga do valor 0x0000 no

Periféricos de Temporização 159

registrador de captura (TDRmn) e inicia a contagem crescente do contador do canal (TCRmn). Ao detectar uma borda válida no pino TImn, a contagem atual do TCRmn é armazenada no registrador TDRmn, o flag de interrupção INTTMmn é setado, o flag OVF (registrador TSRmn) é atualizado e a contagem do TCRmn é reiniciada de zero.

Uma particularidade interessante é que após a partida inicial do canal, uma captura pode ser disparada tanto pela borda válida no pino TImn quanto por um disparo por software (setando novamente o bit TSmn).

A figura 7.4 mostra uma típica operação de captura de borda de subida (CIS1=0 e CIS0=1). Se considerarmos que o clock do canal é igual a 1MHz, teremos que o período do sinal é igual a 100µs (99+1).

TSmn

TEmn

TImn

TCRmn 0 1 2 ... 48 49 0 1 2 3 ... 48 49 50 51 ... 97 98 99 0 1 2 3 ... 48 49 50 51 ... 97 98 99 0 1 2 ...

TDRmn 0 49 99 99

INTTMmn

Figura 7.4

A primeira captura após o disparo inicial do canal deve normalmente ser desprezada, pois é necessário um ciclo completo do sinal na entrada TImn para que a medição seja feita corretamente.

7.3.7. Operação no Modo de Captura de Ciclo

O modo de captura de ciclo é uma variação do modo de captura de período, porém neste modo, a contagem do canal é iniciada somente ao detectar uma borda previamente configurada no pino TImn e a captura ocorre na borda oposta. Desta forma, o período medido não é do sinal, mas do semiciclo.

Nesta modalidade de operação o contador do canal opera em modo crescente, incrementando a contagem a cada ciclo da fonte de clock selecionada (CK0, CK1, CK2 ou CK3, conforme os bits CKS1 e CKS0 do registrador TMRmn).

Ao ser detectada uma borda (selecionada através dos bits CIS1 e CIS0) a contagem do canal é iniciada (partindo de zero) e ao detectar a borda oposta, a contagem atual do contador (TCRmn) é captura (armazenada) no registrador TDRmn. Ao mesmo tempo o bit OVF (registrador TSRmn) é atualizado, de forma a indicar se houve estouro da contagem antes da captura ou não), a contagem do TCRmn retorna a zero e o flag de interrupção do canal (TMIFmn) é setado.

O período do sinal capturado será igual a:

CKx

)1TDRmn(TSINAL

+=

Microcontroladores RL78: Guia Básico 160

Onde: TDRmn é o valor capturado pelo canal e CKx é a frequência de clock do canal (sinal CK0, CK1, CK2 ou CK3, conforme selecionado no registrador de configuração do canal TMRmn).

As mesmas considerações já feitas para o bit OVF valem para este modo de operação.

Para operar no modo de captura de ciclo ativo/inativo, o registrador TMRmn deve ter os seus bits de seleção de modo configurados para 1100 (MD3=1, MD2=1, MD1=0 e MD0=0 ou através o símbolo TAU_MD_CAPTURE_LEVEL). A fonte de clock (bit CCS) deve ser sempre o clock interno (CCS=0).

A seleção da borda de captura é realizada por meio dos bits CIS1 e CIS0, conforme a tabela 7.6. É possível selecionar a captura nas bordas de subida, descida ou ambas (neste caso mede-se os semiciclos de cada período continuamente).

CIS1 CIS0 Borda de Partida Borda de Captura Símbolo C (myRL78.h) 1 0 Descida Subida TAU_EDGE_FALL_RISE 1 1 Subida Descida TAU_EDGE_RISE_FALL

Tabela 7.7

Os bits de seleção do modo de disparo (STS2, STS1 e STS0) devem ser configurados para STS2=0, STS1=1 e STS0=0 (qualquer borda válida no pino TImn).

Após configurado o canal, a operação de captura é iniciada setando-se o respectivo bit de disparo do canal (registrador TSm). Esta operação provoca a carga do valor 0x0000 no registrador de captura (TDRmn). Ao detectar uma borda de partida no pino TImn, o contador do canal inicia a contagem e ao detectar a borda de captura a contagem atual do TCRmn é armazenada no registrador TDRmn, o flag de interrupção INTTMmn é setado, o flag OVF (registrador TSRmn) é atualizado e a contagem do TCRmn retorna a zero.

A figura 7.5 mostra uma típica operação de captura de ciclo ativo (CIS1=1 e CIS0=1). Podemos verificar que a contagem do TCRmn é iniciada de zero a cada borda de subida de TImn e a contagem é capturada na borda de descida do mesmo. Se considerarmos que o clock do canal é igual a 1MHz, teremos que o período do ciclo ativo é igual a 50µs (49+1).

TSmn

TEmn

TImn

TCRmn 0 0 1 2 3 ... 48 49 0 0 1 2 3 ... 48 49 0 0 1 2 3 ...

TDRmn 0 49 49

INTTMmn

Figura 7.5

7.3.8. Operação no Modo de Pulso Configurável

Neste modo de operação utilizam-se dois canais de uma TAU para gerar um pulso único com atraso e duração programáveis.

O canal mestre é responsável pela temporização do atraso antes do pulso e o canal escravo é responsável pela temporização do pulso. Ambos operam no modo de contagem única regressiva, partindo do valor de TDRmn e decrementando até zero.

Periféricos de Temporização 161

O disparo da operação pode se dar através de um pulso na entrada TImn do canal mestre ou via software e a saída do pulso ocorre pelo pino TOmn do canal escravo.

O tempo de atraso antes do pulso é definido pela seguinte fórmula:

CKx

2TDRmestreTATRASO

+=

Onde: TDRmestre é o valor carregado no registrador de comparação do canal mestre e CKx é a frequência de clock do canal (sinal CK0 ou CK1, conforme selecionado no registrador de configuração do canal TMRmn).

A duração do pulso é definida pela seguinte fórmula:

CKx

scravoReTDTPULSO =

Onde: TDRescravo é o valor carregado no registrador de comparação do canal escravo e CKx é a frequência de clock do canal (sinal CK0 ou CK1, conforme selecionado no registrador de configuração do canal TMRmn).

O domínio de clock do canal mestre e do escravo deve ser o mesmo. Isto significa que a seleção do prescaler CKx feita para o canal escravo deve ser exatamente a mesma do canal mestre!

Para operar nesta modalidade, o registrador TMRmn do canal mestre deve ter o seu bit MASTER=1 (exceto quando se trata do canal 0) e os seus bits de seleção de modo MDx configurados para 1000 binário (MD3=1, MD2=0, MD1=0 e MD=0, símbolo TAU_MD_ONECOUNT no arquivo myRL78.h), os bits de seleção de fonte de disparo STSx devem estar configurados para disparo por software (STS2=0, STS1=0 e STS0=0) ou disparo por borda válida no pino TImn (STS2=0, STS1=0 e STS0=1), neste caso a borda válida é selecionada através dos bits CIS1 e CIS0, conforme a tabela 7.7 a seguir.

CIS1 CIS0 Borda de Sensibilidade Símbolo C (myRL78.h) 0 0 Descida TAU_EDGE_FALLING* 0 1 Subida TAU_EDGE_RISING 1 0 Ambas TAU_EDGE_BOTH

* o símbolo TAU_EDGE_FALLING pode ser omitido já que equivale ao valor 0.

Tabela 7.8

No caso do canal escravo, o registrador TMRmn deve ter os seus bits de seleção de modo MDx configurados para 1000 binário (MD3=1, MD2=0, MD1=0 e MD=0, símbolo TAU_MD_ONECOUNT no arquivo myRL78.h) e os bits de seleção de fonte de disparo STSx devem estar configurados para disparo por interrupção do mestre (STS2=1, STS1=0 e STS0=0).

A fonte de clock (bit CCS) do canal mestre e do escravo deve ser sempre o clock interno (CCS=0).

Adicionalmente, os registradores de controle de saída da TAU devem ser configurados da seguinte forma: nos registradores TOEm (habilitação da saída do canal) e TOMm (controle da saída do canal) os bits relativos ao canal escravo devem estar setados, fazendo com que o pino de

Microcontroladores RL78: Guia Básico 162

E/S seja controlado pelo canal e ativado/desativado sob controle do canal mestre e do escravo. A polaridade de saída do pulso é determinada através do registrador TOLm. Quando o bit relativo ao canal escravo está em zero, o pulso no pino TOmn tem polaridade positiva (o pulso é ativo em um) e quando o bit está setado, o pulso no pino TOmn tem polaridade negativa (o pulso é ativo em zero).

TSmestre

TEmestre

TSescravo

TEescravo

TImestre

TCRmestre 0xFFFF X X-1 X-2 ... 0 0xFFFF X X-1 X-2 ... 0

TDRmestre X

INTTMmestre

TCRescravo 0xFFFF Y Y-1 Y-2 ... 0 0xFFFF Y Y-1 Y-2 ...

TDRescravo Y

INTTMescravo

Pino TOescravo (TOL=0) X+2 Y X+2 Pino TOescravo (TOL=1) X+2 Y X+2

Figura 7.6

Observe que somente canais pares (2, 4 ou 6) podem ser configurados para o modo mestre. O canal escravo a ser utilizado será aquele de numeração imediatamente superior a do mestre, assim, caso o mestre seja o canal 0, o escravo deverá ser o canal 1, caso o mestre seja o canal 2, o escravo deverá ser o canal 3 e assim por diante.

Atenção: o canal zero pode operar como mestre mas o bit MASTER do registrador TMRm0 deve ser mantido SEMPRE em zero!

Após a configuração dos canais mestre e escravo (registradores TMRmn), a aplicação deve configurar o atraso inicial (registrador TDR do canal mestre) e largura do pulso (registrador TDR do canal escravo). Feito isso, a operação é iniciada setando-se os bits de disparo (registrador TSm) dos dois canais (mestre e escravo) simultaneamente. Esta operação faz com que os registradores TCR dos canais mestre e escravo sejam carregados com 0xFFFF e inicia a detecção de borda válida na entrada TImn do canal mestre.

Ao detectar uma borda válida o contador TCR do mestre é carregado com o valor do respectivo TDR e inicia uma contagem regressiva até zero. Durante esta contagem a saída TOmn do escravo é mantida inativa.

No instante em que a contagem do mestre atinge o valor zero é gerado um evento de interrupção no canal (que pode ou não ser utilizado pela aplicação) e a contagem do mestre é suspensa, aguardando novamente um pulso de disparo na entrada TImn.

O evento de interrupção do canal mestre provoca a carga do contador TCR do escravo com o valor do respectivo registrador TDR, a contagem regressiva do canal do canal escravo é iniciada e a saída TOmn do escravo é colocada no estado ativo.

Periféricos de Temporização 163

No instante em que a contagem do escravo atinge o valor zero é gerado um evento de interrupção no canal (que pode ou não ser utilizado pela aplicação) e a contagem do escravo é suspensa, aguardando um novo disparo do canal mestre. Ao mesmo tempo, a saída TOmn do escravo é colocada no estado inativo.

A alteração do tempo de atraso (TDR mestre) e da duração do pulso (TDR escravo) deve ser feita preferivelmente logo após o evento de interrupção de cada canal.

É possível associar mais de um canal escravo ao mestre e com isso gerar múltiplos pulsos com larguras diferentes após um atraso comum. Desta forma, uma aplicação poderia utilizar, por exemplo, o canal 2 como mestre e os canais 3 e 4 como escravos, gerando dois pulsos de larguras diferentes após um intervalo comum determinado pelo canal 2!

Enquanto o canal mestre permanece aguardando uma borda válida no pino TImn, é possível provocar um disparo através do software. Para isso, basta setar o bit de disparo do canal mestre (registrador TSm).

O exemplo a seguir dispara um pulso no pino P16 com atraso de 10ms e duração de 500µs, após detectar uma borda de descida no pino P00 (entrada do canal 0 da TAU0).

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

void main(void)

PM1_bit.no6 = 0; // P16 como saída

PU0_bit.no0 = 1; // liga pull-up do pino P00

TAU0EN = 1; // habilita a TAU0

TPS0 = TAU_CK0_DIV32; // CK0=1MHz, CK1=32MHz, CK2=16MHz e CK3=125kHz

// configura o canal 0 no modo de atraso/disparo único

TMR00 = TAU_CK0 | TAU_TRIG_VALID_EDGE | TAU_EDGE_FALLING | TAU_MD_ONECOUNT;

// configura o canal 1 no modo de atraso/disparo único controlado pelo mestre

TMR01 = TAU_CK0 | TAU_TRIG_MASTER | TAU_MD_ONECOUNT;

TDR00 = 9999; // atraso de 10ms

TDR01 = 499; // pulso de 500us

TOE0L = TAU_CH1; // habilita a saída do canal 1

Microcontroladores RL78: Guia Básico 164

TOM0L = TAU_CH1; // configura a saída do canal 1 para operar no modo

TS0L = TAU_CH0 | TAU_CH1; // dispara os canais 0 e 1

while (1);

Exemplo 7.5

A figura 7.7 mostra o comportamento da saída do canal 1 em função da entrada do canal 0.

TI00 (P00)

TO01 (P16) 10ms 0,5ms

Figura 7.7

7.3.9. Operação em Modo PWM

No modo PWM utilizam-se dois ou mais canais de uma TAU para gerar um ou mais (até 7) sinais modulados em largura de pulso (PWM). Sinais PWM são amplamente utilizados em controle de motores, controle de brilho e iluminação, etc.

O PWM na TAU utiliza o canal mestre como responsável pela temporização do período do sinal e operando no modo de intervalo (contagem regressiva), enquanto que os canais escravos são responsáveis pela temporização do ciclo ativo e operam no modo de contagem única (regressiva). A saída dos sinais PWM é realizada através dos pinos TOmn dos canais escravos.

O período do sinal PWM é definido pela seguinte fórmula:

CKx

1TDRmnTPWM

+=

Onde: TDRmn é o valor carregado no registrador de comparação do canal mestre e CKx é a frequência de clock do canal (sinal CK0 ou CK1, conforme selecionado no registrador de configuração do canal TMRmn).

A largura do ciclo ativo é definida pela seguinte fórmula:

CKx

TDRmnT ATIVO_CICLO =

Onde: TDRmn é o valor carregado no registrador de comparação do canal escravo e CKx é a frequência de clock do canal (sinal CK0 ou CK1, conforme selecionado no registrador de configuração do canal TMRmn).

O domínio de clock do canal mestre e dos escravos deve ser o mesmo. Isto significa que a seleção do prescaler CKx feita para os canais escravos deve ser exatamente a mesma do canal mestre!

Um ciclo ativo de 0% é obtido configurando-se o registrador TDR do canal escravo para o valor zero.

Um ciclo ativo de 100% é obtido configurando-se o registrador TDR do canal escravo para um valor maior ou igual ao do TDR do mestre mais um.

Periféricos de Temporização 165

O cálculo do ciclo ativo (em %) pode ser realizado através da seguinte fórmula:

100*)1TDRmestre(

scravoReTD(%)ATIVO_CICLO

+=

A resolução do sinal PWM será de 16 bits quando o período (TDR mestre) for igual a 0xFFFF, para outros valores do TDR mestre a resolução será reduzida conforme o número de contagens do período do sinal.

Em cada TAU é possível ter um conjunto de até 7 canais PWM sincronizados (utilizando o canal 0 como mestre). Também é possível utilizar outros canais (2, 4 ou 6) como mestres de forma a ter diferentes grupos com diferentes frequências de sinal PWM.

Nos RL78, um canal mestre pode ter como escravos apenas os canais de numeração superior a sua, assim, o canal 0 pode ter como escravos todos os demais canais, o canal 2 pode ter como escravos os canais 3, 4, 5, 6 e 7, o canal 4 pode ter como escravos os canais 5, 6 e 7 e o canal 6 pode ter como escravo somente o canal 7.

Também é possível ter canais operando de forma independente dos grupos de PWM, por exemplo, uma aplicação poderia ter um grupo de dois canais PWM utilizando o canal 0 como mestre e os canais 1 e 2 como escravos e outro grupo de dois canais PWM utilizando o canal 4 como mestre e os canais 5 e 6 como escravos. Neste caso, os canais 3 e 7 poderiam ser configurados para operar de forma independente dos grupos PWM.

Atenção: o canal zero pode operar como mestre mas o bit MASTER do registrador TMRm0 deve ser mantido SEMPRE em zero!

Para operar nesta modalidade, o registrador TMRmn do canal mestre deve ter o seu bit MASTER=1 (exceto quando se trata do canal 0) e os seus bits de seleção de modo MDx configurados para 0001 binário (MD3=0, MD2=0, MD1=0 e MD=1 ou utilizando o símbolo TAU_MD_TIMER_TRIG_INT), a fonte de clock (bit CCS) deve ser o clock interno (CCS=0), os bits de seleção de fonte de disparo STSx devem estar configurados para disparo por software (STS2=0, STS1=0 e STS0=0) e os bits CIS1 e CIS0 devem ser mantidos em zero.

No caso dos canais escravos, cada registrador TMRmn deve ter os seus bits de seleção de modo MDx configurados para 1001 binário (MD3=1, MD2=0, MD1=0 e MD=1 ou utilizando o símbolo TAU_MD_ONECOUNT_TRIG), a fonte de clock (bit CCS) deve ser o clock interno (CCS=0), os bits de seleção de fonte de disparo STSx devem estar configurados para disparo por interrupção do mestre (STS2=1, STS1=0 e STS0=0) e os bits CIS1 e CIS0 devem ser mantidos em zero.

Adicionalmente, os registradores de controle de saída da TAU devem ser configurados da seguinte forma: nos registradores TOEm (habilitação da saída do canal) e TOMm (controle da saída do canal) os bits relativos aos canais escravos devem estar setados, fazendo com que os pinos de E/S sejam controlado pelos canais e ativados/desativados sob controle do canal mestre e dos escravos. A polaridade de saída dos sinais é determinada pelo registrador TOLm. Quando o bit relativo ao canal está em zero, o sinal no pino TOmn tem polaridade positiva (ciclo ativo em nível um) e quando o bit está setado, o sinal no pino TOmn tem polaridade negativa (ciclo ativo em nível zero).

Microcontroladores RL78: Guia Básico 166

TSmestre

TEmestre

TSescravo

TEescravo

TCRmestre X X-1 X-2 ... 3 2 1 0 X X-1 X-2 ... 3 2 1 0 X X-1 X-2 ... 3 2 1 0 X X-1 X-2 ... 3 2 1 0

TDRmestre X

INTTMmestre TCRescravo Y Y-1 ... 1 0 Y Y-1 ... 1 0 Y Y-1 ... 1 0 Y Y-1 ... 1 0

TDRescravo Y

INTTMescravo

Pino TOescravo (TOL=0) Ciclo ativo Ciclo ativo Ciclo ativo Ciclo ativo

Pino TOescravo (TOL=1) Ciclo ativo Ciclo ativo Ciclo ativo Ciclo ativo

Figura 7.8

Após a configuração dos canais mestre e escravos (registradores TMRmn), a aplicação deve configurar o período do sinal PWM (registrador TDR do canal mestre) e largura do ciclo ativo de cada canal (registradores TDR dos canais escravos). Feito isso, a operação é iniciada setando-se os bits de disparo (registrador TSm) de todos os canais envolvidos (mestre e escravos) simultaneamente. Esta operação faz com que os registradores TCR dos canais mestre e escravos sejam carregados com o conteúdo dos respectivos TDRs e inicia a contagem regressiva nos canais.

No instante em que um canal escravo atinge a contagem zero, a respectiva saída (TOmn) é invertida e permanece desta forma até que o canal mestre atinja a contagem zero, quando então todos os canais escravos têm as suas saídas configuradas para o estado de repouso (conforme a configuração do registrador TOLm).

A alteração do período do sinal PWM (TDR mestre) e do ciclo ativo (TDR dos escravos) deve ser feita preferivelmente logo após o evento de interrupção de cada canal.

O exemplo a seguir demonstra como configurar os canais 1 e 2 para operar no modo escravo controlando o ciclo ativo de sinais PWM, tendo o canal 0 como mestre, controlando o período do sinal. O exemplo gera dois sinais de 1kHz, com ciclo ativo de 10% no canal 1 (pino P16) e de 90% no canal 2 (pino P17), conforme mostra a figura 7.9. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

Periféricos de Temporização 167

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

void main(void)

PM1 = 0x3F; // P17 e P16 como saídas (canais 1 e 2 da TAU0)

TAU0EN = 1; // habilita a TAU0

TPS0 = TAU_CK0_DIV32; // CK0=1MHz, CK1=32MHz, CK2=16MHz e CK3=125kHz

// configura o canal 0 no modo mestre para PWM

TMR00 = TAU_CK0 | TAU_TRIG_SOFT | TAU_MD_TIMER_TRIG_INT;

// configura os canais 1 e 2 no modo escravo para PWM

TMR01 = TAU_CK0 | TAU_TRIG_MASTER | TAU_MD_ONECOUNT_TRIG;

TMR02 = TAU_CK0 | TAU_TRIG_MASTER | TAU_MD_ONECOUNT_TRIG;

TDR00 = 999; // período do sinal PWM = 1kHz

TDR01 = 100; // canal 1 = 10% de ciclo ativo

TDR02 = 900; // canal 2 = 90% de ciclo ativo

TOE0L = TAU_CH2 | TAU_CH1; // habilita a saída dos canais 1 e 2 da TAU0

// saída dos canais 1 e 2 controladas pelo mestre/escravo

TOM0L = TAU_CH2 | TAU_CH1;

// dispara os canais mestre e escravos

TS0L = TAU_CH0 | TAU_CH1 | TAU_CH2;

while (1);

Exemplo 7.6

TO02 (P17)

TO01 (P16)

1ms

Figura 7.9

7.3.10. Registradores das TAU Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0

PRSm31

PRSm30

0 0 PRSm21

PRSm20

PRSm13

PRSm12

PRSm11

PRSm10

PRSm03

PRSm02

PRSm01

PRSm00 TPSm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1)

Nome do Bit Descrição Símbolo C Seleção do divisor do CK3 da TAU:

00 - fclk dividido por 256 TAU_CK3_DIV256

01 - fclk dividido por 1024 TAU_CK3_DIV1024

10 - fclk dividido por 4096 TAU_CK3_DIV4096

PRSm31 PRSm30

11 - fclk dividido por 16384 TAU_CK3_DIV16384

Seleção do divisor do CK2 da TAU:

00 - fclk dividido por 2 TAU_CK2_DIV2

01 - fclk dividido por 4 TAU_CK2_DIV4

10 - fclk dividido por 16 TAU_CK2_DIV16

PRSm21 PRSm20

11 - fclk dividido por 64 TAU_CK2_DIV64

Microcontroladores RL78: Guia Básico 168

Seleção do divisor do CK0 e CK1 da TAU:

0000 - fclk (nenhuma divisão) TAU_CKx_DIV1

0001 - fclk dividido por 2 TAU_CKx_DIV2

0010 - fclk dividido por 4 TAU_CKx_DIV4

0011 - fclk dividido por 8 TAU_CKx_DIV8

0100 - fclk dividido por 16 TAU_CKx_DIV16

0101 - fclk dividido por 32 TAU_CKx_DIV32

0110 - fclk dividido por 64 TAU_CKx_DIV64

0111 - fclk dividido por 128 TAU_CKx_DIV128

1000 - fclk dividido por 256 TAU_CKx_DIV256

1001 - fclk dividido por 512 TAU_CKx_DIV512

1010 - fclk dividido por 1024 TAU_CKx_DIV1024

1011 - fclk dividido por 2048 TAU_CKx_DIV2048

1100 - fclk dividido por 4096 TAU_CKx_DIV4096

1101 - fclk dividido por 8192 TAU_CKx_DIV8192

1110 - fclk dividido por 16384 TAU_CKx_DIV16384

PRSm13 PRSm12 PRSm11 PRSm10 PRSm03 PRSm02 PRSm01 PRSm00

1111 - fclk dividido por 32768 TAU_CKx_DIV32768

Nota: x pode ser 0 ou 1, por exemplo, TAU_CK0_DIV1 para o CK0 ou TAU_CK1_DIV1 para o CK1

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita CKS1 CKS0 0 CCS

MASTER/SPLI

T

STS2 STS1 STS0 CIS1 CIS0 0 0 MD3 MD2 MD1 MD0 TMRmn

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1) e n corresponde ao canal (0 a 7)

Nome do Bit Descrição Símbolo C Seleção da fonte de clock do canal:

00 – prescaler CK0 TAU_CK0

01 – prescaler CK2 (somente nos canais 1 e 3) TAU_CK2

10 – prescaler CK1 TAU_CK1

CKS1 CKS0

11 – prescaler CK3 (somente nos canais 1 e 3) TAU_CK3

CCS

Seleção da fonte de clock do canal: 0 – o clock do canal é derivado de um dos 4 prescalers da TAU 1 – o clock do canal é derivado da entrada externa do canal (pino TImn)

bTAU_CCS

MASTER

Nos canais 2, 4 e 6, este bit configura o canal para operação independente ou combinada: 0 – canal operando de forma independente ou como escravo de outro canal 1 – canal operando como mestre de outros canais * nos canais 0, 5 e 7 este bit deve ser mantido em zero!

bTAU_MASTER

SPLIT

Nos canais 1 e 3, este bit configura o canal para operar em 8 ou 16 bits: 0 – canal operando em 16 bits 1 – canal operando em 8 bits

bTAU_8BIT

Periféricos de Temporização 169

Nome do Bit Descrição Símbolo C Seleção do modo de disparo e de captura do canal:

000 – disparo somente por software TAU_TRIG_SOFT

001 – uma borda válida no pino TImn provoca o disparo e a captura TAU_TRIG_VALID_EDGE

010 – qualquer transição no pino TImn provoca o disparo e a captura

TAU_TRIG_BOTH_EDGE

100 – disparo e captura gerados por um sinal de interrupção do canal mestre

TAU_TRIG_MASTER

STS2 STS1 STS0

Outras configurações não são permitidas -

Seleção da borda válida para entrada no pino TImn:

00 – borda de descida TAU_EDGE_FALLING

01 – borda de subida TAU_EDGE_RISING

10 – ambas as bordas (disparo ocorre na descida, captura na subida), medição de ciclo inativo

TAU_EDGE_FALL_RISE TAU_EDGE_BOTH

CIS1 CIS0

11 – ambas as bordas (disparo ocorre na subida, captura na descida), medição de ciclo ativo

TAU_EDGE_RISE_FALL

Seleção do modo de operação do canal da TAU:

0000 – modo de timer de intervalo (não gera interrupção no disparo do canal)

TAU_MD_TIMER

0001 – modo de timer de intervalo (gera interrupção no disparo do canal)

TAU_MD_TIMER_TRIG_INT

0100 – modo de captura de período de sinal (não gera interrupção no disparo do canal)

TAU_MD_CAPTURE

0101 – modo de captura de período de sinal (gera interrupção no disparo do timer) TAU_MD_CAPTURE_TRIG_INT

0110 – modo de contagem de eventos (não gera interrupção no disparo do timer) TAU_MD_EVENTCOUNT

1000 – modo de contagem única (não permite re-disparo) TAU_MD_ONECOUNT

1001 – modo de contagem única (re-disparo reinicia a contagem) TAU_MD_ONECOUNT_TRIG

MD3 MD2 MD1 MD0

1100 – modo de captura de ciclo ativo/inativo TAU_MD_CAPTURE_LEVEL

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 OVF

TSRmn

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

* m corresponde ao número da TAU (0 ou 1) e n corresponde ao canal (0 a 7)

* Os 8 bits menos significativos podem ser acessados através do registrador TSRmnL

O bit OVF é setado nos modos de captura quando o contador do canal (TCRmn) estoura a contagem sem que tenha ocorrido uma captura. Ele é automaticamente apagado quando ocorre uma captura sem estouro da contagem do canal.

Microcontroladores RL78: Guia Básico 170

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura 0 0 0 0 TEHm3

0 TEHm1

0 TEm7 TEm6 TEm5 TEm4 TEm3 TEm2 TEm1 TEm0

Escrita - - - - - - - - - - - - - - - - TEm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1) * Os 8 bits menos significativos podem ser acessados através do registrador TEmL

Nome do Bit Descrição Símbolo C

TEHm3 Indicador de operação da parte alta do canal 3 (modo de 8 bits): 0 – desabilitado 1 – habilitado

TAU_CH3_8BIT

TEHm1 Indicador de operação da parte alta do canal 1 (modo de 8 bits): 0 – desabilitado 1 – habilitado

TAU_CH1_8BIT

TEm7 TEm6 TEm5 TEm4 TEm3 TEm2 TEm1 TEm0

Indicador de operação dos canais 0 a 7 da TAU: 0 – desabilitado 1 – habilitado

TAU_CH7 TAU_CH6 TAU_CH5 TAU_CH4 TAU_CH3 TAU_CH2 TAU_CH1 TAU_CH0

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0

TSHm3

0 TSHm1

0 TSm7 TSm6 TSm5 TSm4 TSm3 TSm2 TSm1 TSm0 TSm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1) * Os 8 bits menos significativos podem ser acessados através do registrador TSmL

Nome do Bit Descrição Símbolo C

TSHm3 Controle de disparo da parte alta do canal 3 (modo de 8 bits) 0 – sem efeito 1 – inicia contagem (modo timer)

TAU_CH3_8BIT

TSHm1 Controle de disparo da parte alta do canal 1 (modo de 8 bits) 0 – sem efeito 1 – inicia contagem (modo timer)

TAU_CH1_8BIT

TSm7 TSm6 TSm5 TSm4 TSm3 TSm2 TSm1 TSm0

Controle de disparo dos canais 0 a 7 da TAU: 0 – sem efeito 1 – inicia a operação conforme o modo selecionado

TAU_CH7 TAU_CH6 TAU_CH5 TAU_CH4 TAU_CH3 TAU_CH2 TAU_CH1 TAU_CH0

Periféricos de Temporização 171

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0

TTHm3

0 TTHm1

0 TTm7 TTm6 TTm5 TTm4 TTm3 TTm2 TTm1 TTm0 TTm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1)

* Os 8 bits menos significativos podem ser acessados através do registrador TTmL

Nome do Bit Descrição Símbolo C

TTHm3 Controle de parada da parte alta do canal 3 (modo de 8 bits): 0 – sem efeito 1 – para a contagem do canal

TAU_CH3_8BIT

TTHm1 Controle de parada da parte alta do canal 1 (modo de 8 bits): 0 – sem efeito 1 – para a contagem do canal

TAU_CH1_8BIT

TTm7 TTm6 TTm5 TTm4 TTm3 TTm2 TTm1 TTm0

Controle de parada dos canais 0 a 7 da TAU: 0 – sem efeito 1 – para a contagem do canal

TAU_CH7 TAU_CH6 TAU_CH5 TAU_CH4 TAU_CH3 TAU_CH2 TAU_CH1 TAU_CH0

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 TIS02 TIS01 TIS00

TIS0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

TIS02 TIS01 TIS00

Seleção da entrada de clock externo do canal 5 da TAU0: 000 – Pino TI05 001 – Pino TI05 010 – Pino TI05 011 – Pino TI05 100 – Oscilador LOCO (15kHz) 101 – Oscilador XT1

TIS_TI05

- - -

TIS_LOCO TIS_XT1

Microcontroladores RL78: Guia Básico 172

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0

TOEm7

TOEm6

TOEm5

TOEm4

TOEm3

TOEm2

TOEm1

TOEm0 TOEm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1)

* Os 8 bits menos significativos podem ser acessados através do registrador TOEmL

Nome do Bit Descrição Símbolo C TOEm7 TOEm6 TOEm5 TOEm4 TOEm3 TOEm2 TOEm1 TOEm0

Controle de habilitação das saídas dos canais 0 a 7 da TAU: 0 – saída desabilitada 1 – saída habilitada e controlada pelo canal

TAU_CH7 TAU_CH6 TAU_CH5 TAU_CH4 TAU_CH3 TAU_CH2 TAU_CH1 TAU_CH0

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0

TOm7

TOm6

TOm5

TOm4

TOm3

TOm2

TOm1

TOm0 TOm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1) * Os 8 bits menos significativos podem ser acessados através do registrador TOmL

Nome do Bit Descrição Símbolo C TOm7 TOm6 TOm5 TOm4 TOm3 TOm2 TOm1 TOm0

Controle das saídas dos canais 0 a 7 da TAU (somente quando TOEmn = 0): 0 – saída em nível zero 1 – saída em nível um

TAU_CH7 TAU_CH6 TAU_CH5 TAU_CH4 TAU_CH3 TAU_CH2 TAU_CH1 TAU_CH0

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0

TOLm7

TOLm6

TOLm5

TOLm4

TOLm3

TOLm2

TOLm1

0 TOLm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1) * Os 8 bits menos significativos podem ser acessados através do registrador TOLmL

Nome do Bit Descrição Símbolo C TOLm7 TOLm6 TOLm5 TOLm4 TOLm3 TOLm2 TOLm1

Controle de polaridade da saída dos canais 0 a 7 da TAU (somente quando TOEmn = 1 e com o canal operando como escravo nos modos PWM ou pulso único (TOMmn = 0)): 0 – lógica positiva (ativo em nível um) 1 – lógica negativa (ativo em nível zero)

TAU_CH7 TAU_CH6 TAU_CH5 TAU_CH4 TAU_CH3 TAU_CH2 TAU_CH1

Periféricos de Temporização 173

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0

TOMm7

TOMm6

TOMm5

TOMm4

TOMm3

TOMm2

TOMm1

0 TOMm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da TAU (0 ou 1) * Os 8 bits menos significativos podem ser acessados através do registrador TOMmL

Nome do Bit Descrição Símbolo C TOMm7 TOMm6 TOMm5 TOMm4 TOMm3 TOMm2 TOMm1

Seleção do modo de controle do canal (mestre ou escravo). Este registrador somente tem função quando o pino TOmn é controlado pelo canal (bit TOEmn = 1). 0 – modo mestre – a saída do canal é controlada pelo canal mestre 1 – modo escravo – a saída do canal é setada pelo canal mestre e

apagada pelo escravo (este canal). O nível lógico da saída depende da polaridade selecionada no registrador TOLm

TAU_CH7 TAU_CH6 TAU_CH5 TAU_CH4 TAU_CH3 TAU_CH2 TAU_CH1

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 0 ISC1 ISC0

ISC

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

ISC1

Seleção da entrada do canal 7 da TAU0 (apenas nos modelos com 30 pinos ou mais): 0 – entrada via pino TI07 1 – entrada do canal conectada ao RxD2 (para operação LIN)

bISC1

ISC0 Seleção da entrada de interrupção externa INTP0: 0 – sinal de interrupção derivado do pino INTP0 1 – sinal de interrupção derivado de RxD2 (para operação LIN)

bISC0

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita TNFEN07 TNFEN06 TNFEN05 TNFEN04 TNFEN03 TNFEN02 TNFEN01 TNFEN00

NFEN1

Reset 0 0 0 0 0 0 0 0

Leitura

Escrita TNFEN17 TNFEN16 TNFEN15 TNFEN14 TNFEN13 TNFEN12 TNFEN11 TNFEN10

NFEN2

Reset 0 0 0 0 0 0 0 0

Estes registradores permitem ativar os filtros de ruído existentes nas entradas dos canais das unidades TAU. Quando ativados (TNFENxx = 1), o sinal de entrada (via pino TImn) precisa estar estável por dois ciclos fCLK para que ele seja detectado pelo timer.

Nome do Bit Descrição Símbolo C

TNFEN17 Controle do filtro de ruído do pino TI17/TO17/P106: 0 – filtro desligado 1 – filtro ligado

bTNFEN17

Microcontroladores RL78: Guia Básico 174

Nome do Bit Descrição Símbolo C

TNFEN16 Controle do filtro de ruído do pino TI16/TO16/P105: 0 – filtro desligado 1 – filtro ligado

bTNFEN16

TNFEN15 Controle do filtro de ruído do pino TI15/TO15/P104: 0 – filtro desligado 1 – filtro ligado

bTNFEN15

TNFEN14 Controle do filtro de ruído do pino TI14/TO14/P103: 0 – filtro desligado 1 – filtro ligado

bTNFEN14

TNFEN13 Controle do filtro de ruído do pino TI13/TO13/P67: 0 – filtro desligado 1 – filtro ligado

bTNFEN13

TNFEN12 Controle do filtro de ruído do pino TI12/TO12/P66: 0 – filtro desligado 1 – filtro ligado

bTNFEN12

TNFEN11 Controle do filtro de ruído do pino TI11/TO11/P65: 0 – filtro desligado 1 – filtro ligado

bTNFEN11

TNFEN10 Controle do filtro de ruído do pino TI10/TO10/P64: 0 – filtro desligado 1 – filtro ligado

bTNFEN10

TNFEN07

Controle do filtro de ruído do pino TI07/TO07/P145 ou entrada RxD2/P14 (conforme bit ISC1): 0 – filtro desligado 1 – filtro ligado

bTNFEN7

TNFEN06 Controle do filtro de ruído do pino TI06/TO06/P102: 0 – filtro desligado 1 – filtro ligado

bTNFEN6

TNFEN05 Controle do filtro de ruído do pino TI05/TO05/P46: 0 – filtro desligado 1 – filtro ligado

bTNFEN5

TNFEN04 Controle do filtro de ruído do pino TI04/TO04/P04: 0 – filtro desligado 1 – filtro ligado

bTNFEN4

TNFEN03 Controle do filtro de ruído do pino TI03/TO03/P31: 0 – filtro desligado 1 – filtro ligado

bTNFEN3

TNFEN02 Controle do filtro de ruído do pino TI02/TO02/P17: 0 – filtro desligado 1 – filtro ligado

bTNFEN2

TNFEN01 Controle do filtro de ruído do pino TI01/TO01/P16: 0 – filtro desligado 1 – filtro ligado

bTNFEN1

TNFEN00 Controle do filtro de ruído do pino TI00/TO00/P00: 0 – filtro desligado 1 – filtro ligado

bTNFEN0

Periféricos de Temporização 175

7.4. Outros Timers

Além dos timers vistos até aqui, alguns modelos de RL78 (como os G14) incluem outros timers com funções especiais:

Timer RJ: timer de 16 bits que pode ser utilizado para geração de pulsos, medição de largura e período de pulsos e contagem de eventos externos, ele também pode receber clock do módulo ELC (Event Link Controller).

Timer RD: composto por dois timers de 16 bits e capaz de operar a até 64MHz (utilizando o clock interno dos RL78/G14). Possui dois grupos de 4 canais que podem ser utilizados no modo temporizador, captura de sinais (medição de período), comparação (geração de sinais periódicos) e diversos modos PWM para controle de motores (até 6 canais com dead time e modulação).

Timer RG: timer de 16 bits com duas entradas e dois pinos de E/S (para captura, comparação ou PWM). Este timer inclui um modo especial para decodificação de encoders bifásicos.

Microcontroladores RL78: Guia Básico 176

Periféricos Analógicos 177

8

Periféricos Analógicos 8. Periféricos de Analógicos

O conversor A/D (Analógico/Digital) ou simplesmente ADC, é o dispositivo eletrônico que permite ao microcontrolador realizar a leitura de sinais do mundo analógico, em especial tensões, provenientes das mais variadas fontes: sensores, transdutores, etc.

Na área de microcontroladores, encontramos chips com conversor integrado e outros que dependem de conversores externos. Nos modelos que possuem conversor integrado, eles apresentam resoluções típicas de 10 bits (alguns modelos possuem conversores mais simples, de 8 bits, enquanto outros possuem conversores de maior precisão, com 12 ou 16 bits).

Neste capítulo iremos conhecer o conversor A/D integrado aos RL78/G13. Este conversor possui uma resolução de 10 bits (podendo também operar com apenas 8 bits) e pode ser encontrado em todos os modelos das linhas RL78/G10, G12, G13 e G14, desde os modelos menores, com apenas 10 pinos, até os maiores, com 128 pinos.

8.1. Detalhes Gerais do Conversor A/D

O conversor A/D ou simplesmente ADC dos RL78 é do tipo SAR, o que significa que ele utiliza um registrador de aproximações sucessivas para fazer a conversão de grandezas analógicas para grandezas digitais.

Não vamos discutir neste livro a operação do conversor SAR (que é bastante simples), basta dizer que ele é substancialmente mais rápido que outros tipos de conversores, como o de rampa digital, garantindo ótima velocidade e baixo custo.

Como já foi dito, o conversor A/D dos RL78 pode operar com 8 ou 10 bits de resolução, ou seja, para um sinal de entrada na faixa de 0 a 5V, com uma resolução de 10 bits, cada bit irá representar uma tensão de cerca de 4,88mV ou 19,53mV no caso de uma resolução de 8 bits.

O ADC é composto por diversos blocos:

• Seletor analógico: responsável por selecionar um dos canais (pinos ou referências internas) a ser convertido pelo ADC;

• Circuito de amostragem e retenção: responsável por armazenar (num pequeno capacitor) a tensão a ser medida, de forma a garantir que ela não mude durante a conversão;

• Comparador analógico: responsável por comparar a tensão desconhecida a ser convertida com a tensão proveniente do SAR/DAC, gerando uma saída de erro que alimenta o SAR;

Microcontroladores RL78: Guia Básico 178

• DAC: converte a saída digital do SAR em uma tensão analógica que pode ser comparada com a tensão desconhecida no comparador analógico;

• SAR: o “cérebro” do conversor, responsável pelo algoritmo de aproximação que, utilizando a realimentação do comparador analógico, permite ao mesmo convergir digitalmente para o valor da tensão desconhecida.

Note que apesar do conversor possuir diversos canais de entrada, somente um deles pode ser selecionado, amostrado e convertido num dado instante. Isto significa que não é possível realizar múltiplas conversões simultaneamente.

Os procedimentos para operação do ADC são bastante simples. Em primeiro lugar é necessário ativar o conversor, o que é feito através do já conhecido registrador PER0:

Nome Bits 7 6 5 4 3 2 1 0

Leitura

Escrita RTCEN IICA1EN ADCEN IICA0EN SAU1EN SAU0EN TAU1EN TAU0EN

PER0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Bit C Símbolo C

ADCEN Controle de clock e operação do conversor analógico/digital: 0 – ADC desativado 1 – ADC ativado

ADCEN bADCEN

Uma vez ativado o conversor, a aplicação deve configurar os pinos que serão utilizados pelo ADC para operar como entradas no modo analógico. A configuração dos pinos como entrada é feita nos registradores PMx, ao passo que a seleção do modo analógico é feita através dos registradores ADPC (para as entradas ANI0 a ANI14) e PMCx (para as entradas ANI16 a ANI26).

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 ADPC3 ADPC2 ADPC1 ADPC0

ADPC

Reset 0 0 0 0 0 0 0 0

Valor em ADPC

AN

I14/

P15

6

AN

I13/

P15

5

AN

I12/

P15

4

AN

I11/

P15

3

AN

I10/

P15

2

AN

I9/P

151

AN

I8/P

150

AN

I7/P

27

AN

I6/P

26

AN

I5/P

25

AN

I4/P

24

AN

I3/P

23

AN

I2/P

22

AN

I1/P

21

AN

I0/P

20

0 A A A A A A A A A A A A A A A 1 D D D D D D D D D D D D D D D 2 D D D D D D D D D D D D D D A 3 D D D D D D D D D D D D D A A 4 D D D D D D D D D D D D A A A 5 D D D D D D D D D D D A A A A 6 D D D D D D D D D D A A A A A 7 D D D D D D D D D A A A A A A 8 D D D D D D D D A A A A A A A 9 D D D D D D D A A A A A A A A

10 D D D D D D A A A A A A A A A

Periféricos Analógicos 179

Valor em ADPC

AN

I14/

P15

6

AN

I13/

P15

5

AN

I12/

P15

4

AN

I11/

P15

3

AN

I10/

P15

2

AN

I9/P

151

AN

I8/P

150

AN

I7/P

27

AN

I6/P

26

AN

I5/P

25

AN

I4/P

24

AN

I3/P

23

AN

I2/P

22

AN

I1/P

21

AN

I0/P

20

11 D D D D D A A A A A A A A A A 12 D D D D A A A A A A A A A A A 13 D D D A A A A A A A A A A A A 14 D D A A A A A A A A A A A A A 15 D A A A A A A A A A A A A A A

Tabela 8.1

As entradas ANI16 a ANI26 são controlados pelos registradores PMCx, conforme a tabela a seguir. Note que os demais bits dos registradores não estão implementados e devem ser mantidos em 1. Além disso, os registradores PMCx são carregados com o valor 0xFF após um reset.

Bits Implementados Encapsulamento (número de pinos) Porta 14 Porta 12 Porta 11 Porta 10 Porta 3 Porta 0

20 a 25 PMC147 - - - - PMC00 PMC01

30 a 32 PMC147 PMC120 - - - PMC00 PMC01

36 a 48 PMC147 PMC120 - - - -

52 a 64 PMC147 PMC120 - - - PMC02 PMC03

80 a 100 PMC147 PMC120 - PMC100 - PMC02 PMC03

128 PMC147 PMC120 PMC115 PMC116 PMC117

PMC100 PMC35 PMC36 PMC37

PMC02 PMC03

Tabela 8.2

A tabela a seguir relaciona os pinos com as entradas analógicas do conversor A/D. Canal Pino Canal Pino

0 P20/AVREFP 13 P155 1 P21/AVREFM 14 P156 2 P22 16 P03*1 3 P23 17 P02*2 4 P24 18 P147 5 P25 19 P120 6 P26 20 P100 7 P27 21 P37 8 P150 22 P36 9 P151 23 P35

10 P152 24 P117 11 P153 25 P116 12 P154 26 P115

*1 Nos chips com 32 pinos ou menos, este canal está conectado ao pino P01 *2 Nos chips com 32 pinos ou menos, este canal está conectado ao pino P00

Tabela 8.3

Microcontroladores RL78: Guia Básico 180

Depois de configurados os pinos de E/S para operação como entradas analógicas, a aplicação deve configurar o conversor A/D através dos seus três registradores de controle: ADM0, ADM1 e ADM2.

O registrador ADM0 configura o clock do conversor, habilitação e início de conversão, além do modo de operação (um canal ou uma varredura de quatro canais).

O bit ADCE controla a atividade do comparador analógico de tensão dentro do conversor, quando este bit está setado, o comparador está ligado e o conversor pode realizar uma conversão, quando ADCE=0 o conversor está desativado.

A seleção do clock do conversor é feita através dos bits FR2, FR1 e FR0, eles controlam o fator de divisão aplicado ao sinal de clock global fCLK (que, conforme já vimos no tópico 4.2, pode ser derivado do oscilador interno, do oscilador X1 ou do oscilador XT1) e que origina o sinal de clock do A/D, chamado de fAD. A tabela a seguir mostra as configurações possíveis para os bits FRx.

FR2 FR1 FR0 Clock do ADC (fAD) Tempo de atraso (fCLK) Símbolo C (myRL78.h) 0 0 0 fclk/64 63 ADCLK_DIV64 0 0 1 fclk/32 31 ADCLK_DIV32 0 1 0 fclk/16 15 ADCLK_DIV16 0 1 1 fclk/8 7 ADCLK_DIV8 1 0 0 fclk/6 5 ADCLK_DIV6 1 0 1 fclk/5 4 ADCLK_DIV5 1 1 0 fclk/4 3 ADCLK_DIV4 1 1 1 fclk/2 1 ADCLK_DIV2

Tabela 8.4

Observe que a tabela mostra também uma coluna “Tempo de atraso”, este tempo é utilizado em alguns modos de disparo do conversor, conforme será detalhado mais adiante.

Um ciclo de conversão A/D é iniciado quando o conversor recebe um sinal de disparo. Existem duas fontes de disparo para iniciar uma conversão: um comando de software ou um sinal de interrupção derivado do hardware (interrupção do canal 1 da TAU0, interrupção do RTC ou interrupção do timer de intervalo).

Após o atraso mencionado o conversor inicia a amostragem do sinal, ou seja, a tensão analógica a ser medida é conectada ao capacitor de amostragem do conversor, que irá se carregar até os níveis serem equalizados. O período de amostragem pode ser de 5 ou 7 ciclos de clock fAD conforme a configuração dos bits LV1 e LV0 (registrador ADM0).

FR2 FR1 FR0 LV1, LV0 fAD Tempo de Estabilização Amostragem Conversão Tempo Total

de Conversão 0 0 0 fclk/64 1344/fclk 0 0 1 fclk/32 672/fclk 0 1 0 fclk/16 336/fclk 0 1 1 fclk/8 168/fclk 1 0 0 fclk/6 126/fclk 1 0 1 fclk/5 105/fclk 1 1 0 fclk/4 84/fclk 1 1 1

00

fclk/2

2 fAD 7 fAD 12 fAD

42/fclk

Tabela 8.5

Periféricos Analógicos 181

FR2 FR1 FR0 LV1, LV0 fAD Tempo de Estabilização Amostragem Conversão Tempo Total

de Conversão 0 0 0 fclk/64 1728/fclk 0 0 1 fclk/32 864/fclk 0 1 0 fclk/16 432/fclk 0 1 1 fclk/8 216/fclk 1 0 0 fclk/6 162/fclk 1 0 1 fclk/5 135/fclk 1 1 0 fclk/4 108/fclk 1 1 1

00

fclk/2

8 fAD 7 fAD 12 fAD

54/fclk 0 0 0 fclk/64 1216/fclk 0 0 1 fclk/32 608/fclk 0 1 0 fclk/16 304/fclk 0 1 1 fclk/8 152/fclk 1 0 0 fclk/6 114/fclk 1 0 1 fclk/5 96/fclk 1 1 0 fclk/4 76/fclk 1 1 1

01

fclk/2

2 fAD 5 fAD 12 fAD

38/fclk 0 0 0 fclk/64 1600/fclk 0 0 1 fclk/32 800/fclk 0 1 0 fclk/16 400/fclk 0 1 1 fclk/8 200/fclk 1 0 0 fclk/6 150/fclk 1 0 1 fclk/5 125/fclk 1 1 0 fclk/4 100/fclk 1 1 1

01

fclk/2

8 fAD 5 fAD 12 fAD

50/fclk 0 0 0 fclk/64 1216/fclk 0 0 1 fclk/32 608/fclk 0 1 0 fclk/16 304/fclk 0 1 1 fclk/8 152/fclk 1 0 0 fclk/6 114/fclk 1 0 1 fclk/5 96/fclk 1 1 0 fclk/4 76/fclk 1 1 1

10

fclk/2

- 7 fAD 12 fAD

38/fclk 0 0 0 fclk/64 1088/fclk 0 0 1 fclk/32 544/fclk 0 1 0 fclk/16 272/fclk 0 1 1 fclk/8 136/fclk 1 0 0 fclk/6 102/fclk 1 0 1 fclk/5 85/fclk 1 1 0 fclk/4 68/fclk 1 1 1

11

fclk/2

- 5 fAD 12 fAD

34/fclk

Tabela 8.6

Após a amostragem do sinal, o capacitor de amostragem é desconectado do sinal a ser medido e conectado ao conversor e o processo de conversão A/D propriamente dito tem início. A conversão necessita de 10 ciclos fAD (para uma resolução de 8 bits) ou 12 ciclos (para uma resolução de 10 bits) para ser completada. A seleção da resolução é feita por meio do bit ADTYP (registrador ADM2): quando ADTYP=0, o conversor opera com 10 bits, quando ADTYP=1, o conversor opera com 8 bits.

O tempo total necessário para completar uma conversão pode ser determinado pela seguinte fórmula:

Microcontroladores RL78: Guia Básico 182

CONVERSÃOAMOSTRAGEMESTABATRASOCONV_TOTAL TTTTT +++=

Onde:

TATRASO é o tempo de atraso conforme a tabela 8.4 (válido para disparo por software e para o disparo por hardware sem atraso, no caso do disparo por hardware com atraso, este tempo é igual a um ciclo). Este atraso é medido em ciclos fCLK.

TESTAB é o tempo de estabilização. Ele pode ser de 2 ou 8 ciclos fAD no modo de disparo por hardware com atraso. Nos modos de disparo por software e disparo por hardware sem atraso, o tempo de estabilização é igual a 0.

TAMOSTRAGEM é o tempo de amostragem (5 ou 7 ciclos fAD) conforme mostra as tabelas 8.5 e 8.6.

TCONVERSÃO é o tempo de conversão SAR (10 ciclos fAD para 8 bits ou 12 ciclos fAD para 10 bits).

Os tempos TATRASO e TESTAB são utilizados na primeira conversão após um sinal de disparo. Quando se utiliza o modo de varredura ou o modo de conversões múltiplas, estes tempos são utilizados apenas na primeira conversão, mas não nas posteriores.

Completada a conversão, o resultado é comparado com os registradores de comparação digital ADUL (valor limite superior) e ADLL (valor limite inferior). A operação do comparador digital é controlada pelo bit ADRCK (registrador ADM2). Quando ADRCK=0, o comparador gera uma interrupção INTAD e atualiza o registrador ADCR quando o resultado da conversão (8 bits mais significativos) é menor ou igual ao valor do registrador ADUL e maior ou igual ao valor do registrador ADLL, ou seja, dentro da faixa entre ADLL e ADUL. Quando ADRCK=1, o comparador gera uma interrupção INTAD e atualiza o registrador ADCR quando o resultado da conversão (8 bits mais significativos) é maior que ao valor do registrador ADUL ou menor que valor do registrador ADLL, ou seja, fora da faixa entre ADLL e ADUL.

O comparador digital efetua uma comparação de 8 bits! Quando o conversor opera com resolução de 10 bits a comparação é efetuada apenas com os 8 bits superiores do resultado.

Quando o conversor opera em modo de 8 bits, o resultado da conversão pode ser lido no registrador de 8 bits ADCRH. Quando o conversor opera no modo de 10 bits, o resultado da conversão deve ser lido no registrador de 16 bits ADCR. Neste caso, o resultado é alinhado à esquerda e os 6 bits menos significativos são mantidos em zero (para obter o resultado real basta dividir o conteúdo do ADCR por 64).

O resultado da conversão poderá ser calculado através da seguinte equação (é considerada uma resolução de 10 bits, no caso de 8 bits, basta substituir o valor 1024 por 256 na equação):

+

−= 5,01024*

AVAV

AVVINTRESULTADO

REFMREFP

REFMAINBITS10

Onde: VAIN é a tensão analógica de entrada, AVREFP é a tensão de referência positiva e AVREFP é a tensão de referência negativa. INT consiste na função matemática que retorna a parte inteira do argumento (a parte fracionária é desprezada).

Periféricos Analógicos 183

A seleção da referência positiva do conversor é feita através dos bits ADREFP1 e ADREFP0 (registrador ADM2) conforme a tabela a seguir.

ADREFP1 ADREFP0 Referência Positiva Símbolo C (myRL78.h)

0 0 Alimentação positiva (VDD) ADC_REFP_VDD

0 1 Entrada ANI0 ADC_REFP_PIN

1 0 Referência interna de 1,45V ADC_REFP_INT

* o símbolo ADC_REFP_VDD pode ser omitido já que equivale ao valor 0.

Tabela 8.7

A tensão de referência positiva externa não pode ser inferior a 1,6V e nem superior a tensão de alimentação do chip (VDD)!

A seleção da tensão de referência negativa é feita por meio do bit ADREFM do registrador ADM2: quando ADREFM=0, a referência negativa é o pino VSS (0V) e quando ADREFM=1, a referência negativa é obtida por uma tensão analógica externa fornecida através da entrada ANI1. Lembre-se de que a referência negativa não pode ser menor que VSS.

Caso a interrupção do ADC esteja habilitada (ADMK = 0) e as interrupções globais estejam habilitadas (IE=1), o sinal de interrupção INTAD provocará o desvio do programa para o vetor de interrupção do ADC (INTAD_vect).

8.2. Modos de Operação

Neste tópico veremos os diversos modos de operação disponíveis no conversor A/D dos RL78.

O modo de operação está relacionado a três configurações básicas:

1. Conversão simples ou múltipla;

2. Conversão de um canal ou varredura de canais;

3. Tipo de disparo: por software e por hardware com ou sem atraso.

8.2.1. Conversão Simples ou Múltipla

Esta configuração de operação do A/D determina se após um disparo o conversor vai realizar uma única conversão (one-shot na terminologia do fabricante) ou iniciar conversões sucessivas.

Esta facilidade é controlada pelo bit ADSCM no registrador ADM1: quando ADSCM=1, ao receber um sinal de disparo o conversor realiza apenas uma conversão e após completada ele aguarda um novo disparo.

Quando ADSCM=0, ao receber um sinal de disparo o conversor inicia uma nova conversão e após ela ser completada outra conversão é automaticamente iniciada, neste caso ele permanecerá fazendo conversões indefinidamente até que o software determine a sua parada (escrevendo 0 no bit ADSC).

Microcontroladores RL78: Guia Básico 184

8.2.2. Conversão de Um Canal ou Varredura de Canais

O conversor A/D dos RL78 inclui a facilidade de efetuar a varredura automática de canais (scan na terminologia do fabricante), ou seja, o conversor efetua 4 conversões em sequência, iniciando do canal especificado pelo programador (através do registrador ADS) e continuando pelos 3 canais seguintes.

Desta forma, após um único sinal de disparo, o conversor irá realizar quatro conversões completas em quatro canais sequenciais. Caso o modo de múltiplas conversões esteja habilitado (ADSCM=0), após completar uma varredura dos quatro canais o conversor reiniciará um novo ciclo (com os mesmos quatro canais) e permanecerá repetindo a varredura até que seja desativado pelo software (pela escrita de 0 no bit ADSC).

Esta facilidade é configurada pelo bit ADMD no registrador ADM0: quando ADMD=0, o conversor A/D opera no modo de canal único, ou seja, após um disparo é feita uma conversão (ou sucessivas se o bit ADSCM=0) do canal selecionado pelo registrador ADS. Quando ADMD=1, o conversor opera no modo de varredura de canais.

Atenção: no modo de varredura não é permitido selecionar canais superiores ao décimo primeiro!

Como não há uma forma de identificar qual canal foi convertido num determinado instante, ao utilizar o modo de varredura é interessante configurar o bit ADRCK=0 (registrador ADM2), ADLL=0 e ADUL=0xFF, desta forma garante-se que todas as quatro conversões irão gerar interrupções, permitindo que o software possa rastreá-las corretamente!

8.2.3. Formas de Disparo do Conversor

Uma vez que o conversor esteja devidamente configurado e o canal a ser convertido tenha sido selecionado no registrador ADS, ele permanecerá em standby, aguardando um sinal de disparo para que a conversão seja efetivamente iniciada.

Como já foi dito anteriormente, uma conversão pode ser disparada de duas formas distintas: pelo software ou pelo hardware. Além disso, um disparo por hardware pode incluir ou não um tempo de atraso para estabilização do sinal.

A seleção do tipo de disparo é feita através dos bits ADTMD1 e ADTMD0 localizados no registrador ADM1. A tabela 8.8 mostra as configurações possíveis.

ADTMD1 ADTMD0 Fonte de Disparo Símbolo C (myRL78.h)

0 0 Software ADC_TRIG_SOFT

0 1 Software -

1 0 Hardware (sem atraso) ADC_TRIG_HARD_NO_WAIT

1 1 Hardware (com atraso) ADC_TRIG_HARD_WAIT

* o símbolo ADC_TRIG_SOFT pode ser omitido já que equivale ao valor 0.

Tabela 8.8

Atenção: é necessário aguardar um tempo de no mínimo 1µs entre a habilitação inicial do conversor (ADCE=1) e o disparo da conversão. Este tempo é necessário para a estabilização do circuito do conversor.

Periféricos Analógicos 185

8.2.3.1. Disparo por Software

Quando o conversor está configurado para disparo por software (bit ADTMD1=0 no registrador ADM1), uma nova conversão tem início sempre que o bit ADCS (registrador ADM0) é setado pelo programa.

Após setado o bit ADCS o conversor irá aguardar um tempo de atraso de 1 a 63 ciclos de clock fCLK. Este tempo é selecionado de acordo com a configuração dos bits FR2, FR1 e FR0 (registrador ADM0) conforme mostra a tabela 8.4. Nos modos de múltiplas conversões e de varredura, o tempo de atraso é utilizado somente na primeira conversão.

Completada a conversão, o bit ADCS é automaticamente apagado pelo hardware (exceto quando o modo de múltiplas conversões está selecionado, neste caso ADCS permanece setado).

Redisparar o conversor ou selecionar outro canal no registrador ADS enquanto uma conversão está em andamento, faz com que a conversão atual seja descartada e uma nova conversão seja iniciada!

8.2.3.2. Disparo por Hardware

É possível configurar o conversor para iniciar uma conversão após receber um sinal de disparo proveniente do hardware.

A seleção do módulo de hardware responsável por disparar o conversor é feita pelos bits ADTRS1 e ADTRS0 (registrador ADM1). A tabela 8.8 mostra as configurações possíveis.

ADTRS1 ADTRS0 Fonte de Disparo Símbolo C (myRL78.h) 0 0 Canal 1 da TAU0 ADC_TRIG_TAU

1 0 RTC ADC_TRIG_RTC 1 1 Timer de Intervalo (IT) ADC_TRIG_IT

* o símbolo ADC_TRIG_TAU pode ser omitido já que equivale ao valor 0.

Tabela 8.9

O disparo pela TAU pode ser utilizado para sincronizar as conversões A/D com a geração de sinais (PWM, por exemplo), ou para obter taxas taxas de amostragem específicas.

O RTC e o IT podem ser utilizados para disparar conversões quando o microcontrolador está em modo halt, stop ou snooze. Desta forma o sistema pode permanecer em modo de baixo consumo e ainda assim realizar conversões A/D periodicamente. Podemos citar como exemplo de aplicação a amostragem periódica de sensores em sistemas movidos à bateria.

O disparo por hardware pode incluir ou não um tempo de estabilização. O modo ADC_TRIG_HARD_WAIT inclui um tempo de estabilização de 2 ou 8 ciclos fAD antes do início da conversão.

No modo ADC_TRIG_HARD_NO_WAIT o conversor não utiliza tempo de estabilização, mas antes da conversão ele aguarda o tempo de atraso da mesma forma que no disparo por software. Este tempo é determinado pelos bits FR2, FR1 e FR0 (registrador ADM0) conforme mostra a tabela 8.4.

Microcontroladores RL78: Guia Básico 186

Os tempos de estabilização e de atraso são utilizados na primeira conversão após um sinal de disparo. Quando se utiliza o modo de varredura ou o modo de conversões múltiplas, estes tempos são utilizados apenas na primeira conversão, mas não nas posteriores.

8.3. Referência Interna de Tensão

Um dos canais do conversor A/D dos RL78 está conectado a uma referência interna de tensão com valor típico de saída de 1,45V.

Esta referência interna pode ser utilizada para calibrar o conversor e permite também a medição indireta da tensão de alimentação do chip.

A medição indireta do VDD é possível porque a conversão A/D depende da tensão de referência positiva e, quando utilizamos VDD como referência positiva, a conversão torna-se dependente da tensão de alimentação. Por exemplo, se considerarmos que a tensão de alimentação é igual a 5V teremos:

2975,01024*5

45,1INTRES INT_REF =

+=

Se a tensão VDD variar para 4,95V o resultado da conversão da tensão da referência interna será igual a:

3005,01024*95,4

45,1INTRES INT_REF =

+=

A fórmula a seguir mostra como calcular VDD a partir do valor medido para a referência interna de tensão.

RES

1024*45,1VDD =

Para selecionar a referência interna como o canal de entrada do conversor é necessário configurar o registrador ADS com o valor 0x81 (símbolo ADC_CH_REF no arquivo myRL78.c).

Após selecionar a referência interna como entrada do conversor, o resultado da primeira conversão deve ser descartado, apenas os resultados seguintes devem ser utilizados pela aplicação!

8.4. Sensor de Temperatura

Os microcontroladores RL78 incluem um sensor interno de temperatura que pode ser lido através do conversor A/D.

Este sensor apresenta uma tensão típica de 1,05V quando submetido a uma temperatura de 25oC, apresenta um coeficiente de temperatura de -3,6mV/oC e uma precisão de aproximadamente ±3oC quando calibrado.

Periféricos Analógicos 187

A tensão de saída (em Volts) para uma temperatura T pode ser calculada através da seguinte fórmula:

mV6,3*)25T(05,1VSENSOR −−+=

Isto significa que o sensor apresentará uma tensão de saída de 1,14V quando submetido a uma temperatura de 0oC e 780mV quando submetido a uma temperatura de 100oC.

Lembre-se de que os RL78 com faixa de temperatura comercial podem operar entre -40 e +85ºC ao passo que os modelos com faixa de temperatura industrial podem chegar a 105ºC!

A temperatura do sensor (em oC) pode ser calculada através da seguinte fórmula:

6864,3

2,1075V*64

ADCR

25aTemperaturDD −

−=

Para selecionar o sensor de temperatura como o canal de entrada do conversor é necessário configurar o registrador ADS com o valor 0x80 (símbolo ADC_CH_TEMP no arquivo myRL78.c).

Após selecionar o sensor de temperatura como entrada do conversor, o resultado da primeira conversão deve ser descartado, apenas os resultados seguintes devem ser utilizados pela aplicação!

8.5. Operação em Modo Snooze

O conversor A/D pode operar em modo snooze, realizando conversões periódicas enquanto a CPU e o restante do microcontrolador permanecem em modo stop.

Para isso, é necessário utilizar o disparo por hardware em modo de conversão simples (one-shot) e selecionar o RTC ou timer de intervalo como fonte do disparo. Lembre-se de que o periférico selecionado deverá estar configurado para operar no modo stop!

Também é necessário setar o bit AWC (registrador ADM2) para que o conversor possa operar em modo snooze.

Atenção: o bit AWC deve ser setado apenas antes da entrada no modo stop, esta operação deve ser feita com o conversor desabilitado (ADCE=0). Ao sair do modo stop e retornar ao modo run a aplicação deve apagar o bit AWC. Caso o bit AWC permaneça setado durante a operação normal do conversor, as conversões podem não ser iniciadas corretamente.

A operação neste modo requer também que o oscilador HOCO seja selecionado como fonte de clock da CPU e periféricos. O modo snooze não deve ser utilizado se outro oscilador estiver operando como fonte de clock para a CPU e periféricos.

Existem algumas vantagens na utilização do modo snooze na operação do conversor A/D, em especial podemos destacar a redução do consumo de energia e o aumento da precisão do conversor.

Microcontroladores RL78: Guia Básico 188

A redução de consumo ocorre porque, ao utilizar as facilidades do comparador digital, é possível programar o ADC para somente “acordar” a CPU quando a tensão medida ultrapasse um determinado limite especificado pelos registradores ADUL e ADLL. Neste caso, a interrupção do ADC pode ser utilizada para provocar a saída do modo snooze e o retorno ao modo ativo, permitindo que a aplicação faça o processamento do resultado da conversão.

O aumento da precisão decorre do fato de que quando o chip está em modo snooze, a grande maioria dos seus circuitos internos está parada, reduzindo o ruído elétrico dentro do chip. Esta redução de ruído permite obter leituras mais confiáveis.

8.6. Registradores do ADC Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita ADCS ADMD FR2 FR1 FR0 LV1 LV0 ADCE

ADM0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Bit C Símbolo C

ADCS

Controle de operação do conversor A/D: Numa operação de escrita: 0 – para a conversão 1 – habilita a conversão Numa operação de leitura: 0 – conversão parada 1 – conversão em andamento

ADCS bADCS

ADMD Modo de conversão: 0 – um canal 1 – sequência de canais

- bADMD

Seleção do clock do conversor e tempo de início de conversão (TIC):

000 – fCLK/64 – TIC = 63 fCLK - ADCLK_DIV64

001 – fCLK/32 – TIC = 31 fCLK - ADCLK_DIV32

010 – fCLK/16 – TIC = 15 fCLK - ADCLK_DIV16

011 – fCLK/8 – TIC = 7 fCLK - ADCLK_DIV8

100 – fCLK/6 – TIC = 5 fCLK - ADCLK_DIV6

101 – fCLK/5 – TIC = 4 fCLK - ADCLK_DIV5

110 – fCLK/4 – TIC = 3 fCLK - ADCLK_DIV4

FR2 FR1 FR0

111 – fCLK/2 – TIC = 1 fCLK - ADCLK_DIV2

LV1 LV0

Seleção do tempo de estabilização (vide tabelas 8.5 e 8.6) -

ADC_LV0 ADC_LV1 ADC_LV2 ADC_LV3

ADCE Controle do comparador de tensão do ADC: 0 – desativa o comparador analógico 1 – ativa o comparador analógico

ADCE bADCE

Periféricos Analógicos 189

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita ADTMD1 ADTMD0 ADSCM 0 0 0 ADTRS1 ADTRS0

ADM1

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C Seleção do modo de disparo do conversor A/D:

00, 01 – disparo por software (bit ADCS) ADC_TRIG_SOFT

10 – disparo por hardware (sem tempo de estabilização) ADC_TRIG_HARD_NO_WAIT

ADTMD1 ADTMD0

11 – disparo por hardware (com tempo de estabilização) ADC_TRIG_HARD_WAIT

ADSCM Modo de conversão: 0 – conversões sequenciais 1 – conversão única

bADSCM

Seleção da fonte de disparo por hardware:

00 – interrupção do canal 1 da TAU0 ADC_TRIG_TAU

10 – interrupção do RTC ADC_TRIG_RTC

ADTRS1 ADTRS0

11 – interrupção do timer de intervalo (IT) ADC_TRIG_IT

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita ADREFP1 ADREFP0 ADREFM 0 ADRCK AWC 0 ADTYP

ADM2

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C Seleção da referência positiva do conversor:

00 – VREF+ proveniente do VDD ADC_REFP_VDD

01 – VREF+ proveniente da entrada ANI0 ADC_REFP_PIN

ADREFP1 ADREFP0

10 – VREF+ proveniente da referência interna de 1,45V ADC_REFP_INT

ADREFM Seleção da referência negativa do conversor: 0 – pino VSS 1 – pino P21/ANI1 bADREFM

ADRCK

Checagem de limites do resultado da conversão: 0 – A interrupção INTAD é disparada quando o resultado da conversão está dentro da faixa entre ADLL e ADUL 1 – A interrupção INTAD é disparada quando o resultado da conversão é menor que ADLL ou maior que ADUL

bADRCK

AWC Habilitação de operação do conversor no modo snooze: 0 – ADC não opera no modo snooze 1 – ADC pode operar no modo snooze

ADC_SNOOZE_ENABLE

ADTYP Número de bits do resultado da conversão: 0 – 10 bits 1 – 8 bits

ADC_8BIT

Microcontroladores RL78: Guia Básico 190

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita ADISS 0 0 ADS4 ADS3 ADS2 ADS1 ADS0

ADS

Reset 0 0 0 0 0 0 0 0

Este registrador seleciona o canal a ser convertido no próximo disparo do conversor:

Canal selecionado Símbolo C Canal selecionado Símbolo C ANI0/P20 ADC_CH0 ANI14/P156 ADC_CH14

ANI1/P21 ADC_CH1 ANI16/P03 ADC_CH16

ANI2/P22 ADC_CH2 ANI17/P02 ADC_CH17

ANI3/P23 ADC_CH3 ANI18/P147 ADC_CH18

ANI4/P24 ADC_CH4 ANI19/P120 ADC_CH19

ANI5/P25 ADC_CH5 ANI20/P100 ADC_CH20

ANI6/P26 ADC_CH6 ANI21/P37 ADC_CH21

ANI7/P27 ADC_CH7 ANI22/P36 ADC_CH22

ANI8/P150 ADC_CH8 ANI23/P35 ADC_CH23

ANI9/P151 ADC_CH9 ANI24/P117 ADC_CH24

ANI10/P152 ADC_CH10 ANI25/P116 ADC_CH25

ANI11/P153 ADC_CH11 ANI26/P115 ADC_CH26

ANI12/P154 ADC_CH12 Sensor de temperatura ADC_CH_TEMP

ANI13/P155 ADC_CH13 Referência interna de 1,45V ADC_CH_REF

* Os canais 15 (0x0F) e 27 em diante (0x1B e acima) não são permitidos

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura Resultado da conversão 0 0 0 0 0 0

Escrita - ADCR

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Este registrador armazena o resultado da conversão (desde que ela esteja dentro da faixa programada nos registradores de comparação). Quando o conversor opera no modo de 8 bits (ADTYP = 1), o resultado da conversão pode ser lido no registrador ADCRH. Neste caso, a leitura do registrador ADCR irá retornar o resultado de 8 bits no byte superior, com os 8 bits inferiores mantidos em zero.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita Limiar superior do comparador digital

ADUL

Reset 1 1 1 1 1 1 1 1

Leitura

Escrita Limiar inferior do comparador digital

ADLL

Reset 0 0 0 0 0 0 0 0

Os registradores ADUL e ADLL armazenam os limiares de comparação do circuito comparador digital do conversor A/D. Quando ADRCK=0, a interrupção INTAD é disparada quando o resultado da conversão está dentro da faixa entre ADLL e ADUL (inclusive). Quando ADRCK=1, a interrupção INTAD é disparada quando o resultado da conversão é menor que ADLL ou maior que ADUL.

Periféricos Analógicos 191

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 0 ADTES1 ADTES0

ADTES

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C Modo de teste do conversor A/D:

00 – Teste desativado ADC_TEST_OFF

10 – Converte a entrada AVREFM ADC_TEST_REFM

ADTES1 ADTES0

11 – Converte a entrada AVREFP ADC_TEST_REFP

8.7. Exemplo

O exemplo a seguir demonstra a operação do conversor A/D do RL78/G13. O programa monitora a tensão do cursor do trimpot R15 da placa YRPBRL78G13, ligando o led quando o valor lido no ADC é maior que 511 (o equivalente a aproximadamente 2,5V). #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED P7_bit.no7

#pragma vector = INTAD_vect

__interrupt void trata_ADC(void)

unsigned int result;

result = ADCR >> 6; // lê o resultado da conversão

if (result>511) LED = 0; else LED = 1;

void main(void)

PM7_bit.no7 = 0; // pino P77 como saída

LED = 0; // apaga o led

Microcontroladores RL78: Guia Básico 192

ADPC = 4; // pinos P20, P21 e P22 no modo analógico

ADCEN = 1; // habilita o ADC

// Configura o ADC (conversões múltiplas, um canal, disparo por software)

ADM0 = ADCLK_DIV64 | ADC_LV0 | bADCE;

ADM1 = ADC_TRIG_SOFT;

ADS = ADC_CH2; // seleciona o canal 2

ADMK = 0; // habilita interrupção do ADC

__enable_interrupt(); // habilita as interrupções do RL78

ADCS = 1; // inicia uma conversão

while (1);

Exemplo 8.1

8.8. Outros Periféricos Disponíveis

Algumas linhas de RL78 possuem outros periféricos analógicos que substituem ou coexistem com o conversor A/D de 10 bits apresentado neste capítulo. A seguir mostramos alguns destes periféricos.

8.8.1. Comparador Analógico

Os microcontroladores da linha G14 incluem dois comparadores analógicos que podem ser utilizados para comparar tensões analógicas externas ou fazer comparação de tensões externas com a referência interna de 1,45V. Estes comparadores possuem também filtros digitais em suas saídas, que podem ser utilizados para reduzir ruídos de saída. O sinal de saída dos comparadores pode ser disponibilizado em pinos de E/S, pode gerar interrupção e também alimentar o módulo ELC (Event Link Controller).

8.8.2. Conversor A/D de 12 bits

Os microcontroladores RL78/G1A possuem um conversor A/D de 12 bits ao invés do conversor de 10 bits mostrado neste capítulo, mas que opera de forma muito similar ao mostrado neste livro. As diferenças básicas residem no fato de que o bit ADTYP (registrador ADM2) seleciona entre o modo de 12 bits (ADTYP=0) e o modo de 8 bits (ADTYP=1). Além disso, o registrador de resultado da conversão (ADCR) é alinhado à direita ao invés da esquerda como mostrado neste livro. Para maiores detalhes, consulte o manual de hardware desta linha de chips.

8.8.3. Conversor D/A

Alguns modelos da linha G14 incluem um ou dois módulos conversores digital para analógico (DAC) de 8 bits. Estes conversores podem ser utilizados para gerar tensões analógicas sob o controle do microcontrolador.

Periféricos de Comunicação 193

9

Periféricos de Comunicação 9. Periféricos de Comunicação

Neste capítulo apresentamos as interfaces de comunicação disponíveis nos microcontroladores RL78/G13 e em outras linhas da família RL78.

Além dos periféricos descritos neste capítulo, a linha RL78/G1C inclui também interface USB 2.0 capaz de operar em modo full speed (12Mbps) e low speed (1,5Mbps).

9.1. Unidades SAU

Uma unidade SAU (Serial Array Unit – unidade conjunta serial) é o elemento básico de comunicação serial dos RL78.

Cada unidade SAU pode conter até quatro canais seriais e podem existir até duas unidades SAU num mesmo microcontrolador.

Um canal da SAU é composto por um registrador de deslocamento responsável pela conversão serial/paralelo e outros circuitos adjacentes.

Cada canal pode operar em três modos distintos:

• CSI – modo de comunicação síncrono similar ao SPI 3 fios e utilizado para comunicação de alta velocidade com memórias seriais (normalmente flash e EEPROM), conversores A/D, cartões de memória MMC, SD e SDIO e outros dispositivos. Cada canal pode ser configurado para transmitir 7 ou 8 bits de dados, com palavras iniciando pelo MSB ou pelo LSB, com controle de fase do clock e de polaridade do clock e dos dados. Neste modo cada canal da SAU utiliza três pinos: SOxx para saída de dados seriais, SIxx para entrada de dados seriais e SCKxx para entrada de clock (modo escravo) ou saída de clock (modo mestre);

• I2C simplificado – modo I2C mestre com algumas limitações (não há suporte a múltiplos mestres, nem a arbitragem de barramento e nem solicitação de espera pelo escravo). Este modo pode ser utilizado para comunicação com virtualmente qualquer dispositivo I2C, como por exemplo: RTCs, memórias EEPROM, flash e RAM seriais, conversores A/D e D/A, etc. Cada canal pode ser configurado para transmissão ou recepção em modo mestre, o hardware inclui controle para geração e detecção do bit de reconhecimento (ACK), mas a geração das condições de partida e de parada deve ser providenciada pela aplicação;

• UART – modo de comunicação assíncrona, disponível apenas nos canais 0 e 2 das unidades SAU. Pode operar com 7, 8 ou 9 bits e inclui gerador/detector de paridade,

Microcontroladores RL78: Guia Básico 194

inversão de polaridade dos dados e detecção de erros (paridade, quadro e de sobrescrita). O modo UART utiliza dois canais da SAU, assim, quando o canal 0 opera como UART o canal 1 fica indisponível e quando o canal 2 opera como UART o canal 3 fica indisponível da mesma forma. Adicionalmente, a UART2 pode operar em modo LIN e conjunto com a TAU e a interrupção externa INTP0.

Isto significa que nos modelos com 80, 100 e 128 pinos é possível dispor de até 8 canais CSI (SPI), ou 8 canais I2C simplificado ou até 4 canais UART.

A tabela a seguir mostra a disponibilidade de canais das unidades SAU nos diversos modelos de encapsulamentos encontrados na linha RL78/G13.

SAU Disponibilidade de Canais SAU

(número de pinos do encapsulamento)

Unidade Canal 128,100,80 64 52,48 44,40,36 32,30 25,24,20

0

CSI00

IIC00

UART0

CSI00

IIC00

UART0

CSI00

IIC00

UART0

CSI00

IIC00

UART0

CSI00

IIC00

UART0

CSI00

IIC00

UART0

1 CSI01

IIC01

CSI01

IIC01

CSI01

IIC01 - - -

2

CSI10

IIC10

UART1

CSI10

IIC10

UART1 UART1 UART1 UART1 UART1

0

3 CSI11

IIC11

CSI11

IIC11

CSI11

IIC11

CSI11

IIC11

CSI11

IIC11

CSI11

IIC11

0

CSI20

IIC20

UART2

CSI20

IIC20

UART2

CSI20

IIC20

UART2

CSI20

IIC20

UART2

CSI20

IIC20

UART2 -

1 CSI21

IIC21

CSI21

IIC21

CSI21

IIC21

CSI21

IIC21 - -

2

CSI30

IIC30

UART3 - - - - -

1

3 CSI31

IIC31 - - - - -

Tabela 9.1

A tabela a seguir mostra as funções dos canais SAU e os pinos de E/S associados a elas.

Encapsulamento (pinos) Função

128 100 80 64 52,48 44,40,36 32,30 25,24 20

SI00/SDA00/RxD0 P11/P16 P11/P16 P11/P16 P11/P16 P11/P16 P11/P16 P11/P16 P11 P11

SO00/TxD0 P12/P17 P12/P17 P12/P17 P12/P17 P12/P17 P12/P17 P12/P17 P12 P12

SCK00/SCL00 P10/P55 P10/P55 P10 P10 P10 P10 P10 P10 P10

SI01/SDA01 P44 P44 P44 P74 P74 - - - -

SO01 P45 P45 P45 P73 P73 - - - -

SCK01/SCL01 P43 P43 P43 P75 P75 - - - -

SI10/SDA10/RxD1 P03/P81 P03/P81 P03 P03 P01 P01 P01 P01 P01

Periféricos de Comunicação 195

Encapsulamento (pinos) Função

128 100 80 64 52,48 44,40,36 32,30 25,24 20

SO10/TxD1 P02/P82 P02/P82 P02 P02 P00 P00 P00 P00 P00

SCK10/SCL10 P04/P80 P04/P80 P04 P04 - - - - -

SI11/SDA11 P50 P50 P50 P50 P50 P50 P50 P50 P17

SO11 P51 P51 P51 P51 P51 P51 P51 P17 P16

SCK11/SCL11 P30 P30 P30 P30 P30 P30 P30 P30 P30

SI20/SDA20/RxD2 P14/P76 P14/P76 P14/P76 P14 P14 P14 P14 - -

SO20/TxD2 P13/P77 P13/P77 P13/P77 P13 P13 P13 P13 - -

SCK20/SCL20 P15 P15 P15 P15 P15 P15 P15 - -

SI21/SDA21 P71 P71 P71 P71 P71 P71 - - -

SO21 P72 P72 P72 P72 P72 P72 - - -

SCK21/SCL21 P70 P70 P70 P70 P70 P70 - - -

SI30/SDA30/RxD3 P143 P143 P143 - - - - - -

SO30/TxD3 P144 P144 P144 - - - - - -

SCK30/SCL30 P142 P142 P142 - - - - - -

SI31/SDA31 P53 P53 P53 - - - - - -

SO31 P52 P52 P52 - - - - - -

SCK31/SCL31 P54 P54 P54 - - - - - -

Tabela 9.2

Adicionalmente, o canal 0 (e o canal 2 nos modelos com 64 pinos ou mais) de cada unidade SAU pode continuar operando em modo snooze (quando operando no modo CSI ou UART), permitindo que o microcontrolador receba dados seriais enquanto permanece em modo de baixo consumo de energia.

Funcionalmente uma unidade SAU apresenta muitas similaridades em relação a TAU, os registradores possuem formato parecido, com um controle geral de divisor de clock (registrador SPSm), registradores de configuração independentes para cada canal (SMRmn e SCRmn), registradores de disparo (SSm), de parada (STm) e de indicação de habilitação (SEm). Também estão presentes registradores para o controle dos pinos de saída dos canais (SOEm, SOm e SOLm), além dos registradores ISC (para utilização de LIN) e NFEN0 (para ativação dos filtros digitais nas entradas dos canais da SAU).

As unidades SAU também incluem registradores de status para indicação de erros (SSRmn) e para o apagamento dos indicadores de erro (SIRmn).

Os dados transmitidos/recebidos são controlados através do registrador SDRmn. Este registrador também controla (através dos seus 7 bits mais significativos) o fator de divisão final que determina o baud rate da comunicação (neste livro chamaremos este fator de FDC).

A seguir veremos os registradores relacionados às unidades SAU e nos tópicos seguintes estudaremos cada um dos três modos de operação dos seus canais.

Microcontroladores RL78: Guia Básico 196

9.1.1. Registradores das SAU

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0 PRS

m13 PRSm12

PRSm11

PRSm10

PRSm03

PRSm02

PRSm01

PRSm00 SPSm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da unidade SAU (0 ou 1) * Os 8 bits menos significativos podem ser acessados através do registrador SPSmL

Nome do Bit Descrição Símbolo C Seleção do divisor do CK0 e CK1 da SAU:

0000 - fclk (nenhuma divisão) SAU_CKx_DIV1

0001 - fclk dividido por 2 SAU_CKx_DIV2

0010 - fclk dividido por 4 SAU_CKx_DIV4

0011 - fclk dividido por 8 SAU_CKx_DIV8

0100 - fclk dividido por 16 SAU_CKx_DIV16

0101 - fclk dividido por 32 SAU_CKx_DIV32

0110 - fclk dividido por 64 SAU_CKx_DIV64

0111 - fclk dividido por 128 SAU_CKx_DIV128

1000 - fclk dividido por 256 SAU_CKx_DIV256

1001 - fclk dividido por 512 SAU_CKx_DIV512

1010 - fclk dividido por 1024 SAU_CKx_DIV1024

1011 - fclk dividido por 2048 SAU_CKx_DIV2048

1100 - fclk dividido por 4096 SAU_CKx_DIV4096

1101 - fclk dividido por 8192 SAU_CKx_DIV8192

1110 - fclk dividido por 16384 SAU_CKx_DIV16384

PRSm13 PRSm12 PRSm11 PRSm10 PRSm03 PRSm02 PRSm01 PRSm00

1111 - fclk dividido por 32768 SAU_CKx_DIV32768

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita

CKS mn

CCS mn

0 0 0 0 0 STS mn

0 SIS mn0

1 0 0 MD mn2

MD mn1

MD mn0 SMRmn

Reset 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1) , n corresponde ao número do canal da SAU (0 a 3)

Nome do Bit Descrição Símbolo C

CKSmn Seleção do prescaler associado ao canal SAU (CK0 ou CK1): 0 – seleciona o prescaler 0 da SAU 1 – seleciona o prescaler 1 da SAU

bSAU_CKS

CCSmn Seleção da fonte de clock do canal: 0 – clock interno fCLK (utiliza o fator FDC do SDRmn) 1 – clock externo via pino SCK do canal

SAU_CLK_EXT

STSmn Seleção da fonte de disparo de partida: 0 – software (para modo CSI, I2C simplificado ou transmissão UART) 1 – borda válida no pino RxD do canal (para o modo de recepção UART)

bSAU_STS

Periféricos de Comunicação 197

Nome do Bit Descrição Símbolo C

SISmn0 Controle de inversão da linha de recepção da UART: 0 – bit de partida detectado na borda de descida, recepção normal 1 – bit de partida detectado na borda de subida, recepção invertida

SAU_RX_INV

Seleção do modo de operação do canal SAU:

00 – modo CSI SAU_MD_CSI

01 – modo UART SAU_MD_UART

MDmn2 MDmn1

10 – modo I2C simplificado SAU_MD_I2C

MDmn0 Seleção do modo de interrupção do canal SAU: 0 – interrupção ao final da transferência 1 – interrupção no esvaziamento do buffer

SAU_INT_BUFFER

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita

TXE mn

RXE mn

DAP mn

CKP mn

0 EOC mn

PTCmn1

PTCmn0

DIR mn

0 SLCmn1

SLCmn0

0 1 DLSmn1

DLSmn0 SCRmn

Reset 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1

*m corresponde ao número da SAU (0 ou 1) , n corresponde ao número do canal da SAU (0 a 3)

Nome do Bit Descrição Símbolo C Configuração do modo de operação do canal n:

00 – comunicação desabilitada SAU_COMM_DISABLE

01 – somente recepção SAU_COMM_RX

10 – somente transmissão SAU_COMM_TX

TXEmn RXEmn

11 – transmissão e recepção SAU_COMM_TXRX

Seleção da polaridade do clock e fase do sinal em modo CSI (nos modos UART e I2C estes bits devem ser configurados para 0):

00 – clock ativo em nível baixo, dado amostrado na borda de subida do clock

SAU_CSI_CLKMODE0

01 – clock ativo em nível alto, dado amostrado na borda de descida do clock

SAU_CSI_CLKMODE1

10 – clock ativo em nível baixo, dado amostrado na borda de descida do clock

SAU_CSI_CLKMODE2

DAPmn CKPmn

11 – clock ativo em nível alto, dado amostrado na borda de subida do clock SAU_CSI_CLKMODE3

EOCmn

Habilitação da interrupção de erro INTSRE (válido apenas no modo UART): 0 – interrupção de erro desabilitada 1 – interrupção de erro habilitada

SAU_INTSRE_ENABLE

Seleção da paridade no modo UART:

00 – paridade desativada SAU_NO_PARITY

01 – paridade mantida sempre em zero SAU_PARITY_ZERO

10 – paridade par SAU_PARITY_EVEN

PTCmn1 PTCmn0

11 – paridade ímpar SAU_PARITY_ODD

Microcontroladores RL78: Guia Básico 198

Nome do Bit Descrição Símbolo C

DIRmn Ordem de transferência dos dados no modo CSI e UART: 0 – comunicação inicia pelo bit MSB 1 – comunicação inicia pelo bit LSB

SAU_LSB_FIRST

Número de bits de parada no modo UART:

00 – nenhum bit de parada (somente modo CSI) SAU_NO_STOP

01 – um bit de parada SAU_ONE_STOP

SLCmn1 SLCmn0

10 – dois bits de parada (apenas canal 0 e 2) SAU_TWO_STOP

Seleção do tamanho da palavra no modo CSI e UART:

01 – 9 bits (somente modo UART) SAU_9BITS

10 – 7 bits SAU_7BITS

DLSmn1 DLSmn0

11 – 8 bits SAU_8BITS

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura Dado recebido (7, 8 ou 9 bits)

Escrita FDC

Dado a ser transmitido (7, 8 ou 9 bits) SDRmn

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1) , n corresponde ao número do canal da SAU (0 a 3)

O campo FDC (fator de divisão do clock) determina o baud rate da comunicação. O baud rate é igual a fMCLK/fCK/(FDC*2+2) (pode ir de 2 até 256).

O campo FDC somente pode ser lido ou escrito no registrador SDR quando o canal da SAU está parado (bit SEmn = 0). Quando o canal está em operação normal (SEmn=1), um dado escrito no SDR altera somente os bits 0 a 8 e a leitura do SDR retorna os o campo FDC (bits 9 a 15) em zero.

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0 0 0 0 0 0

FECTmn

PECTmn

OVCTmn SIRmn

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1) , n corresponde ao número do canal da SAU (0 a 3)

* os 8 bits inferiores podem ser acessados através do registrador SIRmnL

Nome do Bit Descrição Símbolo C

FECTmn Apagamento do flag de erro de quadro: 0 – não apaga o flag 1 – apaga o flag FEFmn no registrador SSRmn

bFECT

PECTmn Apagamento do flag de erro de paridade: 0 – não apaga o flag 1 – apaga o flag PEFmn no registrador SSRmn

bPECT

OVCTmn Apagamento do flag de erro de sobrescrita: 0 – não apaga o flag 1 – apaga o flag OVFmn no registrador SSRmn

bOVCT

Periféricos de Comunicação 199

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura 0 0 0 0 0 0 0 0 0 TSF mn

BFFmn

0 0 FEF mn

PEF mn

OVFmn

Escrita - - - - - - - - - - - - - - - - SSRmn

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1) , n corresponde ao número do canal da SAU (0 a 3)

* os 8 bits inferiores podem ser acessados através do registrador SSRmnL

Nome do Bit Descrição Símbolo C

TSFmn Indicador de estado de comunicação do canal: 0 – comunicação parada ou suspensa 1 – comunicação em andamento

bTSF

BFFmn Indicador de estado do buffer do canal: 0 – não há dado válido no SDRmn 1 – há um dado válido no SDRmn

bBFF

FEFmn

Indicador de erro de quadro: 0 – nenhum erro 1 – erro de quadro detectado (no modo UART, indica falha na detecção do bit de parada)

bFEF

PEFmn

Indicador de erro de paridade ou NACK: 0 – nenhum erro 1 – erro de paridade detectado (modo UART) ou NACK recebido do escravo (modo I2C)

bPEF

OVFmn

Indicador de erro de sobrescrita: 0 – nenhum erro 1 – um novo dado foi recebido antes de o anterior ser lido no SDRmn

bOVF

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Escrita 0 0 0 0 0 0 0 0 0 0 0 0 SSm3 SSm2 SSm1 SSm0 SSm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1)

* os 8 bits inferiores podem ser acessados através do registrador SSmL

Nome do Bit Descrição Símbolo C SSm3 SSm2 SSm1 SSm0

Inicia a operação do canal (o canal da SAU passa a aguardar o início da comunicação e o bit SEmn correspondente é setado)

SAU_CH3 SAU_CH2 SAU_CH1 SAU_CH0

Microcontroladores RL78: Guia Básico 200

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Escrita 0 0 0 0 0 0 0 0 0 0 0 0 STm3 STm2 STm1 STm0 STm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1)

* os 8 bits inferiores podem ser acessados através do registrador STmL

Nome do Bit Descrição Símbolo C STm3 STm2 STm1 STm0

Para a operação do canal (a comunicação é encerrada e o bit SEmn correspondente é apagado)

SAU_CH3 SAU_CH2 SAU_CH1 SAU_CH0

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura 0 0 0 0 0 0 0 0 0 0 0 0 SEm3 SEm2 SEm1 SEm0

Escrita - SEm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1)

* os 8 bits inferiores podem ser acessados através do registrador SEmL

Nome do Bit Descrição Símbolo C SEm3 SEm2 SEm1 SEm0

Indicador de estado de operação do canal da SAU: 0 – operação paralisada 1 – operação normal

SAU_CH3 SAU_CH2 SAU_CH1 SAU_CH0

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0 0 0 0 0

SOEm3

SOE m2

SOE m1

SOE m0 SOEm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1) * os 8 bits inferiores podem ser acessados através do registrador SOEmL

* Só é permitido alterar este registrador com o canal paralisado (SEmn=0)

Nome do Bit Descrição Símbolo C SOEm3 SOEm2 SOEm1 SOEm0

Habilitação da saída do canal n: 0 – saída desativada 1 – saída ativada

SAU_CH3 SAU_CH2 SAU_CH1 SAU_CH0

Periféricos de Comunicação 201

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0

CKOm3

CKOm2

CKOm1

CKOm0

0 0 0 0 SO m3

SO m2

SO m1

SO m0 SOm

Reset 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1

*m corresponde ao número da SAU (0 ou 1) * os 8 bits inferiores podem ser acessados através do registrador SOmL

* somente é permitido alterar os bits CKO e SO quando a saída do canal está desativada (registrador SOEm)

Nome do Bit Descrição Símbolo C CKOm3 CKOm2 CKOm1 CKOm0

Estado da saída de clock do canal n: 0 – linha de clock em “0” 1 – linha de clock em “1”

SAU_CKO3 SAU_CKO2 SAU_CKO1 SAU_CKO0

SOm3 SOm2 SOm1 SOm0

Estado da saída de dados do canal n: 0 – saída desativada 1 – saída ativada

SAU_CH3 SAU_CH2 SAU_CH1 SAU_CH0

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0 0 0 0 0 0

SOL m2

0 SOL m0 SOLm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1)

* os 8 bits inferiores podem ser acessados através do registrador SOLmL

Nome do Bit Descrição Símbolo C

SOLm2 SOLm0

Inversão do sinal transmitido do canal n: 0 – sinal não invertido 1 – sinal invertido

SAU_CH2 SAU_CH0

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 0 0 0 0 0 0 0 0

SSECm

SWCm SSCm

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*m corresponde ao número da SAU (0 ou 1)

* os 8 bits inferiores podem ser acessados através do registrador SSCmL

Nome do Bit Descrição Símbolo C

SSECm Mascaramento da interrupção de erro INTSRE no modo snooze: 0 – interrupção habilitada 1 – interrupção desabilitada

bSSEC

SWCm Controle do modo snooze: 0 – desativado 1 – ativado

bSWC

Microcontroladores RL78: Guia Básico 202

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 0 ISC1 ISC0

ISC

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

ISC1

Seleção da entrada do canal 7 da TAU0 (apenas nos modelos com 30 pinos ou mais): 0 – entrada via pino TI07 1 – entrada do canal conectada ao RxD2 (para operação LIN)

bISC1

ISC0 Seleção da entrada de interrupção externa INTP0: 0 – sinal de interrupção derivado do pino INTP0 1 – sinal de interrupção derivado de RxD2 (para operação LIN)

bISC0

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 SNFEN30 0 SNFEN20 0 SNFEN10 0 SNFEN00

NFEN0

Reset 0 0 0 0 0 0 0 0

Estes registradores permitem ativar os filtros de ruído existentes nas entradas dos canais das unidades SAU. Quando ativados (SNFENxx = 1), o sinal RxD do respectivo canal precisa estar estável por dois ciclos fCLK para que ele seja detectado pelo timer.

Nome do Bit Descrição Símbolo C

SNFEN30 Controle do filtro de ruído do pino RxD3/SDA30/SI30/P143: 0 – filtro desligado 1 – filtro ligado bSNFEN30

SNFEN20 Controle do filtro de ruído do pino RxD2/SDA20/SI20/P14: 0 – filtro desligado 1 – filtro ligado

bSNFEN20

SNFEN10 Controle do filtro de ruído do pino RxD1/ANI16/SI10/SDA10/P03: 0 – filtro desligado 1 – filtro ligado

bSNFEN10

SNFEN00 Controle do filtro de ruído do pino RxD0/TOOLRxD/SDA00/SI00/ P11: 0 – filtro desligado 1 – filtro ligado

bSNFEN00

Nome Bits 7 6 5 4 3 2 1 0

Leitura

Escrita RTCEN IICA1EN ADCEN IICA0EN SAU1EN SAU0EN TAU1EN TAU0EN

PER0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Bit C Símbolo C

SAU1EN Controle de clock e operação da SAU1: 0 – SAU1 desativada 1 – SAU1 ativada

SAU1EN bSAU1EN

SAU0EN Controle de clock e operação da SAU0: 0 – SAU0 desativada 1 – SAU0 ativada SAU0EN bSAU0EN

Periféricos de Comunicação 203

9.1.2. Modo UART

O modo UART permite implementar comunicação serial assíncrona, sendo muito utilizado na comunicação com computadores e outros dispositivos.

Por ser um modo assíncrono, não há um sinal de clock comum para sincronizar os dados entre o transmissor e o receptor, ao invés disso, utiliza-se uma frequência conhecida para se efetuar o deslocamento dos dados através do registrador de deslocamento de transmissão/recepção (baud rate).

A sincronização entre transmissor e receptor é garantida pela utilização de uma sinalização específica para marcar o início e o fim de uma transmissão (bits de partida e de parada). A figura 9.1 mostra um típico quadro serial assíncrono. Chamamos quadro pois ele contém a informação mais os bits de controle (partida e parada).

Partida D0 D1 D2 D3 D4 D5 D6 D7* D8* Parada

Figura 9.1

É fácil perceber que o receptor detecta o início de uma transmissão quando ocorre uma borda de descida no sinal (início do bit de partida). Após a partida, os dados são lidos e amostrados pelo registrador de deslocamento utilizando uma frequência (baud rate) conhecida pelo transmissor e pelo receptor. Após os bits de dados, o bit de parada serve exclusivamente para fazer com que a linha de comunicação retorne ao seu estado inativo, de forma que um novo bit de partida possa ser detectado.

Quando operando no modo UART é possível configurar a polaridade do sinal serial, a ordem de deslocamento (início pelo bit menos significativo ou pelo bit mais significativo), o número de bits de dados transmitido em cada quadro (7, 8 ou 9) e o número de bits de parada (1 ou 2). Também é possível adicionar um bit de paridade (par, ímpar ou sempre zero), de forma que se efetue um controle básico de erros (feito automaticamente pelo hardware quando a paridade é utilizada).

A seleção do modo UART é feita pela configuração dos bits MD2=0 e MD1=1 (símbolo SAU_MD_UART no arquivo myRL78.h) no registrador de controle de modo do canal (SMRmn). O bit MD0 permite configurar o evento que gera uma interrupção conforme mostra a tabela 9.3.

MD0 Canal Descrição do Evento de Interrupção

0 Recepção Um caractere foi recebido, a aplicação deve fazer a leitura do mesmo no registrador RXDu

0 Transmissão Um caractere foi transmitido, para outra transmissão a aplicação deve escrever no novo dado no registrador TXDu

1 Recepção O buffer de recepção está cheio, a aplicação deve ler os dados no registrador RXDu até que o indicador de buffer cheio seja apagado (bit BFF no registrador SSRmn)

1 Transmissão O buffer de transmissão está vazio, a aplicação deve escrever novos dados no registrador TXDu até que o indicador de buffer cheio seja setado (bit BFF no registrador SSRmn)

Tabela 9.3

É importante destacar que para a operação da UART no modo full duplex (transmissão e recepção simultâneas) é necessário configurar um dos canais como transmissor (bit TXE = 1 no

Microcontroladores RL78: Guia Básico 204

registrador SCRmn) e o outro como receptor (bit RXE = 1 no registrador SCRmn). No modo UART, é possível utilizar os símbolos TXDu e RXDu para acessar a parte menos significativa do SDRmn, assim, utiliza-se o registrador TXDu para envio de dados pela UART “u” e o registrador RXDu para leitura dos dados recebidos pela UART “u”. A tabela a seguir mostra a organização e configuração dos canais UART nas SAU dos RL78/G13.

SAU Canal UART Modo STSmn*1 TXE*2 RXE*2 Registrador de Dados

0 TX 0 1 0 TXD0

1 0

RX 1 0 1 RXD0

2 TX 0 1 0 TXD1 0

3 1

RX 1 0 1 RXD1

0 TX 0 1 0 TXD2

1 2

RX 1 0 1 RXD2

2 TX 0 1 0 TXD3 1

3 3

RX 1 0 1 RXD3 *1 Registrador SMRmn *2 Registrador SCRmn

Tabela 9.4

A configuração dos canais da SAU deve seguir os seguintes passos:

1. Habilitação da SAU (registrador PER0);

2. Configuração dos divisores de clock da SAU (registrador SPSm);

3. Configuração dos canais conforme a UART a ser utilizada;

No modo UART, os canais da SAU devem operar sempre com clock interno, além disso, não é permitido configurar a UART para operar sem bits de parada. Os bits DAPmn e CKPmn não possuem função no modo UART e devem ser mantidos em zero.

4. Configuração do baud rate do transmissor e do receptor no campo FDC dos registradores SDRmn (é possível ter baud rates diferentes para o transmissor e para o receptor). A configuração do baud rate será vista em detalhes no próximo tópico;

5. Configuração dos registradores de controle de E/S da SAU (SOm, SOLm e SOEm) conforme modo de operação desejado. Normalmente é necessário apenas ativar a saída (pino TxD) do canal no registrador SOEm e configurar o estado da saída no registrador SOm. A inversão de dados (registrador SOLm) é usada apenas em algumas aplicações específicas;

6. Ativar o filtro digital de ruído na entrada RxD correspondente (registrador NFEN0);

7. Habilitar as interrupções utilizadas INTSTn para transmissão, INTSRn para recepção e INTSREn para erros de recepção);

8. Disparar os canais para dar início ao processo de comunicação (registrador SSm).

Feito isso, uma escrita no registrador TXDu provoca o início de uma transmissão e os dados recebidos pelo receptor são armazenados no registrador RXDu.

Periféricos de Comunicação 205

A transmissão de dados irá gerar um evento de interrupção de transmissão, setando o flag STIFx. Caso a interrupção de transmissão esteja habilitada (STMKx=0) o programa será desviado para o vetor (INTSTx_vect (x corresponde ao número da UART).

A recepção de dados irá gerar um evento de interrupção de recepção, setando o flag SRIFx. Caso a interrupção de recepção esteja habilitada (SRMKx=0) o programa será desviado para o vetor INTSRx_vect (x corresponde ao número da UART).

Observe que o evento gerador da interrupção de transmissão e da interrupção de recepção será aquele determinado pelo configuração do bit MD0 no registrador de configuração do canal SMRmn.

Adicionalmente, cada canal da SAU possui um registrador de status (SSRmn) que abriga alguns bits sinalizadores da operação do canal. O bit TSFmn indica se há comunicação em andamento no canal (transmissão ou recepção, conforme a configuração do canal), BFFmn indica se há um dado válido armazenado no buffer SDRmn (TXDu/RXDu) e os bits FEFmn, PEFmn e OVFmn indicam condições de erro conforme abaixo:

• FEFmn – erro de quadro. Este bit é setado quando a UART (modo de recepção) não detecta corretamente o bit de parada;

• PEFmn – erro de paridade. Quando a paridade está configurada, este bit é setado pelo hardware quando o dado recebido possui paridade diferente da calculada;

• OVFmn – erro de sobrescrita. Este erro ocorre quando o dado presente no buffer do canal (SDRmn) é sobrescrito por um novo dado;

Lembre-se de que os bits indicadores de erros são atualizados a cada novo caractere recebido. Estes bits podem ser apagados através do registrador SIRmn. No caso dos erros de quadro e de paridade, o caractere lido do registrador RXDu deve ser descartado.

No caso da ocorrência de um dos três erros citados o flag de erro SREIFx será setado e caso a interrupção de erro de recepção da UART esteja habilitada (EOC=1 no registrador SCRmn e a máscara SREMKx correspondente a UART esteja em zero), o programa será desviado para o vetor de interrupção INTSREx_vect (x corresponde ao número da UART).

9.1.2.1. Configuração do Baud Rate

A configuração da velocidade de comunicação dos canais da UART é realizada através de três registradores: SPSm e os registradores SDRmn relativos aos canais de transmissão e de recepção.

O baud rate final pode ser calculado através da seguinte fórmula:

22*FDCCKx

f

Baudrate

MCLK

+=

Onde:

Baudrate é a velocidade em bits por segundo (bps);

Microcontroladores RL78: Guia Básico 206

CKx é o fator de divisão do prescaler da SAU (CK0 ou CK1) configurado no registrador SPSm;

FDC é o valor configurado no campo FDC do registrador SDRmn.

As tabelas 9.4 e 9.5 mostram as configurações ideais para os divisores de clock CK0 e CK1 (registrador SPSm) e o fator de divisão FDC para diversas frequências de clock e baud rates comumente utilizados.

32MHz 24MHz

Baud rate CKx FDC Baud rate real Erro CKx FDC Baud rate real Erro 300 512 103 300,48 0,16% 512 77 300,48 0,16% 600 512 51 600,96 0,16% 512 38 600,96 0,16%

1200 512 25 1201,92 0,16% 128 77 1201,92 0,16% 2400 512 12 2403,85 0,16% 128 38 2403,85 0,16% 4800 32 103 4807,69 0,16% 32 77 4807,69 0,16% 9600 32 51 9615,38 0,16% 32 38 9615,38 0,16%

19200 32 25 19230,77 0,16% 8 77 19230,77 0,16% 38400 32 12 38461,54 0,16% 8 38 38461,54 0,16% 57600 4 68 57971,01 0,64% 8 25 57692,31 0,16% 115200 2 68 115942,03 0,64% 8 12 115384,62 0,16% Mínimo 32768 127 3,81 - 32768 127 2,86 - Máximo 4 0 4M - 4 0 3M -

20MHz 16MHz

Baud rate CKx FDC Baud rate real Erro CKx FDC Baud rate real Erro

300 512 64 300,48 0,16% 256 103 300,48 0,16% 600 256 64 600,96 0,16% 256 51 600,96 0,16%

1200 128 64 1201,92 0,16% 256 25 1201,92 0,16% 2400 64 64 2403,85 0,16% 256 12 2403,85 0,16% 4800 32 64 4807,69 0,16% 16 103 4807,69 0,16% 9600 16 64 9615,38 0,16% 16 51 9615,38 0,16%

19200 8 64 19230,77 0,16% 16 25 19230,77 0,16% 38400 4 64 38461,54 0,16% 16 12 38461,54 0,16% 57600 2 85 58139,53 0,94% 2 68 57971,01 0,64% 115200 2 42 116279,07 0,94% 2 33 117647,06 2,12% Mínimo 32768 127 2,38 - 32768 127 1,91 - Máximo 2 0 5M - 2 0 4M -

12MHz 10MHz

Baud rate CKx FDC Baud rate real Erro CKx FDC Baud rate real Erro

300 256 77 300,48 0,16% 256 64 300,48 0,16% 600 256 38 600,96 0,16% 128 64 600,96 0,16%

1200 64 77 1201,92 0,16% 64 64 1201,92 0,16% 2400 64 38 2403,85 0,16% 32 64 2403,85 0,16% 4800 16 77 4807,69 0,16% 16 64 4807,69 0,16% 9600 16 38 9615,38 0,16% 8 64 9615,38 0,16%

19200 4 77 19230,77 0,16% 4 64 19230,77 0,16% 38400 4 38 38461,54 0,16% 2 64 38461,54 0,16% 57600 4 25 57692,31 0,16% 1 85 58139,53 0,94% 115200 4 12 115384,62 0,16% 1 42 116279,07 0,94% Mínimo 32768 127 1,43 - 32768 127 1,19 - Máximo 2 0 3M - 1 0 5M -

Tabela 9.5

Periféricos de Comunicação 207

8MHz 6MHz

Baud rate CKx FDC Baud rate real Erro CKx FDC Baud rate real Erro

300 128 103 300,48 0,16% 128 77 300,48 0,16% 600 128 51 600,96 0,16% 128 38 600,96 0,16%

1200 128 25 1201,92 0,16% 32 77 1201,92 0,16% 2400 16 103 2403,85 0,16% 32 38 2403,85 0,16% 4800 16 51 4807,69 0,16% 8 77 4807,69 0,16% 9600 16 25 9615,38 0,16% 8 38 9615,38 0,16%

19200 16 12 19230,77 0,16% 2 77 19230,77 0,16% 38400 1 103 38461,54 0,16% 2 38 38461,54 0,16% 57600 1 68 57971,01 0,64% 2 25 57692,31 0,16% 115200 1 33 117647,06 2,12% 2 12 115384,62 0,16% Mínimo 32768 127 0,95 - 32768 127 0,72 - Máximo 1 0 4M - 1 0 3M -

4MHz 2MHz

Baud rate CKx FDC Baud rate real Erro CKx FDC Baud rate real Erro

300 64 103 300,48 0,16% 32 103 300,48 0,16% 600 64 51 600,96 0,16% 16 103 600,96 0,16%

1200 16 103 1201,92 0,16% 16 51 1201,92 0,16% 2400 16 51 2403,85 0,16% 16 25 2403,85 0,16% 4800 16 25 4807,69 0,16% 16 12 4807,69 0,16% 9600 16 12 9615,38 0,16% 1 103 9615,38 0,16%

19200 1 103 19230,77 0,16% 1 51 19230,77 0,16% 38400 1 51 38461,54 0,16% 1 25 38461,54 0,16% 57600 1 33 58823,53 2,12% 1 16 58823,53 2,12% 115200 1 16 117647,06 2,12% 1 7 125000,00 8,51% Mínimo 32768 127 0,48 - 32768 127 0,24 - Máximo 1 0 2M - 1 0 1M -

Tabela 9.6

Observe que o valor constante no campo FDC das tabelas deve ser carregado no registrador SDRmn com um deslocamento de 9 bits à esquerda. Assim, supondo que se deseje configurar o transmissor da UART0 para operar numa velocidade de 19200bps com clock principal de 32MHz, a configuração do baud rate deverá ser feita da seguinte forma (utilizando os símbolos do arquivo myRL78.h):

// Supondo que utilizaremos o CK0 como clock da UART

SPS0 = SAU_CK0_DIV32; // prescaler CK0 da SAU0 dividindo por 32

...

SDR00 = 25<<9;

Microcontroladores RL78: Guia Básico 208

9.1.2.2. Operação em Modo Snooze

As UARTs 0 e 2 podem ser configuradas para operar em modo snooze, desta forma elas podem acordar a CPU ao receber dados.

A operação em modo snooze é controlada pelo registrador SSCm. Na SAU0, o bit AWC0 configura a operação em modo snooze para a UART0 e na SAU1, o bit AWC1 configura a mesma função para a UART2.

Quando o bit AWC está setado, a UART é habilitada para operar em modo snooze e quando o mesmo está apagado, a operação em modo snooze é desabilitada.

Atenção: no modo snooze a velocidade máxima de operação da UART é 9600bps, enquanto que a velocidade mínima é de 4800bps! A operação fora destas velocidades pode provocar erros de comunicação e perda de dados.

9.1.2.3. LIN

A UART2 pode ser utilizada para implementar comunicação em protocolo LIN (Local Interconnect Network), um protocolo bastante utilizado na indústria automotiva.

Para operar em modo LIN, é necessário utilizar a interrupção externa INTP0 para detecção do pulso de wakeup e o canal 7 da TAU0 (no modo de captura de ciclo) para medir o quadro de break e (no modo de captura de período) medir os pulsos do quadro de sincronismo.

O registrador ISC permite associar os sinais INTP0 e TI07 a entrada RxD2 da UART, tornando desnecessário fazer estas conexões externamente.

O manual de hardware do microcontrolador mostra em maiores detalhes a configuração e operação da UART2 em modo LIN.

9.1.2.4. API Applilet

O Applilet3 oferece uma série de funções que podem ser utilizadas para implementar a comunicação serial utilizando qualquer uma das UARTs disponíveis:

• R_UARTx_Start() – para disparar a UARTx, esta função também habilita as interrupções da UART;

• R_UARTx_Stop() – para encerrar a comunicação da UARTx, as interrupções da mesma são também desabilitadas;

• R_UARTx_Send(uint8_t *txbuf, uint16_t txnum) – para envio de dados pela UARTx. Esta função transmite “txnum” caracteres armazenados no buffer (array) indicado por “txbuf”. Esta função retorna imediatamente após a chamada (a função R_UARTx_Callback_SendEnd é chamada automaticamente quando a transmissão é completada);

• R_UARTx_Receive(uint8_t *rxbuf, uint16_t rxnum) – para recepção de dados pela UARTx. Esta função armazena no buffer “rxbuf” os “rxnum” caracteres

Periféricos de Comunicação 209

recebidos pela UART. Esta função retorna imediatamente após a chamada (a função R_UARTx_Callback_ReceiveEnd é chamada automaticamente quando a recepção é completada);

As funções de callback a seguir podem ser definidas pelo usuário (no arquivo r_cg_serial_user.c):

• R_UARTx_Callback_SendEnd() – esta função é chamada automaticamente quando todos os dados do buffer de transmissão (especificado na função R_UARTx_Send) foram transmitidos;

• R_UARTx_Callback_ReceiveEnd() – esta função é chamada automaticamente quando o buffer de recepção (especificado na função R_UARTx_Receive) está cheio;

• R_UART_Callback_Error() – esta função é chamada sempre que ocorre um erro de recepção na UART;

• R_UART_Callback_SoftwareOverRun(uint8_t rxdata) – esta função é chamada quando novos dados são recebidos e o buffer de recepção (especificado por R_UARTx_Receive) está cheio. A variável “rxdata” contém o dado recebido.

9.1.2.5. Exemplo

O exemplo a seguir demonstra como configurar a UART do RL78/G13. A aplicação utiliza a UART2 conectada através da COM virtual integrada a placa de promoção do RL78/G13 (YRPBRL78G13) para realizar a comunicação com um computador através da porta USB.

Os caracteres enviados pelo computador são lidos e o programa retorna pela serial o caractere seguinte, assim, ao receber “a” é retornado “b”, ao receber “c” é retornado “d” e assim por diante. Adicionalmente, ao receber “a” o led D2 é ligado e ao receber “b” o led D2 é desligado.

Para executar este programa é necessário que, após o download do mesmo, os jumpers J6 a J9 sejam colocados na posição 2-3, de forma que os pinos da UART2 (TxD2 e RxD2) sejam conectados aos pinos RX e TX da conversor USB-serial da placa. Após isso é possível utilizar um programa de terminal serial (como o Termite, disponível em http://www.compuphase.com/software_termite.htm) para fazer a comunicação com a placa. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

Microcontroladores RL78: Guia Básico 210

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define __9600BPS 51 << 9

#define LED P7_bit.no7

#pragma vector = INTSR2_vect

__interrupt void trata_rx_UART2(void)

unsigned char temp;

temp = RXD2; // lê o caractere recebido

TXD2 = temp+1; // envia o caractere (seguinte)

if (temp=='a') LED = 0; // se recebeu "a", liga o led

if (temp=='b') LED = 1; // se recebeu "b", desliga o led

#pragma vector = INTST2_vect

__interrupt void trata_tx_UART2(void)

void MCU_init(void)

PM1_bit.no3 = 0; // P13/TXD2 como saída

P1_bit.no3 = 1; // coloca TXD2 em 1 (importante!!!) PM1_bit.no4 = 1; // P14/RXD2 como entrada

PM7_bit.no7 = 0; // P77 como saída (led)

LED = 1; // desliga o led

SAU1EN = 1; // ativa a SAU1

// Clock CK0 da SAU1 = 32MHz / 32 = 1MHz

SPS1 = SAU_CK0_DIV32;

// Configura o canal 0 da SAU1 (transmissão da UART2)

SMR10 = SAU_MD_UART | SAU_INT_BUFFER;

SCR10 = SAU_COMM_TX | SAU_NO_PARITY | SAU_LSB_FIRST | SAU_ONE_STOP | SAU_8BITS;

SDR10 = __9600BPS; // seta o baud rate do transmissor

// Configura o canal 1 da SAU1 (recepção da UART2)

SMR11 = bSAU_STS | SAU_MD_UART;

SCR11 = SAU_COMM_RX | SAU_NO_PARITY | SAU_LSB_FIRST | SAU_ONE_STOP | SAU_8BITS;

SDR11 = __9600BPS; // seta o baud rate do receptor

SOE1 = SAU_CH0; // habilita a saída da UART2

SO1 = SAU_CH0; // seta a saída TXD2

NFEN0 = SNFEN20; // ativa o filtro digital da entrada RXD2

// Dispara os canais 0 e 1 da SAU1

SS1 = SAU_CH1 | SAU_CH0;

SRMK2 = 0; // habilita a interrupção de recepção da UART

__enable_interrupt(); // habilita as interrupções do RL78

void main(void)

MCU_init();

while (1);

Exemplo 9.1

Periféricos de Comunicação 211

9.1.3. Modo CSI

O modo CSI (Clocked Serial Interface) permite o envio e recepção de dados seriais através de uma interface de 3 fios: SI (entrada de dados seriais), SO (saída de dados seriais) e SCK (entrada ou saída de clock). Diferentemente da SPI (Serial Peripheral Interface) a CSI não inclui uma linha de seleção de periférico (normalmente chamada de SS – Slave Select no dispositivo mestre e CS – Chip Select no dispositivo escravo), por isso, esta funcionalidade deve ser implementada pelo software.

Note que na terminologia SPI, o sinal SO é chamado MOSI (Master Out Slave In) e o sinal SI é chamado MISO (Master In Slave Out).

A figura 9.2 mostra o esquema típico de ligação da interface CSI com um periférico. O dispositivo mestre inicia e controla a comunicação, sendo o responsável por gerar o sinal de clock (SCK) que sincroniza a transferência de dados. Para cada bit enviado serialmente pela saída SO, outro bit é recebido pela entrada SI. Ao final de sete ou oito pulsos de clock (conforme a configuração da CSI) o dado do mestre é enviado para o escravo e o dado presente no escravo é recebido pelo mestre.

Figura 9.2

A tabela 9.7 mostra a nomenclatura das unidades CSI disponíveis (consulte a tabela 9.1 para a disponibilidade de canais SAU conforme a pinagem do microcontrolador).

SAU Canal Número do canal (p) Unidade CSI

0 00 CSI00

1 01 CSI01

2 10 CSI10 0

3 11 CSI11

0 20 CSI20

1 21 CSI21

2 30 CSI30 1

3 31 CSI31

Tabela 9.7

A frequência máxima de operação da CSI em modo mestre é de fMCLK/2 (com fMCLK≤24MHz e apenas na CSI00) ou fMCLK/4 (com fMCLK≤24MHz e válido para os demais canais das SAU). No modo escravo a frequência máxima é igual fMCLK/6.

O modo CSI é selecionado configurando-se os bits MD2=0 e MD1=0 (símbolo SAU_MD_CSI no arquivo myRL78.h) no registrador de controle de modo do canal (SMRmn). Neste modo pode-se utilizar o símbolo SIOp (onde p é o número da unidade CSI de acordo com a

Mestre Escravo SI SO SI SO

SCK SCK

SS CS

Microcontroladores RL78: Guia Básico 212

tabela 9.7) para acessar a parte menos significativa do SDRmn, de forma a ler os dados recebidos pela CSI ou escrever novos dados a serem transmitidos (conforme o modo de operação).

A interface CSI pode operar em seis modos distintos, de acordo com a configuração dos bits TXE, RXE (registrador SCRmn) e CCS (registrador SMRmn). A tabela 9.8 mostra as diferentes configurações possíveis.

CCS TXE RXE Modo de Operação

0 1 0 Modo mestre, somente transmissão

0 0 1 Modo mestre, somente recepção

0 1 1 Modo mestre, transmissão e recepção

1 1 0 Modo escravo, somente transmissão

1 0 1 Modo escravo, somente recepção

1 1 1 Modo escravo, transmissão e recepção

Tabela 9.8

O bit MD0 (registrador SMRmn) permite configurar o evento que gera uma interrupção, conforme mostra a tabela 9.9.

MD0 Modo Descrição do Evento de Interrupção

0 Recepção Um caractere foi recebido, a aplicação deve fazer a leitura do mesmo no registrador SIO do canal

0 Transmissão Um caractere foi transmitido, para outra transmissão a aplicação deve escrever no novo dado no registrador SIO do canal

0 Transmissão/

Recepção

Um caractere foi transmitido e outro foi recebido durante a última transferência, a aplicação deve escrever um novo dado em SIO do canal para iniciar uma nova transmissão

1 Recepção O buffer está cheio, a aplicação deve ler os dados no registrador SIO do canal até que o indicador de buffer cheio seja apagado (bit BFF no registrador SSRmn)

1 Transmissão O buffer está vazio, a aplicação deve escrever novos dados no registrador SIO do canal até que o indicador de buffer cheio seja setado (bit BFF no registrador SSRmn)

1 Transmissão/

Recepção

O buffer está cheio, a aplicação deve ler o dado recebido no registrador SIO e em seguida escrever o novo dado a ser transmitido no SIO. Novos dados podem ser escritos no SIO até que o bit BFF seja setado, indicando que o buffer está cheio

Tabela 9.9

Também é possível configurar a ordem de deslocamento (iniciando pelo MSB ou pelo LSB), a polaridade do sinal de clock, a fase do sinal de dados e o tamanho da palavra transmitida (7 ou 8 bits).

Atenção: no modo CSI a controle de paridade deve estar desativado (bits PTC1 e PTC0 = 0 no registrador SCRmn) e a opção de bits de parada deve ser desativada (bits SLC1 e SLC0 = 0 no registrador SCRmn)!

Dois bits do registrador SCRmn configuram a polaridade do clock e a fase dos dados enviados/recebidos. O controle de polaridade de clock (CKP) permite selecionar se o sinal de clock é ativo em nível baixo (CKP=0) ou ativo em nível alto (CKP=1). O controle de fase dos

Periféricos de Comunicação 213

dados (DAP) seleciona se o dado é amostrado na segunda borda do clock (DAP=0) ou na primeira borda (DAP=1).

Note que os bits CKP e DAP possuem polaridade invertida em relação aos bits equivalentes em outras interfaces SPI encontradas no mercado!

A figura 9.3 mostra os quatro modos possíveis selecionados através dos bits DAP e CKP, nela é possível identificar o instante em que o receptor amostra o sinal de entrada serial (linha tracejada em SI) e o instante em que o transmissor coloca um novo dado na saída serial (SO).

SCK (CKP=1)

SI (DAP=1)

SO (DAP=1) D0 D1 D2 D3 D4 D5 D6 D7

SCK (CKP=1)

SI (DAP=0)

SO (DAP=0) D0 D1 D2 D3 D4 D5 D6 D7

SCK (CKP=0)

SI (DAP=1)

SO (DAP=1) D0 D1 D2 D3 D4 D5 D6 D7

SCK (CKP=0)

SI (DAP=0)

SO (DAP=0) D0 D1 D2 D3 D4 D5 D6 D7

Figura 9.3

A tabela 9.10 mostra a equivalência entre os modos de operação CSI e os modos de operação SPI.

CKP DAP Modo CSI Modo SPI Símbolo C (myRL78.h) 1 1 3 0 SAU_CSI_CLKMODE3 1 0 2 1 SAU_CSI_CLKMODE2 0 1 1 2 SAU_CSI_CLKMODE1 0 0 0 3 SAU_CSI_CLKMODE0

Tabela 9.10 – Modos SPI

A configuração de um canal da SAU para operar no modo CSI deve seguir os seguintes passos:

1. Habilitação da SAU (registrador PER0);

2. Configuração dos divisores de clock da SAU (registrador SPSm);

3. Configuração do canal: no registrador SMRmn somente a seleção do clock, o modo de operação do canal e a seleção do prescaler devem ser alterados. Algumas possibilidades de configuração são mostradas a seguir: // Modo mestre, clock CK0, interrupção na transferência

SMRmn = SAU_MD_CSI;

// Modo mestre, clock CK1, interrupção buffer cheio/vazio

SMRmn = bSAU_CKS | SAU_MD_CSI | SAU_INT_BUFFER;

// Modo escravo, clock CK0, interrupção na transferência

SMRmn = SAU_CLK_EXT | SAU_MD_CSI;

Microcontroladores RL78: Guia Básico 214

4. No registrador SCRmn somente a seleção TX/RX, modo de operação CSI, ordem dos dados e largura da palavra devem ser alterados. Algumas possibilidades de configuração são mostradas a seguir: // Transmissor, CSI modo 0, 8 bits iniciando pelo MSB

SCRmn= SAU_COMM_TX | SAU_CSI_CLKMODE0 | SAU_8BITS;

// Receptor, CSI modo 2, 8 bits iniciando pelo MSB

SCRmn= SAU_COMM_RX | SAU_CSI_CLKMODE2 | SAU_8BITS;

// TX/RX, CSI modo 3, 8 bits iniciando pelo LSB

SCRmn= SAU_COMM_TXRX | SAU_CSI_CLKMODE3 | SAU_LSB_FIRST | SAU_8BITS;

5. Configuração da velocidade da CSI no campo FDC do registrador SDRmn. A configuração do baud rate será vista em detalhes no próximo tópico;

6. Configuração dos registradores de controle de E/S da SAU (SOm, SOLm e SOEm) conforme modo de operação desejado. Normalmente é necessário apenas ativar a saída (pino SO) do canal no registrador SOEm e configurar o estado da saída no registrador SOm (lembre-se de configurar a saída correspondente ao pino SCK para o nível inativo, caso contrário a comunicação não ocorrerá);

7. Habilitar a interrupção da CSI (INTCSIp onde p é o número da unidade CSI de acordo com a tabela 9.7);

8. Disparar o canal para dar início ao processo de comunicação (registrador SSm).

Cada canal CSI dispõe de um único vetor de interrupção (INTCSIp_vect, onde p é o número da unidade CSI de acordo com a tabela 9.7) para onde o programa é desviado quando o flag CSIIFp é setado e a interrupção do canal está habilitada (CSIMKp=0). O flag CSIIFp é setado sempre que uma transferência é completada, o buffer de transmissão está vazio ou o buffer de recepção está cheio. a condição é determinada pelo bit MD0 do registrador de configuração do canal (SMRmn) e também depende do modo de operação do canal (transmissão, recepção ou transmissão/recepção).

Caso um novo dado seja armazenado no registrador SIOp antes que o anterior tenha sido lido pela aplicação o indicador de erro OVFmn (registrador SSRmn) é setado.

Alguns chips disponíveis no mercado utilizam uma única linha bidirecional para entrada e saída de dados digitais, operando num modo chamado de SPI a três fios (DATA, SCK e CE). É possível utilizar um canal da CSI para comunicação com este tipo de periférico, para isso, basta conectar as linhas SI e SO da CSI à linha de dados bidirecional do chip escravo e utilizar o modo de transmissão/recepção mestre. Lembre-se de desativar a saída SO quando o escravo enviar dados para o mestre!

9.1.3.1. Configuração do Baud Rate

A configuração da velocidade de comunicação dos canais CSI é realizada através de dois registradores: SPSm e o registrador SDRmn relativo ao canal da CSI.

O baud rate final pode ser calculado através da seguinte fórmula:

22*FDCCKx

f

Baudrate

MCLK

+=

Periféricos de Comunicação 215

Onde:

Baudrate é a velocidade em bits por segundo (bps);

CKx é o fator de divisão do prescaler da SAU (CK0 ou CK1) configurado no registrador SPSm;

FDC é o valor configurado no campo FDC do registrador SDRmn.

Observe que o valor FDC deve ser carregado no registrador SDRmn com um deslocamento de 9 bits à esquerda. Assim, supondo que se deseje configurar o transmissor da CSI00 para operar numa velocidade de 1Mbps com clock de 32MHz, poderemos utilizar um fator de divisão de 16 para CK0 e manter FDC em zero. A configuração do baud rate deverá ser feita da seguinte forma (utilizando os símbolos do arquivo myRL78.h):

// Supondo que utilizaremos o CK0 como clock da CSI00

SPS0 = SAU_CK0_DIV16;

...

SDR00 = 0;

No modo escravo o FDC deve ser igual a zero e o clock do canal (registrador SPSm) deve ser configurado para no mínimo metade da frequência do clock de comunicação enviado pelo mestre.

9.1.3.2. API Applilet

O Applilet3 oferece uma série de funções que podem ser utilizadas para implementar a comunicação serial síncrona utilizando qualquer um dos canais CSI disponíveis (a letra p especifica um dos canais CSI conforme a tabela 9.7):

• R_CSIp_Start() – para disparar a CSIp, esta função também habilita a interrupção do canal;

• R_CSIp_Stop() – para encerrar a comunicação da CSIp, a interrupção do canal também é desabilitada;

• R_CSIp_Send(uint8_t *txbuf, uint16_t txnum) – quando o canal é configurado para o modo de transmissão, esta função transmite “txnum” caracteres armazenados no buffer (array) indicado por “txbuf”. Esta função retorna imediatamente após a chamada (a função r_csip_callback_sendend é chamada automaticamente quando a transmissão é completada);

• R_CSIp_Receive(uint8_t *rxbuf, uint16_t rxnum) – quando o canal é configurado para o modo de recepção, esta função fará com que os dados recebidos pela CSI sejam armazenados no buffer “rxbuf” até que o número especificado por “rxnum” de caracteres sejam recebidos. Esta função retorna imediatamente após a chamada (a função re_csip_callback_receiveend é chamada automaticamente quando a recepção é completada);

• R_CSIp_Send_Receive(uint8_t *txbuf, uint16_t txnum, uint8_t *rxbuf) – quando o canal é configurado para o modo de transmissão/recepção, esta função transmite “txnum” caracteres armazenados no buffer (array) indicado por “txbuf” ao mesmo

Microcontroladores RL78: Guia Básico 216

tempo em que recebe a mesma quantidade de caracteres armazenando-os no buffer especificado por “rxbuf”. Esta função retorna imediatamente após a chamada (esta função chama automaticamente as funções r_csip_callback_sendend e r_csip_callback_receiveend para ao completar a transferência);

As funções de callback a seguir podem ser definidas pelo usuário (no arquivo r_cg_serial_user.c):

• r_csip_callback_sendend() – esta função é chamada automaticamente quando todos os dados do buffer de transmissão (especificado na função R_CSIp_Send) foram transmitidos;

• r_csip_callback_error() – esta função é chamada sempre que ocorre um erro de recepção na CSI;

• r_csip_callback_receiveend() – esta função é chamada automaticamente quando o buffer de recepção (especificado na função R_CSIp_Receive) está cheio;

9.1.4. Modo I2C

O protocolo I2C (Inter-Integrated Comunication – Comunicação inter-integrados) é um protocolo serial síncrono half-duplex a dois fios desenvolvido pela Philips Holandesa para auxiliar na modularização das placas de controle dos seus aparelhos de TV.

O I2C é um protocolo do tipo mestre-escravo e possui como grande vantagem a característica de permitir que múltiplos dispositivos possam compartilhar o mesmo barramento e ser endereçados individualmente, sem a necessidade de linhas de controle ou habilitação auxiliares. Como desvantagem do I2C podemos citar a sua maior complexidade e menor velocidade (quando comparado com outros protocolos síncronos como o SPI, por exemplo).

Eletricamente o protocolo é baseado numa configuração do tipo coletor aberto (dreno aberto nos dispositivos CMOS), o que significa que nenhum dispositivo pode manter uma linha ativamente em nível lógico “1”. Duas linhas são utilizadas para se efetuar a comunicação: SDA (Serial Data, utilizada para o tráfego bidirecional de dados) e SCL (Serial Clock, utilizada para sincronização entre o mestre e o escravo).

A figura 9.4 mostra um típico barramento I2C com um mestre (master1) e vários escravos (slave1, slave2, slaveN). Observe também a existência dos resistores de pull-up RP, necessários ao funcionamento do barramento.

Figura 9.4 – Barramento I2C

Periféricos de Comunicação 217

O protocolo I2C prevê regras simples que devem ser seguidas durante a comunicação:

1. Nenhum dispositivo pode forçar ativamente a linha em nível lógico “1”;

2. Não é permitido alterar o estado da linha SDA durante a fase alta do sinal de clock (SCL);

3. Uma borda de descida da linha SDA durante a fase alta de SCL é considerada uma condição de partida (início da comunicação);

4. Uma borda de subida da linha SDA durante a fase alta de SCL é considerada uma condição de parada (fim da comunicação).

Figura 9.5 – Condição de partida e de parada

5. Após o envio de um byte o transmissor (que pode ser o mestre ou o escravo) deve sempre enviar um novo pulso de clock para que o receptor responda com o bit de reconhecimento (bit de acknowledgement ou ACK). ACK = 0 indica que o receptor reconheceu o dado, ao passo que ACK = 1 indica que o receptor não reconheceu o mesmo;

SCL

SDA

Partida 0 0 1 0 0 1 1 0 ACK Parada

Figura 9.6 – Um típico quadro I2C

6. Uma comunicação I2C deve ser sempre precedida de um quadro de endereçamento. A função do mesmo é especificar o endereço do escravo com o qual o mestre deseja se comunicar e a natureza da operação (leitura ou escrita). O bit R/W especifica se a operação é de escrita (R/W=0) ou leitura (R/W=1). A figura 9.7 mostra um típico quadro de endereçamento I2C (endereços de 7 bits);

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0 START A6 A5 A4 A3 A2 A1 A0 R/W ACK

Endereço do escravo (7 bits) 0-escrita 1-leitura

0-ACK 1-NACK

Figura 9.7 – Quadro de endereçamento I2C

7. Quando o bit R/W do quadro de endereçamento é igual a 0 (escrita), o dispositivo mestre envia dados para o escravo. Nesta situação o mestre opera como transmissor e o escravo como receptor. A cada byte enviado pelo mestre o escravo deve responder com um bit ACK (0 ou 1). Após enviar todos os dados ao escravo o mestre deve gerar uma condição de parada para que a comunicação seja encerrada e o barramento liberado;

Condição de partida Condição

de parada

Microcontroladores RL78: Guia Básico 218

8. Quando o bit R/W do quadro de endereçamento é igual a 1 (leitura), o dispositivo mestre irá receber dados do escravo. Nesta situação o mestre atua como receptor e o escravo como transmissor. Após cada byte enviado pelo escravo o mestre deverá responder com um bit ACK (0 ou 1). Quando todos os bytes forem recebidos, o mestre encerra a comunicação com uma condição de parada, liberando o barramento;

9. É possível também que ocorram múltiplas inversões no sentido da comunicação dentro de uma mesma transferência, neste caso, o mestre envia um quadro de endereçamento com R/W=0 (escrita) seguido por um ou mais quadros de dados (conforme necessário pelo dispositivo escravo), em seguida o mestre deve gerar uma nova condição de partida (chamada de repeated start ou partida repetida na terminologia I2C) com um novo quadro de endereçamento, desta vez com o bit R/W=1 (leitura) e aí a sentido de comunicação será invertido e o mestre poderá receber tantos bytes do escravo quanto for necessário. Eventualmente é possível realizar outras inversões no sentido da comunicação seguindo o mesmo processo descrito acima. Após enviar/receber todos os dados, o mestre deve encerrar a comunicação com uma condição de parada, liberando o barramento.

O protocolo I2C prevê também uma série de endereços pré-definidos para alguns tipos de circuitos integrados e aplicações conforme mostra a tabela 9.11. Note a presença de um endereço especial para chamada geral (broadcast) o qual todos os dispositivos devem responder, um endereço especial para o modo mestre de alta velocidade (até 3,4Mbps) e um endereço especial para utilização de endereçamento de 10 bits (ao invés dos tradicionais 7).

Endereço R/W Descrição 0000000 0 Endereço de chamada geral (broadcast) 0000000 1 Byte de partida (para dispositivos lentos) 0000001 x Endereço CBUS 0000010 x Reservado para outros formados de barramento 0000011 x Reservado para propósitos futuros 00001xx x Modo mestre de alta velocidade (até 3,4Mbps) 0010xxx x Sintetizadores de voz 0011xxx x Interfaces de audio PCM 0100xxx x Geradores de audio 0111xxx x Displays LED/LCD 1000xxx x Interfaces de video 1001xxx x Conversores A/D e D/A 1010xxx x Memórias 1100xxx x Sintetizadores de RF 1101xxx x Calendários/relógios 11111xx x Reservado para propósitos futuros 11110xx x Modo de endereçamento de 10 bits

Tabela 9.11 – Alguns endereços reservados da I2C

9.1.4.1. I2C Simplificado na SAU

A implementação do protocolo I2C na SAU consiste numa solução mista de hardware e software, permitindo uma grande economia de recursos e aumento da velocidade de transferência quando comparada a uma solução inteiramente por software.

Conforme já foi dito anteriormente, este modo de operação consiste numa simplificação do I2C, apresentando como limitações principais:

Periféricos de Comunicação 219

1. Operação apenas em modo mestre;

2. Não é permitida a presença de outro mestre no barramento (não há suporte para arbitramento de barramento);

3. Não é suportada a funcionalidade de clock stretching, que permite que um dispositivo aguarde por outro escravo lento.

Estas limitações não constituem um grande problema pois a maioria das aplicações do I2C em sistemas microcontrolados envolve comunicação apenas de um mestre (o microcontrolador) com um ou mais escravos (tipicamente memórias EEPROM ou flash, relógios de tempo real, etc.), o que é perfeitamente atendido pelo modo I2C simplificado. Nos demais casos é possível utilizar a interface IICA para implementação de comunicação I2C sem as limitações impostas pela SAU.

A tabela 9.12 mostra a nomenclatura das unidades I2C disponíveis nos RL78. Consulte a tabela 9.1 para a disponibilidade de canais nos diversos encapsulamentos e a tabela 9.2 para a pinagem dos canais no modo I2C.

SAU Canal Número do Canal (p) Unidade I2C Simplificado

0 00 IIC00 1 01 IIC01 2 10 IIC10

0

3 11 IIC11 0 20 IIC20 1 21 IIC21 2 30 IIC30

1

3 31 IIC31

Tabela 9.12

Os pinos utilizados no modo I2C são o SCK/SCL (clock) e SI/SDA (dados), estes pinos devem ser configurados para operar como saídas dreno aberto (registrador POMx). O pino de saída de dados do canal (SO) não é utilizado neste modo (mas internamente a entrada e saída do registrador de deslocamento do canal são conectadas ao pino DAS).

A velocidade máxima de transferência no modo I2C simplificado é de 1Mbps (1MHz) quando operando no modo rápido melhorado, 400kbps (400kHz) no modo rápido ou 100kbps (100kHz) no modo padrão.

No modo I2C simplificado o registrador para leitura/escrita de dados na interface é representado pelo símbolo SIOp (onde p é o número do canal conforme mostrado na tabela 9.12).

A seleção do modo I2C simplificado é feita configurando-se os bits MD2=1 e MD1=0 no registrador SMRmn. O bit MD0 deve ser mantido em zero neste modo de operação (geração de interrupção ao final de cada transferência).

Ainda no registrador SMRmn, a fonte de clock deve ser interna (CCS=0), o disparo deve ser por software (STS=0) e a recepção não deve ser invertida (SIS=0).

No registrador SCRmn, é necessário configurar os bits SLC1=0 e SLC0=1 (um bit de parada) pois o bit de parada no modo I2C é utilizado na função ACK, também é necessário

Microcontroladores RL78: Guia Básico 220

selecionar o tamanho do caractere para 8 bits (DLS1=DLS0=1), a ordem dos dados deve ser primeiro o MSB (bit DIR=0) e os bits TXE e RXE devem ser configurados de acordo com o modo do mestre (transmissor ou receptor).

A configuração de um canal da SAU para operar no modo I2C simplificado deve seguir os seguintes passos:

1. Habilitação da SAU (registrador PER0);

2. Configuração dos divisores de clock da SAU (registrador SPSm);

3. Configuração do canal: no registrador SMRmn somente o modo de operação do canal e a seleção do prescaler devem ser alterados. Algumas possibilidades de configuração são mostradas a seguir: // Modo I2C com prescaler CK0

SMRmn = SAU_MD_I2C;

// Modo I2C com prescaler CK1

SMRmn = bSAU_CKS | SAU_MD_I2C;

4. No registrador SCRmn basicamente alteramos somente a seleção TX/RX, a paridade deve ser nenhuma, um bit de parada (que é utilizado como ACK) e palavra de 8 bits. As possibilidades de configuração são mostradas a seguir: // I2C como transmissor

SCRmn= SAU_COMM_TX | SAU_ONE_STOP | SAU_8BITS;

// I2C como receptor

SCRmn= SAU_COMM_RX | SAU_ONE_STOP | SAU_8BITS;

5. Configuração do baud rate da I2C no campo FDC do registrador SDRmn. A configuração do baud rate será vista em detalhes no próximo tópico;

6. Os registradores POMm relativos aos pinos SDA e SCL devem ser configurados para o modo de saída em dreno aberto;

7. Configuração dos registradores de controle de E/S da SAU (SOm, SOLm e SOEm). O bit relativo ao pino SDA no registrador SOEm deve ser mantido em “0”. Os bits relativos ao canal no registrador SOm devem ser mantidos em “1” (tanto o CKO quanto o SO), isto garante que, após a inicialização do canal, os pinos SDA e SCL permaneçam no estado inativo (nível lógico “1” mantido por pull-up externo);

8. Habilitar a interrupção do canal (INTIICp, onde p é o número do canal conforme a tabela 9.12);

9. No modo I2C o canal não é disparado na inicialização, o disparo deve ocorrer apenas após a geração da condição de partida.

Lembre-se de instalar resistores de pull-up nas linhas SDA e SCL! Não é possível utilizar os resistores internos já que, ao configurar os pinos para o modo dreno aberto, os resistores internos dos pinos são automaticamente desabilitados.

Periféricos de Comunicação 221

9.1.4.2. Configuração do Baud Rate

A configuração da velocidade de comunicação dos canais I2C é realizada através de dois registradores: SPSm e o registrador SDRmn relativo ao canal da I2C.

O baud rate final pode ser calculado através da seguinte fórmula:

22*FDCCKx

f

Baudrate

MCLK

+=

Onde:

Baudrate é a velocidade em bits por segundo (bps);

CKx é o fator de divisão do prescaler da SAU (CK0 ou CK1) configurado no registrador SPSm;

FDC é o valor configurado no campo FDC do registrador SDRmn.

Observe que o valor FDC deve ser carregado no registrador SDRmn com um deslocamento de 9 bits à esquerda. Assim, supondo que se deseje configurar o transmissor da IIC00 para operar numa velocidade de 1Mbps com clock de 32MHz, poderemos utilizar um fator de divisão de 8 para CK0 e utilizar FDC = 1. A configuração do baud rate deverá ser feita da seguinte forma (utilizando os símbolos do arquivo myRL78.h):

// Supondo que utilizaremos o CK0 como clock da CSI00

SPS0 = SAU_CK0_DIV8;

...

SDR00 = 1<<9;

9.1.4.3. Comunicação I2C

Depois de inicializado o canal da SAU, a comunicação I2C deverá obedecer aos seguintes passos:

1. Partida: o início de uma transferência I2C é sinalizado pela condição de partida, que consiste numa borda de descida da linha SDA enquanto a linha SCL permanece inativa (nível lógico “1” fornecido por pull-up externo). Na SAU a condição de partida é gerada por software, através dos seguintes passos:

a. Inicialmente a aplicação deve escrever “0” no bit correspondente ao pino SDA do registrador SOm e aguardar por um período mínimo de metade do clock de comunicação;

b. Em seguida a linha SCK deve ser colocada em zero, para isso, a aplicação deve escrever “0” no bit correspondente (CKO) do registrador SOm;

c. Feito isso a aplicação deve habilitar a saída SDA (registrador SOEm) e em seguida disparar o canal (registrador SSm) para que a comunicação tenha início (transmissão do quadro de endereçamento);

2. Quadro de endereçamento: após uma condição de partida (ou partida repetida) o primeiro quadro a ser transmitido pela I2C deve ser o e endereçamento. A aplicação

Microcontroladores RL78: Guia Básico 222

deve escrever o byte de endereçamento (7 bits do endereço do escravo mais o bit R/W, como mostra a figura 9.7) no registrador SIO do canal para que a transmissão tenha início;

3. Quando a transmissão for completada, uma interrupção INTIICp (onde p é o número do canal conforme a tabela 9.12) será gerada. A ISR deverá verificar o estado do bit PEF (registrador SSRm) para determinar o resposta (ACK) enviada pelo escravo: se PEF=0, significa que houve reconhecimento pelo escravo (ACK=0), neste caso o mestre deve prosseguir com a comunicação. Se PEF=1, não houve resposta do escravo (possivelmente porque o endereço não existe ou o escravo não está pronto) e a aplicação deverá providenciar uma nova tentativa ou tratar o erro;

4. Transmissão de dados: caso o mestre tenha enviado um quadro de endereçamento com R/W=0 e o escravo tenha respondido com ACK=0, então a aplicação deverá providenciar o envio dos dados ao escravo. Para isso basta escrever o dado no registrador SIO do canal e aguardar pela interrupção INTIICp;

5. A ISR deverá verificar o estado do ACK (através do bit PEF, registrador SSRm), caso PEF=0, houve reconhecimento e um novo dado pode ser transmitido, caso contrário, um processamento de erro deve ser executado (isto varia conforme o tipo de escravo). Caso não haja mais dados a serem transmitidos o mestre deve encerrar a comunicação, enviando uma condição de parada (passo 9);

6. Recepção de dados: caso o mestre tenha enviado um quadro de endereçamento com R/W=1 e tenha recebido um ACK=0 do escravo, então a aplicação deverá preparar-se para receber dados do escravo, devendo o mestre ser configurado para o modo de recepção. Para isso, o canal deve ser paralisado (registrador STm), de forma que se possa modificar o registrador SCRmn (o bit TXE deve ser apagado e o bit RXE setado). Em seguida o canal deve ser disparado novamente (registrador SSm) e um valor qualquer (por exemplo 0xFF) deve ser escrito no registrador SIO do canal (isto força a SAU a iniciar uma transferência, mas nenhum dado será transmitido, apenas recebido);

7. Ao ser completada a transferência a SAU gera automaticamente um ACK=0 e a interrupção INTIICp é disparada. A ISR deve então efetuar a leitura do dado recebido no registrador SIO do canal. Caso ainda existam dados a serem recebidos, o mestre deve fazer uma nova escrita (qualquer valor) no registrador SIO para que outra transferência tenha início. Caso o mestre não deseje mais receber dados, uma condição de parada deve ser gerada (passo 9);

8. Partida Repetida (repeated start): caso o mestre necessite modificar o sentido da comunicação, é necessário gerar uma nova condição de partida (partida repetida). Para isso, é necessário seguir os seguintes passos:

a. Desabilitar o canal (via registrador STm);

b. Desabilitar a saída da I2C (via registrador SOEm);

c. Configurar a linha SCL para o estado inativo (nível lógico “1” mantido por pull-up externo) através do respectivo bit CKO (registrador SOm);

Periféricos de Comunicação 223

d. Configurar a linha SDA para o estado inativo (nível lógico “1” mantido por pull-up externo) através do respectivo bit SO (registrador SOm);

e. Iniciar a nova geração de uma condição de partida (passo 1);

9. Parada: para encerrar uma transferência I2C é necessário que o mestre gere uma condição de parada no barramento, que consiste numa borda de subida da linha de dados (SDA) enquanto a linha de clock (SCL) está em inativa (nível lógico “1” mantido pelo pull-up externo). Para gerar a condição de parada na SAU, a aplicação deve seguir os seguintes passos:

a. Paralisar a comunicação (setando o bit correspondente no registrador STm);

b. Desativar a saída (apagando o bit do registrador SOEmn). Se o mestre já se encontra em modo de recepção, este bit já deverá estar apagado;

c. Forçar a linha SDA em nível “0” (apagando o bit SO correspondente no registrador SOm);

d. Forçar a linha SCL no estado inativo (setando o bit CKO correspondente no registrador SOm) e aguardar por um período mínimo de metade do clock de comunicação;

e. Forçar a linha SDA no estado inativo (setando o bit SO correspondente no registrador SOm).

9.1.4.4. API Applilet

O Applilet3 oferece uma série de funções que podem ser utilizadas para implementar a comunicação serial síncrona utilizando qualquer um dos canais I2C disponíveis (onde p é o número do canal conforme a tabela 9.12):

• R_IICp_StartCondition() – gera uma condição de partida no barramento I2C. Esta função é chamada automaticamente pelas funções R_IICp_Master_Send() e R_IICp_Master_Receive();

• R_IICp_Master_Send(uint8_t adr, uint8_t *txbuf, uint16_t txnum) – transmite “txnum” caracteres armazenados no buffer (array) indicado por “txbuf” para o escravo no endereço “adr”. Esta função retorna imediatamente após a chamada (a função r_iicp_callback_master_sendend é executada automaticamente quando a transmissão é completada). As condições de partida e de parada são geradas automaticamente;

• R_IICp_Master_Receive(uint8_t adr, uint8_t *rxbuf, uint16_t rxnum) – recebe um bloco de dados através da interface I2C armazenando-os no buffer especificado por “rxbuf” até que o número especificado por “rxnum” de caracteres sejam recebidos. Esta função retorna imediatamente após a chamada (a função r_iicp_callback_master_receiveend é executada automaticamente quando a recepção é completada). As condições de partida e de parada são geradas automaticamente;

Microcontroladores RL78: Guia Básico 224

• R_IICp_StopCondition() – gera uma condição de parada no barramento I2C. Esta função é chamada automaticamente pelas funções R_IICp_Master_Send() e R_IICp_Master_Receive() ao término da comunicação;

• R_IICp_Stop() – para encerrar a comunicação da IICp, a interrupção do canal também é desabilitada;

As funções de callback a seguir podem ser definidas pelo usuário (no arquivo r_cg_serial_user.c):

• r_iicp_callback_master_sendend() – esta função é chamada automaticamente quando todos os dados do buffer de transmissão (especificado na função R_IICp_Master_Send) foram transmitidos;

• r_iicp_callback_master_receiveend() – esta função é chamada automaticamente quando o buffer de recepção (especificado na função R_IICp_Master_Receive) está cheio;

• r_iicp_callback_master_error(MD_STATUS flag) – esta função é chamada sempre que ocorre um erro na I2C (normalmente a recepção de um NACK vindo do escravo).

9.2. Unidades IICA (I2C)

As unidades I2C avançadas (IICA) consistem em interfaces de comunicação I2C plenas que podem operar tanto no modo mestre quanto no modo escravo (ou seja, podem endereçar e ser endereçadas por outros dispositivos mestre no barramento).

As unidades IICA apresentam as seguintes características:

• Operação em modo mestre (com suporte a arbitramento do barramento) ou modo escravo;

• Velocidade de comunicação de até 1MHz (quando a CPU opera acima de 10MHz);

• Suporte a chamada geral (broadcast);

• Pode operar em modo stop (como escravo), acordando a CPU ao ser endereçada por um mestre;

• Suporte a clock stretching: permite que o receptor mantenha a comunicação em espera até que processado o dado recebido.

A tabela 9.13 mostra a quantidade de canais IICA disponíveis conforme o encapsulamento dos RL78/G13.

IICA 20 a 64 pinos

80 a 128 pinos

Número de Canais 1 2

Tabela 9.13

Periféricos de Comunicação 225

9.2.1. Operação da IICA

A interface IICA possui todos os automatismos necessários para processar uma transferência I2C completa, sem a necessidade de grandes intervenções da aplicação.

Para utilizar uma das unidades IICA é necessário inicialmente ativá-la no registrador PER0, conforme a seguir.

Nome Bits 7 6 5 4 3 2 1 0

Leitura

Escrita RTCEN IICA1EN ADCEN IICA0EN SAU1EN SAU0EN TAU1EN TAU0EN

PER0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Bit C Símbolo C

IICA1EN Controle de clock e operação da IICA1: 0 – IICA1 desativada 1 – IICA1 ativada

IICA1EN bIICA1EN

IICA0EN Controle de clock e operação da IICA0: 0 – IICA0 desativada 1 – IICA0 ativada IICA0EN bIICA0EN

Uma vez ativada no registrador PER0, também é necessário habilitar a interface setando-se o bit IICE no registrador IICCTLn0.

A IICA possui um registrador para transferência de dados (IICAn) que pode ser utilizado para o envio de dados (quando a interface opera como transmissor) ou para leitura dos dados recebidos (quando a interface opera como receptor).

Há também um registrador específico (SVAn) para armazenamento do endereço local da interface. Este endereço é utilizado pela IICA para detectar quando ela está sendo endereçada por um dispositivo mestre do barramento.

O registrador SVAn somente é utilizado quando a IICA opera em modo escravo!

Lembre-se de que o primeiro byte enviado após uma condição de partida (ou partida repetida) é sempre o byte de endereçamento, contendo o endereço do escravo que deve receber a comunicação e o bit R/W indicador do tipo de transferência.

A velocidade de comunicação é controlada através de dois registradores: IICWLn que controla a fase baixa do sinal de clock e IICWHn que controla a fase alta do sinal de clock.

A condição de partida, que sinaliza o início de uma transferência I2C é gerada setando-se o bit STT (registrador IICCTLn0), este bit é apagado automaticamente pela interface após a geração da condição de partida. Adicionalmente, a aplicação pode verificar o estado do bit STD (registrador IICSn). Este bit indica quando uma condição de partida foi detectada no barramento.

Após a condição de partida o mestre deve enviar o campo de endereçamento. Isto é feito escrevendo-se os 7 bits do endereço do escravo mais o bit R/W no registrador de dados da interface (IICAn).

De acordo com o estado do bit R/W a interface passa a operar como transmissora (se R/W=0) ou receptora (se R/W=1). A qualquer instante isto pode ser verificado através do bit TRC (registrador IICSn).

Microcontroladores RL78: Guia Básico 226

Após o envio de dados pelo transmissor deve verificar se a transmissão foi reconhecida pelo receptor (ACK). O estado do ACK pode ser lido através do bit ACKD no registrador IICSn.

Caso a transmissão tenha sido reconhecida o novo dado a ser transmitido deve ser escrito no registrador IICAn e após isso o bit ACKD deve ser verificado para determinar se houve reconhecimento ou não por parte do receptor.

A IICA inclui a facilidade de clock stretching, permitindo o controle de fluxo dos dados entre o transmissor e o receptor e que funciona da seguinte forma: o receptor, caso precise de tempo para processar os dados recebidos do transmissor, pode manter a linha de clock (SCL) em nível “0” após oitavo ou nono pulso de clock, desta forma o transmissor irá aguardar que a linha de clock retorne ao estado inativo, ou seja, que ela seja liberada pelo receptor, de forma a prosseguir com a comunicação.

Este sistema de controle de fluxo ou estado de espera está sempre ativo na IIAC e pode ser configurado para ocorrer após o oitavo ciclo de clock (no bit ACK) ou após o nono pulso de clock (após o bit ACK). Esta seleção é realizada através do bit WTIM no registrador IICCTLn0.

Quando a IICA está em estado de espera, ele é liberado de uma das seguintes formas:

• Através de uma escrita no registrador IICAn;

• Setando o bit de liberação de modo de espera (WREL) no registrador IICCTLn0;

• Pela geração de uma condição de partida ou de parada (apenas no modo mestre).

No caso de operação como recepção, cada byte recebido pela interface é armazenado no registrador IICAn e no nono pulso de clock um ACK é enviado de acordo com o estado do bit ACKE no registrador IICCTLn0.

A cada transferência completada (seja de transmissão ou de recepção) é gerado um evento de interrupção INTIICAn. O instante em que o sinal de interrupção é gerado (oitavo ou nono pulso de clock) irá depender da configuração do bit WTIM no registrador IICCTLn0.

Também é possível configurar a IICA para gerar uma interrupção ao detectar uma condição de parada no barramento, setando-se o bit SPIE no registrador IICCTLn0.

9.2.2. API Applilet

O Applilet3 oferece uma série de funções que podem ser utilizadas para implementar a comunicação serial síncrona utilizando uma das interfaces IICA disponíveis (a letra n especifica uma das unidades IICA):

• R_IICAn_Master_Send(uint8_t adr, uint8_t *txbuf, uint16_t txnum, uint8_t wait) – transmite “txnum” caracteres armazenados no buffer (array) indicado por “txbuf” para o escravo no endereço “adr”. O parâmetro “wait” especifica um tempo de espera para a geração da condição de partida. Esta função retorna imediatamente após a chamada (a função r_iican_callback_master_sendend é executada automaticamente quando a transmissão é completada). Esta função também realiza automaticamente a geração das condições de partida e de parada;

Periféricos de Comunicação 227

• R_IICAn_Master_Receive(uint8_t adr, uint8_t *rxbuf, uint16_t rxnum, uint8_t wait) – recebe um bloco de dados através da interface I2C armazenando-os no buffer especificado por “rxbuf” até que o número especificado por “rxnum” de caracteres sejam recebidos. O parâmetro “wait” especifica um tempo de espera para a geração da condição de partida. Esta função retorna imediatamente após a chamada (a função r_iican_callback_master_receiveend é executada automaticamente quando a recepção é completada). As condições de partida e de parada são geradas automaticamente;

• R_IICAn_StopCondition() – gera uma condição de parada no barramento I2C;

• R_IICAn_Slave_Send(uint8_t *txbuf, uint16_t txnum) – transmite para o mestre os “txnum” caracteres armazenados no buffer (array) indicado por “txbuf”. Esta função retorna imediatamente após a chamada (a função r_iican_callback_slave_sendend é executada automaticamente quando a transmissão é completada);

• R_IICAn_Slave_Receive(uint8_t *rxbuf, uint16_t rxnum) – recebe um bloco de dados através da interface I2C armazenando-os no buffer especificado por “rxbuf” até que o número especificado por “rxnum” de caracteres sejam recebidos. Esta função retorna imediatamente após a chamada (a função r_iican_callback_slave_receiveend é executada automaticamente quando a recepção é completada);

• R_IICAn_Stop() – para encerrar a comunicação da interface IICAn, a interrupção da interface também é desabilitada;

As funções de callback a seguir podem ser definidas pelo usuário (no arquivo r_cg_serial_user.c):

• r_iican_callback_master_sendend() – esta função é chamada automaticamente quando todos os dados do buffer de transmissão (especificado na função R_IICAn_Master_Send) foram transmitidos;

• r_iican_callback_master_receiveend() – esta função é chamada automaticamente quando o buffer de recepção (especificado na função R_IICAn_Master_Receive) está cheio;

• r_iican_callback_master_error(MD_STATUS flag) – esta função é chamada sempre que ocorre um erro na interface (uma detecção de condição de parada inesperada ou recepção de um NACK);

• r_iican_callback_slave_sendend() – esta função é chamada automaticamente quando todos os dados do buffer de transmissão (especificado na função R_IICAn_Slave_Send) foram transmitidos;

• r_iican_callback_slave_receiveend() – esta função é chamada automaticamente quando o buffer de recepção (especificado na função R_IICAn_Slave_Receive) está cheio;

• r_iican_callback_slave_error(MD_STATUS flag) – esta função é chamada sempre que ocorre um erro na interface (endereço inválido ou recepção de um NACK).

Microcontroladores RL78: Guia Básico 228

9.2.3. Registradores IICA

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura Dado recebido pela interface I2C

Escrita Dado a ser transmitido pela interface I2C IICAn

Reset 0 0 0 0 0 0 0 0

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita A6 A5 A4 A3 A2 A1 A0 0

SVAn

Reset 0 0 0 0 0 0 0 0

Este registrador armazena o endereço da interface IICA quando ela opera como escrava. O bit 0 deve ser mantido sempre apagado.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita IICEn LRELn WRELn SPIEn WTIMn ACKEn STTn SPTn

IICCTLn0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

IICEn Habilitação da operação I2C: 0 – desativa a interface 1 – ativa a interface bIICE

LRELn

Solicitação de encerramento de comunicação: 0 – nenhuma solicitação 1 – encerra a comunicação, coloca as linhas SCLA e SDAA em alta impedância e força a interface para modo standby, após a execução do comando este bit é apagado automaticamente

bLREL

WRELn

Solicitação de cancelamento de espera: 0 – nenhuma solicitação 1 – cancela um estado de espera. Após o cancelamento este bit é apagado automaticamente

bWREL

SPIEn Habilitação da interrupção de recepção de condição de parada: 0 – interrupção desabilitada 1 – interrupção habilitada

bSPIE

WTIMn

Controle da geração do tempo de espera (clock stretching) e da interrupção de transferência: 0 – interrupção gerada na borda de descida do oitavo pulso de clock, após o oitavo clock a condição de espera é ativada 1 – interrupção gerada na borda de descida do nono pulso de clock, após o nono clock a condição de espera é ativada

bWTIM

ACKEn

Controle de envio de reconhecimento (ACK ou NACK) na próxima transferência: 0 – envia NACK (não reconhecimento) 1 – envia ACK (reconhecimento)

bACKE

Periféricos de Comunicação 229

Nome do Bit Descrição Símbolo C

STTn

Disparo de condição de partida (START): 0 – não gera START 1 – Gera uma condição de partida (START) ou reinício (RESTART). Caso o barramento esteja ocupado por outro mestre, uma condição de partida somente será gerada após a liberação do barramento e caso a função de reserva de comunicação esteja ativada (IICRSVn=0)

bSTT

SPTn

Disparo de condição de parada (STOP): 0 – não gera STOP 1 – gera uma condição de parada, encerrando a transferência I2C. Este bit somente pode ser setado no modo mestre

bSPT

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura MSTSn ALDn EXCn COIn TRCn ACKDn STDn SPDn

Escrita - IICSn

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

MSTSn Indicador de modo de comunicação (mestre/escravo): 0 – modo escravo ou em standby 1 – modo mestre

bMSTS

ALDn Indicador de perda de arbitragem de barramento: 0 – não ocorreu perda de arbitragem 1 – o mestre perdeu a arbitragem e passou para modo escravo (MSTS=0)

bALD

EXCn Indicador de recepção de código de extensão: 0 – nenhum código de extensão recebido 1 – código de extensão recebido

bEXC

COIn

Indicador de detecção de endereçamento do escravo (quando a interface I2C operando em modo escravo é endereçada por um mestre externo): 0 – não houve detecção de endereçamento 1 – a interface foi endereçada por um mestre externo

bCOI

TRCn Indicador de estado de transmissão ou recepção: 0 – modo de recepção 1 – modo de transmissão

bTRC

ACKDn Indicador de reconhecimento (ACK ou NACK): 0 – foi recebido um NACK 1 – foi recebido um ACK

bACKD

STDn Indicador de condição de partida (START): 0 – nenhuma partida foi detectada 1 – condição de partida detectada, transferência em andamento

bSTD

SPDn

Indicador de condição de parada (STOP): 0 – nenhuma parada foi detectada 1 – condição de parada detectada, transferência completada, o barramento é liberado

bSPD

Microcontroladores RL78: Guia Básico 230

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura STCFn IICBSYn

Escrita - - 0 0 0 0 STCENn IICRSVn

IICFn

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

STCFn Indicador de geração da condição de partida (START): 0 – condição de partida gerada com sucesso (STTn = 1) 1 – condição de partida não foi gerada (STTn = 0)

bSTCF

IICBSYn Indicador de estado do barramento I2C: 0 – barramento liberado 1 – barramento ocupado

bIICBSY

STCENn

Disparo da habilitação inicial da interface após a habilitação da mesma (IICEn = 1): 0 – permite gerar uma condição de partida após detectar uma condição de parada 1 – permite gerar uma condição de partida sem detectar uma condição de parada

bSTCEN

IICRSVn Controle de desabilitação da função de reserva de comunicação: 0 – reserva de comunicação habilitada 1 – reserva de comunicação desabilitada

bIICRSV

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita WUPn 0 CLDn DADn SMCn DFCn 0 PRSn

IICCTLn1

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

WUPn Controle da detecção de endereçamento em modo stop: 0 – detecção de endereçamento desabilitada em modo stop 1 – detecção de endereçamento habilitada em modo stop

bWUP

CLDn Indicador de estado do pino SCLAn (somente quando IICEn=1): 0 – pino em nível baixo 1 – pino em nível alto

bCLD

DADn Indicador de estado do pino SDAAn (somente quando IICEn=1): 0 – pino em nível baixo 1 – pino em nível alto

bDAD

SMCn Seleção do modo de operação: 0 – padrão (até 100kbps) 1 – alta velocidade (até 1Mbps)

bSMC

DFCn Controle do filtro digital: 0 – filtro desligado 1 – filtro ligado

bDFC

PRSn Seleção do clock de operação: 0 – fCLK 1 – fCLK/2 (clock acima de 20MHz)

bPRS

Periféricos de Comunicação 231

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita Configuração do ciclo inativo do clock SCLAn

IICCWLn

Reset 1 1 1 1 1 1 1 1

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita Configuração do ciclo ativo do clock SCLAn

IICCWHn

Reset 1 1 1 1 1 1 1 1

Microcontroladores RL78: Guia Básico 232

Tópicos Avançados 233

10

Tópicos Avançados 10. Tópicos Avançados

Neste capítulo iremos estudar algumas funcionalidades avançadas dos RL78 tais como o ajuste BCD, sistemas de segurança e de proteção de memória, hardware de multiplicação e divisão, gravação e apagamento da memória flash e dataflash e módulo de acesso direto a memória (DMA). No final do capítulo também são abordadas algumas técnicas de programação voltadas aos RL78.

10.1. Ajuste BCD

O sistema de ajuste BCD consiste numa pequeno bloco de hardware encarregado de corrigir o resultado de uma operação de adição ou subtração envolvendo dados codificados em BCD (Binary Coded Decimal).

Caso o leitor não se recorde, BCD é uma técnica de representação que utiliza apenas os dígitos decimais para codificação em binário. Assim, utilizando a representação hexadecimal natural, um byte pode representar valores entre 0x00 e 0xFF, num total de 256 combinações. Utilizando BCD temos apenas as codificações de 0x00 a 0x99 e cada grupo de quatro dígitos binários (um nibble) representa uma posição decimal. Desta forma, o número 0x19 se codificado em BCD irá representar o número 19 decimal e o incremento dele deve resultar em 0x20 (o equivalente BCD a 20 decimal).

O problema com a codificação BCD é que, apesar de ela ser natural para o ser humano, não é natural para os computadores digitais. Assim, numa CPU digital como a do RL78, a adição de 1 ao valor 0x19 irá sempre resultar em 0x1A, que não é um número BCD válido.

Para contornar isso a Renesas incluiu um pequeno circuito de correção BCD que atua com o registrador A e os flags CY e AC (registrador PSW) produzindo um resultado no registrador BCDADJ que consiste no valor de A ajustado para BCD conforme o estado dos flags CY e AC.

A utilização do ajuste BCD em linguagem assembly é muito simples. No exemplo citado (0x19 + 1), o código seria o seguinte:

MOV A,#0x19 ; A = 0x19

ADD A,#1 ; A = 0x1A

ADD A,!BCDADJ ; A = 0x20

Infelizmente não há uma forma simples de utilizar o ajuste BCD em linguagem C, já que não há como garantir que uma determinada variável seja armazenada no registrador A da CPU, por isso, é sempre necessário utilizar código assembly.

Microcontroladores RL78: Guia Básico 234

O exemplo a seguir demonstra como utilizar instruções assembly dentro de um programa em C para implementar uma adição BCD. Observe que este programa deve ser testado diretamente no hardware já que o simulador (ao menos no EWRL78 versão 1.10) não implementa o circuito de ajuste BCD. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

volatile unsigned char va_BCD, vb_BCD;

unsigned char bcd_add(unsigned char va, unsigned char vb)

__asm("ADD A,B");

__asm("ADD A,0xF00FE"); // 0xF00FE é o endereço do registrador BCDADJ

unsigned char bcd_sub(unsigned char va, unsigned char vb)

__asm("SUB A,B");

__asm("SUB A,0xF00FE"); // 0xF00FE é o endereço do registrador BCDADJ

void main(void)

va_BCD = 0x19;

vb_BCD = bcd_add(va_BCD,1); // vb_BCD = 0x20

va_BCD = 0x32;

vb_BCD = bcd_sub(va_BCD,3); // vb_BCD = 0x29

while (1);

Exemplo 10.1

10.2. Funções de Segurança

Aplicações microcontroladas estão sujeitas a falhas: interferências causadas por ruídos elétricos ou campos elétricos intensos podem provocar alterações indesejadas no conteúdo das memórias e registradores, causando, em alguns casos, falhas que podem ser catastróficas (como em aplicações aeroespaciais, automotivas relacionadas a sistemas de segurança tais como: airbags, ABS, controle do motor, câmbio, etc.).

Tópicos Avançados 235

A Comissão Eletrotécnica Internacional (IEC) criou alguns padrões (IEC60335, IEC60730 e IEC61508) que estabelecem conjuntos de testes e algoritmos de detecção de falhas que podem evitar que falhas de software ou hardware afetem a aplicação de forma a causar danos sérios ou prejuízos a vida. A Associação para Confiabilidade de Software na Indústria Automotiva (MISRA) também definiu uma série de regras (MISRA-C) que devem ser seguidas para garantir maior confiabilidade às aplicações envolvendo software automotivo (inclusive disponível dentro do ambiente EWRL78 da IAR).

Os microcontroladores RL78 incluem uma série de facilidades de hardware que permitem garantir a correta operação da aplicação e o atendimento aos padrões IEC, são elas:

• Checagem de CRC da memória flash: para detecção de falhas na memória flash;

• Checagem de paridade da memória RAM: para detecção de erros simples na área da RAM;

• Sistema de guarda: evita alterações indevidas em registradores chave do microcontrolador;

• Execução de opcode ilegal: detecta a tentativa de executar uma instrução não implementada;

• Acesso ilegal à memória: detecta acessos a áreas de memória inválidas ou não permitidas;

• Verificação do ADC e do Clock: permite detectar se estes módulos estão operando dentro das especificações da aplicação.

Alguns outros testes especificados nos padrões IEC60730 e IEC61508 são implementados inteiramente por software. A Renesas possui uma nota de aplicação que detalha as funções de uma biblioteca de auto teste específica para a norma IEC60730. A AN0749 demonstra a implementação de diversos testes e a utilização do hardware de segurança interno no suporte de segurança da aplicação.

10.2.1. Checagem de CRC da Flash

A checagem de CRC da memória flash utiliza um circuito de alta velocidade (high speed CRC) que realiza o cálculo do CRC (polinomial CRC16 do CCITT) a uma taxa de 32 bits por ciclo de clock. Isto permite que o cálculo do CRC de uma área de 64KiB de memória (como no R5F100LE utilizado na maioria dos exemplos deste livro) seja completado em 512µs (quando operando com um clock de 32MHz).

A utilização desta facilidade é muito simples:

1. A aplicação deve habilitar o módulo (bit CRC0EN) e configurar a faixa de endereços a ser verificada (registrador CRC0CTL);

2. Em seguida é necessário inicializar o registrador PGCRCL com o valor 0x0000;

3. O CRC inicia a sua operação quando a instrução HALT é executada (na RAM);

4. A CPU permanece no modo halt enquanto o cálculo do CRC estiver em andamento, ao término do mesmo a CPU é acordada automaticamente e o valor final do CRC pode ser lido no registrador PGCRCL.

Microcontroladores RL78: Guia Básico 236

Normalmente o resultado do cálculo do CRC deverá ser comparado com um valor previamente armazenado (o CRC calculado previamente para a mesma área de memória) e caso o resultado seja diferente, a aplicação deve entrar em um estado de erro.

Atenção: a instrução HALT deve ser executada na memória RAM! Isso pode ser feito através de um pequeno código (HALT seguido por RET) que deve ser colocado armazenado na RAM e chamado através de uma instrução CALL (ou CALLT). Além disso, caso a depuração esteja ativada, o resultado do CRC será diferente daquele feito com a depuração desativada.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita CRC0EN 0 FEA5 FEA4 FEA3 FEA2 FEA1 FEA0

CRC0CTL

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

CRC0EN Controle de operação da checagem de CRC da memória flash: 0 – checagem desativada 1 – checagem ativada (durante a execução da instrução HALT)

bCRC0EN

FEA5 FEA4 FEA3 FEA2 FEA1 FEA0

Seleção da faixa de endereços da checagem de CRC. A faixa de endereços vai de 0x00000 até o endereço final determinado pela fórmula: END_FINAL=16379+16384*FEA Assim, quando FEA = 4, o endereço final será igual a 81915 ou 0x13FFB. O maior valor para o campo FEA é 31 (para um chip com 512KiB de memória)

-

10.2.2. Checagem de Paridade da RAM

Os microcontroladores RL78 incluem um bit de paridade para cada byte de memória RAM, ou seja, toda a memória RAM destes chips é dotada de um nono bit de paridade. Esta característica é bastante incomum e raramente vista em microcontroladores do mesmo nível do RL78.

A verificação de paridade encontra-se sempre ativa e pode ser verificada através do bit RPEF no registrador RPECTL, caso ocorra um erro de paridade o microcontrolador é automaticamente ressetado. Opcionalmente, é possível desabilitar o reset por erro de paridade, para isso, basta setar o bit RPERDIS no registrador RPECTL.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita RPERDIS 0 0 0 0 0 0 RPEF

RPECTL

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

RPERDIS Mascaramento do reset por erro de paridade da RAM: 0 – reset por erro de paridade habilitado 1 – reset por erro de paridade desabilitado

bRPERDIS

RPEF Indicador de erro de paridade da RAM: 0 – nenhum erro de paridade 1 – foi detectado um erro de paridade

bRPEF

Tópicos Avançados 237

10.2.3. Bloqueio de Registradores e da RAM

Outra característica importante acerca da segurança dos microcontroladores RL78 é a possibilidade de bloquear a alteração (proteção contra escrita) de grupos de registradores SFR e áreas da RAM, evitando desta forma que, uma aplicação em estado anômalo de execução, possa alterar inadvertidamente registradores ou áreas importantes de memória.

Esta funcionalidade é controlada pelos bits GRAM1, GRAM0, GPORT, GINT e GCSC do registrador IAWCTL.

Os bits GRAM1 e GRAM0 controlam o bloqueio da RAM. Até 512 bytes da RAM podem ser protegidos contra escrita (sempre contando-se do endereço mais baixo para o mais alto).

O bit GPORT permite proteger contra escrita os registradores associados às portas de E/S: PMxx, PUxx, PIMxx, POMxx, PMCxx, ADPC e PIOR. Note que os registradores de leitura e escrita nas portas (Pxx) não são protegidos por esta função e continuam podendo ser lidos ou escritos livremente.

O bit GINT permite proteger contra escrita os registradores associados ao sistema de interrupção: IFxx, MKxx, PRxx, EGPx e EGNx.

O bit GCSC permite proteger contra escrita os registradores associados ao sistema de clock: CMC, CSC, PSTS, CKC, PERx, OSMC, LVIM, LVIS e RPECTL.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura IAWEN

Escrita 1 0 GRAM1 GRAM0 0 GPORT GINT GCSC

IAWCTL

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

IAWEN

Controle de reset por acesso a área de memória inválida: 0 – reset desabilitado 1 – reset habilitado Uma vez setado, este bit não pode ser apagado por software! Escrever “0” no mesmo não produz efeito.

bIAWEN

Proteção contra a escrita na RAM (RAM Guard):

00 – RAM Guard desabilitada, toda a RAM pode ser escrita RAMGUARD_DIS

01 – primeiros 128 bytes da RAM protegidos RAMGUARD_128

10 – primeiros 256 bytes da RAM protegidos RAMGUARD_256

GRAM1

GRAM0

11 – primeiros 512 bytes da RAM protegidos RAMGUARD_512

GPORT

Proteção contra a escrita nos SFRs das portas (PMxx, PUxx, PIMxx, POMxx, PMCxx, ADPC e PIOR): 0 – proteção desabilitada, SFRs pode ser escritos livremente 1 – proteção contra escrita ativada nos SFRs

bGPORT

GINT

Proteção contra a escrita nos SFRs de interrupção (IFxx, MKxx, PRxx, EGPx e EGNx): 0 – proteção desabilitada, SFRs pode ser escritos livremente 1 – proteção contra escrita ativada nos SFRs

bGINT

GCSC

Proteção contra a escrita nos SFRs do sistema de clock, LVD e controle de paridade da RAM (CMC, CSC, PSTS, CKC, PERx, OSMC, LVIM, LVIS e RPECTL): 0 – proteção desabilitada, SFRs pode ser escritos livremente 1 – proteção contra escrita ativada nos SFRs

bGCSC

Microcontroladores RL78: Guia Básico 238

10.2.4. Execução de Opcode Ilegal (Trap)

Outro mecanismo de proteção existente nos RL78 é o reset por execução de opcode ilegal. O único opcode não implementado nos RL78 é o de código hexadecimal 0xFF, assim, caso a CPU tente executar uma instrução cujo primeiro byte é iniciado por este valor, um reset será gerado e o bit TRAP no registrador RESF será setado.

10.2.5. Acesso Ilegal à Memória (IAW)

Também é possível configurar o RL78 para gerar um reset caso a CPU tente fazer um acesso a área de memória não implementada ou de acesso não permitido.

No RL78, considera-se um acesso não permitido a tentativa de executar instruções na área de registradores SFR ou dataflash, além da tentativa de escrita na área de dataflash ou flash de programa. As áreas não implementadas são aquelas marcadas como “reservadas” na figura 3.1. Qualquer acesso (leitura ou escrita) a áreas não implementadas irá provocar um reset IAW.

O reset IAW deve ser habilitado por software, escrevendo-se “1” no bit IAWEN do registrador IAWCTL. Uma vez habilitado, não é possível desabilitar o reset IAW por software!

10.2.6. Verificação do A/D

O conversor A/D dos RL78 possui um registrador especial destinado a realização de testes. Através do registrador ADTES, é possível configurar o conversor para realizar conversões utilizando como entrada a tensão de referência externa positiva (AVREFP) ou negativa (AVREFM).

Quando os bits ADTES1=1 e ADTES0=0 no registrador ADTES, o conversor irá converter a entrada AVREFM. Neste caso, se o conversor estiver operando corretamente, o resultado deverá ser igual a zero.

Quando os bits ADTES1=1 e ADTES0=1 no registrador ADTES, o conversor irá converter a entrada AVREFP. Neste caso, se o conversor estiver operando corretamente, o resultado deverá ser igual a 0xFF (modo de 8 bits) ou 0x3FF (modo de 10 bits).

10.2.7. Verificação do Clock

É possível utilizar o canal 5 da TAU0 para efetuar a medição do período do sinal do oscilador LOCO (15kHz) ou do oscilador XT1 (32768Hz). Desta forma a aplicação pode determinar se o clock principal (seja ele derivado do oscilador interno HOCO ou do oscilador externo X1) está dentro ou fora de uma faixa de valores aceitáveis.

Tópicos Avançados 239

Para fazer esta medição, basta configurar o canal 5 da TAU0 para operar no modo de medição de período e utilizar o registrador TIS0 para selecionar o LOCO ou o XT1 como fonte de sinal para o canal.

Caso seja utilizado o LOCO (15kHz) como fonte de sinal do canal, lembre-se de que este oscilador possui uma baixa precisão (±15%) e, portanto, a aplicação deverá tolerar variações de medição incluindo este valor e mais a tolerância do oscilador principal (HOCO ou X1).

É possível realizar a calibração do oscilador HOCO utilizando-se o oscilador externo XT1 como fonte de clock do canal. Através do valor medido para o período de XT1 a aplicação pode determinar o erro do oscilador HOCO e atuar sobre o registrador HIOTRM de forma que o valor medido se aproxime o máximo possível do valor calculado.

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita 0 0 0 0 0 TIS02 TIS01 TIS00

TIS0

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C

TIS02 TIS01 TIS00

Seleção da entrada de clock externo do canal 5 da TAU0: 000 – Pino TI05 001 – Pino TI05 010 – Pino TI05 011 – Pino TI05 100 – Oscilador LOCO (15kHz) 101 – Oscilador XT1

TIS_TI05

- - -

TIS_LOCO TIS_XT1

10.3. CRC de Uso Geral

Os microcontroladores da linha G13 incluem um circuito de cálculo de CRC (checagem de redundância cíclica) que pode ser utilizado para calcular CRC (16 bits com polinomial CCITT) de maneira simples e rápida.

A utilização do módulo CRC é bastante simples: basta inicializar o registrador de dados do CRC (CRCD) com o valor 0x0000, em seguida, utiliza-se o registrador CRCIN para inserir os dados de 16 bits com os quais deseja-se calcular o CRC, após isso, basta ler o valor do CRC no registrador CRCD.

A seguir temos um pequeno fragmento de programa que demonstra o cálculo do CRC dos valores 0x12, 0x34 e 0x56:

CRCD = 0;

CRCIN = 0x12;

CRCIN = 0x34;

CRCIN = 0x56;

crc_final = CRCD;

Microcontroladores RL78: Guia Básico 240

10.4. Gravação e Apagamento da Flash e DataFlash

Os microcontroladores RL78 incluem os circuitos internos necessários para gravação e apagamento da memória flash de programa e de dados. A utilização desta funcionalidade se dá através do uso de bibliotecas especiais de software fornecidas pelo fabricante.

Estão disponíveis três bibliotecas, que deve ser utilizadas de acordo com o tipo de memória (flash ou dataflash) e o tipo de uso (dados ou programa):

FSL – Flash Self-programming Library, utilizada para apagamento e programação da memória flash de programa;

FDL – Flash Data Library, utilizada para apagamento e programação da memória dataflash (utilizada exclusivamente para dados não voláteis);

EEL – EEPROM Emulation Library, utilizada para emulação de EEPROM na memória dataflash.

Cada uma destas bibliotecas possui uma API (Application Programming Interface) composta de uma série de funções C utilizadas para inicialização, apagamento, programação e controle da memória.

10.4.1. FSL

A biblioteca FSL pode ser utilizada para apagamento e programação da área de memória flash de programa. Ela pode ser utilizada tanto por bootloaders (programas especiais que permitem apagar e reprogramar a memória flash com outras aplicações) quanto para armazenamento de grandes quantidades de dados não voláteis.

A desvantagem do uso da memória de programa para o armazenamento de dados não voláteis é que ela possui uma menor capacidade de ciclos de apagamento/gravação (um mínimo de 1.000 ciclos para retenção de 20 anos, enquanto a dataflash apresenta uma capacidade de 10.000 ciclos para o mesmo tempo de retenção).

A tabela a seguir apresenta as principais características da FSL (o tamanho da FSL na memória flash depende das funções utilizadas).

Tamanho da FSL

Flash (bytes)

Buffer na RAM (bytes)

Pilha (bytes) Capacidades

Mínimo 570 5 a 256 56 Básicas: apagamento, gravação, verificação e proteção de área

Médio 870 5 a 256 56 Todas, exceto as relacionadas ao bloco duplo de boot Completo 1.350 5 a 256 56 Todas

Tabela 10.1

Nos RL78 a memória flash somente pode ser apagada em blocos, cada um com tamanho de 1024 bytes. A figura 3.2 mostra a organização dos blocos de memória flash. O tempo mínimo de apagamento de um bloco é de 4.880 ciclos de clock mais 163µs (cerca de 5,04ms com clock de 1MHz ou 315µs com clock de 32MHz). O tempo máximo é de 73.342 ciclos de clock mais 255.366µs (cerca de 328,71ms com clock de 1MHz ou 257,66ms com clock de 32MHz).

Tópicos Avançados 241

No tocante a gravação, em razão da disposição dos barramentos internos da memória flash, somente é possível gravar palavras de 32 bits (4 bytes) de cada vez. O tempo máximo de gravação de uma palavra de 32 bits é de 4.283 ciclos de clock mais 627µs (cerca de 4,91ms com clock de 1MHz ou 760,84µs com clock de 32MHz). No caso de palavras posteriores gravadas dentro do mesmo ciclo de gravação, o tempo máximo de gravação é de 1153 ciclos de clock mais 561µs (cerca de 1,72ms com clock de 1MHz ou 597µs com clock de 32MHz).

A biblioteca FSL pode operar de duas formas: checagem de status automática ou checagem de status pelo usuário.

Na checagem de status automática (SCI) a chamada a uma função FSL somente retorna após a execução completa do comando, ou seja, enquanto o comando é executado a aplicação permanece parada.

Na checagem de status pelo usuário (SCU), a chamada a uma função FSL retorna imediatamente e a FSL opera no chamado modo background (segundo plano). Neste caso, a verificação do status cabe a aplicação (através da função FSL_StatusCheck). Note que neste modo a FSL deve ser executada em RAM o que faz com que a ocupação de RAM, pelo programa, seja maior.

A API da FSL define algumas estruturas e tipos de dados utilizados pelas mesmas. A seguir apresentamos as principais funções e os seus tempos de execução máximos no modo de checagem de status automática.

FSL_Init(const __far fsl_descriptor_t __far* descriptor_pstr) – inicializa a FSL conforme o descritor passado como parâmetro. O descritor é uma estrutura composta de três campos:

fsl_flash_voltage_u08: especifica a faixa de tensões no qual a flash vai operar. Pode assumir dois valores: 0 – operação em alta velocidade (tensões de 3 a 5,5V); outros valores – operação em ampla faixa de tensão. fsl_frequency_u08 – seleção da frequência de operação do chip (cada unidade vale 1MHz). Para 32MHz o valor deve ser 32, para 20MHz o valor deve ser 20 e assim por diante. A FSL não suporta operação abaixo de 1MHz! fsl_auto_status_check_u08 – seleção do modo de operação da FSL. Pode assumir dois valores: 0 – checagem pelo usuário (funções retornam imediatamente) Outros valores – checagem interna (funções retornam somente após a execução)

Esta função retorna um dado do tipo fsl_u08: 0 – FSL inicializada (símbolo FSL_OK); 5 – erro de parâmetro (símbolo FSL_ERR_PARAMETER);

Tempo de execução: 5021 ciclos de clock.

FSL_Open() – inicia uma sessão FSL. Esta função somente pode ser executada após a FSL estar inicializada corretamente. Tempo de execução: 10 ciclos de clock.

FSL_Close() – encerra uma sessão FSL. Tempo de execução: 10 ciclos de clock.

Microcontroladores RL78: Guia Básico 242

FSL_PrepareFunctions() – ativa as funções básicas da FSL (FSL_BlankCheck, FSL_Erase, FSL_Write, FSL_IVerify, FSL_StatusCheck, FSL_StandBy e FSL_WakeUp). Esta função somente pode ser chamada dentro de uma sessão FSL já aberta por FSL_Open(). Somente após a sua execução é que as funções mencionadas podem ser executadas. Tempo de execução: 2465 ciclos de clock.

FSL_BlankCheck(fsl_u16 block_u16) – verifica se o bloco especificado está apagado.

block_u16: especifica um bloco de 1024 bytes da memória (começando do endereço 0).

Esta função retorna um dado do tipo fsl_u08: 0 – FSL inicializada (símbolo FSL_OK); 0x05 – erro de parâmetro (símbolo FSL_ERR_PARAMETER); 0x1A – erro de apagamento (símbolo FSL_ERR_ERASE); 0x1B – erro de verificação de apagamento (símbolo FSL_ERR_BLANKCHECK); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW); 0xFF – FSL ocupada, comando em execução (símbolo FSL_BUSY).

Tempo de execução: 4844 ciclos de clock + 164µs.

FSL_IVerify(fsl_u16 block_u16) – verifica o estado do bloco especificado (verificação interna da FSL com o objetivo de determinar se as células de memória estão gravadas de forma a atingir a máxima retenção de dados).

block_u16: especifica um bloco de 1024 bytes da memória (começando do endereço 0).

Esta função retorna um dado do tipo fsl_u08: 0 – bloco apagado e com retenção máxima garantida (símbolo FSL_OK); 0x05 – erro de parâmetro (símbolo FSL_ERR_PARAMETER); 0x1B – erro de verificação (símbolo FSL_ERR_IVERIFY); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW); 0xFF – FSL ocupada, comando em execução (símbolo FSL_BUSY).

Tempo de execução: 10476 ciclos de clock + 1107µs.

FSL_Erase(fsl_u16 block_u16) – apaga o bloco de memória especificado.

block_u16: especifica um bloco de 1024 bytes da memória (começando do endereço 0).

Esta função retorna um dado do tipo fsl_u08: 0 – bloco apagado (símbolo FSL_OK); 0x05 – erro de parâmetro (símbolo FSL_ERR_PARAMETER); 0x10 – bloco protegido, apagamento não permitido (símbolo FSL_ERR_PROTECTION) 0x1A – erro de apagamento (símbolo FSL_ERR_ERASE); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW); 0xFF – FSL ocupada, comando em execução (símbolo FSL_BUSY).

Tempo de execução: 73342 ciclos de clock + 255366µs.

Tópicos Avançados 243

FSL_Write(__near fsl_write_t __near* write_pstr) – escreve palavras (32 bits) no endereço especificado. Os parâmetros da função são passados através de uma estrutura contendo os seguintes campos:

fsl_data_buffer_p_u08: ponteiro para o buffer (array) contendo os dados a serem escritos; fsl_destination_address_u32: endereço da flash onde os dados devem ser escritos (deve ser um múltiplo de 4); fsl_word_count_u08: número de palavras (32 bits) a serem escritas (1 a 256).

Esta função retorna um dado do tipo fsl_u08: 0 – dados gravados (símbolo FSL_OK); 0x05 – erro de parâmetro (símbolo FSL_ERR_PARAMETER); 0x10 – bloco protegido, gravação não permitida (símbolo FSL_ERR _PROTECTION) 0x1C – erro de gravação (símbolo FSL_ERR_WRITE); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW); 0xFF – FSL ocupada, comando em execução (símbolo FSL_BUSY).

Tempo de execução: 3130 ciclos de clock+66µs+(1153 ciclos+561µs)*número de palavras.

FSL_StatusCheck() – retorna o status de execução de um comando (especialmente útil no modo de checagem de status pelo usuário).

Esta função retorna um dado do tipo fsl_u08: 0 – FSL inicializada (símbolo FSL_OK); 0x1A – erro de apagamento (símbolo FSL_ERR_ERASE); 0x1B – erro de verificação de apagamento (símbolo FSL_ERR_BLANKCHECK); 0x1C – erro de escrita (símbolo FSL_ERR_WRITE); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW); 0x30 – nenhum comando em execução (símbolo FSL_ERR_IDLE); 0xFF – FSL ocupada com um comando em execução (símbolo FSL_BUSY).

Tempo de execução: veja documentação da FSL.

FSL_StandBy() – suspende um comando em execução (escrita, apagamento, etc.). Esta função somente pode ser utilizada no modo de checagem de status pelo usuário.

Esta função retorna um dado do tipo fsl_u08: 0 – comando suspenso corretamente (símbolo FSL_OK); 0x1A – apagamento suspenso com erro (símbolo FSL_ERR_ERASE); 0x1B – verificação de apagamento suspensa com erro (símbolo FSL_ERR_BLANKCHECK); 0x1C – escrita suspensa com erro (símbolo FSL_ERR_WRITE); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW); 0x30 – nenhum comando em execução (símbolo FSL_ERR_IDLE); 0x43 – comando já suspenso (símbolo FSL_SUSPEND).

Tempo de execução: veja documentação da FSL.

Microcontroladores RL78: Guia Básico 244

FSL_WakeUp() – resume um comando previamente suspenso por FSL_StandBy. Esta função somente pode ser utilizada no modo de checagem de status pelo usuário.

Esta função retorna um dado do tipo fsl_u08: 0 – comando resumido e executado com sucesso (símbolo FSL_OK); 0x1A – apagamento resumido com erro (símbolo FSL_ERR_ERASE); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW); 0xFF – comando resumido em execução (símbolo FSL_BUSY).

Tempo de execução: veja documentação da FSL.

FSL_PrepareExtFunctions() – ativa as funções estendidas da FSL (FSL_SetXXXProtectFlag, FSL_InvertBootFlag, FSL_SetFlashShieldWindow, FSL_SwapBootCluster e FSL_SwapActiveBootCluster) além das funções básicas de FSL_PrepareFunctions(). Esta função somente pode ser chamada dentro de uma sessão FSL já aberta por FSL_Open(). Somente após a sua execução é que as funções mencionadas podem ser executadas. Tempo de execução: 1221 ciclos de clock.

FSL_GetBlockEndAddr(__near fsl_getblockendaddr_t* getblockendaddr_pstr) – retorna o último endereço do bloco especificado. Os parâmetros da função são passados através de uma estrutura contendo os seguintes campos:

fsl_destination_address_u32: após a execução da função, este parâmetro irá conter o último endereço do bloco especificado; fsl_block_u16: contém o número do bloco a ser pesquisado.

Esta função retorna um dado do tipo fsl_u08: 0 – comando executado com sucesso (símbolo FSL_OK); 0x05 – erro de parâmetro (símbolo FSL_ERR_PARAMETER); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW).

Tempo de execução: 368 ciclos de clock.

FSL_GetFlashShieldWindow(__near fsl_fsw_t __near* getfsw_pstr) – retorna o bloco inícial e final da área de janela da flash. Os parâmetros da função são passados através de uma estrutura contendo os seguintes campos:

fsl_start_block_u16: número do primeiro bloco da área de janela da flash; fsl_end_block_u16: número do último bloco da área de janela da flash.

Esta função retorna um dado do tipo fsl_u08: 0 – comando executado com sucesso (símbolo FSL_OK); 0x05 – erro de parâmetro (símbolo FSL_ERR_PARAMETER); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW).

Tempo de execução: 307 ciclos de clock.

Tópicos Avançados 245

FSL_SetFlashShieldWindow(__near fsl_fsw_t __near* getfsw_pstr) – configura o bloco inicial e final da área de janela da flash. Os parâmetros da função são passados através de uma estrutura contendo os seguintes campos:

fsl_start_block_u16: número do primeiro bloco da área de janela da flash; fsl_end_block_u16: número do último bloco da área de janela da flash.

Esta função retorna um dado do tipo fsl_u08: 0 – comando executado com sucesso (símbolo FSL_OK); 0x05 – erro de parâmetro (símbolo FSL_ERR_PARAMETER); 0x1F – erro de fluxo (símbolo FSL_ERR_FLOW).

Tempo de execução: veja documentação da FSL.

10.4.1.1. Utilização da FSL

Para utilizar a FSL em uma aplicação é necessário primeiramente baixar o instalador da biblioteca, disponível no site da Renesas: www.renesas.com.

O instalador irá apresentar uma janela na qual o programador deverá selecionar o microcontrolador e o compilador utilizado para desenvolver a aplicação (figura 10.1).

Figura 10.1

O instalador irá gerar uma pasta no local selecionado. Esta pasta irá conter duas subpastas:

Lib – com os arquivos da biblioteca FSL que devem ser incluídos no projeto (fsl.h, fsl_types.h e fsl.r87);

Smp – com dois arquivos de configuração do linker. Estes arquivos devem ser utilizados como base, substituindo o arquivo de configuração do linker no projeto. Observe que apenas um dos arquivos deve ser utilizado. A seleção deverá considerar o modo de operação da FSL: caso seja utilizada a checagem de status interna, seleciona-se o arquivo de linker fsl_sample_linker_file_SCI.xcl e caso seja utilizada a checagem de status pelo usuário, seleciona-se o arquivo de linker fsl_sample_linker_file_SCU.xcl.

Observe que o arquivo de configuração do linker irá conter uma seção destinada aos segmentos de memória necessários para a operação da FSL (neles são armazenadas as funções da API da FSL). A seguir temos um trecho do arquivo gerado para o R5F100LE:

Microcontroladores RL78: Guia Básico 246

// FSL

// ============

-Z(CODE)FSL_FCD=[2800-FFFF]/10000

-Z(CODE)FSL_FECD=[2800-FFFF]/10000

-Z(CODE)FSL_BCD=[2800-FFFF]/10000

-Z(CODE)FSL_BECD=[2800-FFFF]/10000

-Z(CODE)FSL_RCD=[2000-FFFF]/10000

Conforme a aplicação pode ser necessário modificar a área destinada ao armazenamento da FSL e da aplicação.

A seguir apresentamos um exemplo de utilização da FSL. Trata-se uma aplicação simples que memoriza (na flash do chip) o último estado do led (aceso ou apagado), desta forma, ao se desligar e religar a placa, o estado do led é mantido.

Este exemplo também demonstra como configurar o linker de forma a criar uma área dedicada ao armazenamento de dados não voláteis na memória de programa.

Note que o arquivo fsl.r87 deve ser incluído dentro do projeto, pois ele contém o código compilado da biblioteca FSL. Para inserir o arquivo no projeto clique no menu principal: Projects > Add files, selecione a pasta do projeto, em tipo de arquivos selecione “Library/Object files” e então selecione e adicione o arquivo fsl.r87.

A figura 10.2 mostra a aparência que o projeto deve ter após a inclusão do arquivo.

O arquivo do linker (fsl_sample_linker_ file_SCI.xcl) deverá ser selecionado na janela de opções do projeto, categoria “linker”, aba “config”, conforme mostra a figura 10.3.

Figura 10.2

Figura 10.3

Tópicos Avançados 247

Neste exemplo precisamos armazenar apenas o estado do led (ligado ou desligado), o que significa apenas um bit de informação. No entanto, devido ao fato de que o menor bloco de memória apagável no RL78 é de 1024 bytes, seremos obrigados a reservar todo um bloco de 1024 bytes de memória de programa para armazenar o estado do led.

Este bloco de memória deverá ser incluído no arquivo de configuração do linker, assim, utilizando como base o arquivo fsl_sample_linker_file_SCI.xcl gerado pelo instalador da FSL, faremos as modificações mostradas em negrito, conforme a seguir: -Z(FARCONST)FAR_ID=02FFF-FBFF -Z(FARDATA)FAR_I=FF700-FFEDF

// FSL

// ============

-Z(CODE)FSL_FCD=[2800-FBFF]/10000 -Z(CODE)FSL_FECD=[2800-FBFF]/10000 -Z(CODE)FSL_BCD=[2800-FBFF]/10000 -Z(CODE)FSL_BECD=[2800-FBFF]/10000 -Z(CODE)FSL_RCD=[2000-FBFF]/10000

//---------------------------------------------------------------------

// Startup, Runtime-library, Near, Interrupt

// and CALLT functions code segment.

//---------------------------------------------------------------------

-Z(CODE)RCODE,CODE=01000-FBFF -Z(DATA)FLASH_DATA=FBFF-FFFF

//---------------------------------------------------------------------

// Far functions code segment.

//---------------------------------------------------------------------

-Z(CODE)XCODE=[01000-FBFF]/10000

//---------------------------------------------------------------------

// Data initializer segments.

//---------------------------------------------------------------------

-Z(CONST)NEAR_ID=[02000-FBFF]/10000 -Z(CONST)SADDR_ID=[02000-FBFF]/10000 -Z(CONST)DIFUNCT=[02000-FBFF]/10000

//---------------------------------------------------------------------

// Constant segments

//---------------------------------------------------------------------

-Z(CONST)NEAR_CONST=_NEAR_CONST_LOCATION_START-_NEAR_CONST_LOCATION_END

-P(CONST)FAR_CONST=[02000-FBFF]/10000 -Z(CONST)SWITCH=02000-FBFF -Z(CONST)FSWITCH=[02000-FBFF]/10000

Listagem 10.1

Basicamente, as modificações dizem respeito à inclusão dos segmentos destinados ao código da FSL e a delimitação da área destinada a código e constantes (até o endereço 0xFBFF da flash). O segmento destinado ao armazenamento dos dados não voláteis da aplicação é alocado nos últimos 1024 bytes da flash (0xFC00 a 0xFFFF) através do comando: -Z(DATA)FLASH_DATA=FBFF-FFFF

O código de manipulação da flash foi separado em um arquivo próprio (flash.c), devendo o mesmo ser incluído no projeto O seu conteúdo é mostrado na listagem 10.2. #include "fsl_types.h"

#include "fsl.h"

#pragma location = "FLASH_DATA"

Microcontroladores RL78: Guia Básico 248

__no_init __far unsigned char flash_data[1024];

static fsl_u08 my_fsl_status;

static fsl_descriptor_t fsl_descr;

// Escreve uma palavra de 32 bits num endereço de 32 bits da flash

void flash_write32(unsigned long data, unsigned long int address)

unsigned long int array[1];

fsl_write_t my_fsl_write_str;

array[0] = data;

my_fsl_write_str.fsl_data_buffer_p_u08 = (fsl_u08 __near*)array;

my_fsl_write_str.fsl_word_count_u08 = 0x01;

my_fsl_write_str.fsl_destination_address_u32 = address;

my_fsl_status = FSL_Write((fsl_write_t __near*)&my_fsl_write_str);

// lê um byte da flash

unsigned char flash_read8(unsigned long addr)

return(*(__far char *)addr);

// Apaga o bloco de dados não voláteis na flash

void flash_erase(void)

FSL_Erase(63); // apaga o bloco 63 (0xFC00 a 0xFFFF)

void flash_init(void)

// Inicialização da FSL

fsl_descr.fsl_flash_voltage_u08 = 0; // full speed mode

fsl_descr.fsl_frequency_u08 = 32; // 32MHz

// Modo da FSL = SCI - checagem de status interna

fsl_descr.fsl_auto_status_check_u08 = 0x01;

// Inicializa a FSL

FSL_Init((__far fsl_descriptor_t*)&fsl_descr);

FSL_Open(); // abre uma sessão FSL

FSL_PrepareFunctions(); // inicializa funções básicas FSL

Listagem 10.2

Repare que a função de apagamento do bloco da flash realiza o apagamento do bloco de número 63. Este valor pode ser obtido através das fórmulas mostradas no tópico 3.1.2.

Foi também criado um array chamado flash_data. Através do mesmo é possível acessar diretamente qualquer um dos 1024 bytes localizados no bloco FLASH_DATA (definido no arquivo do linker).

Lembre-se de que o RL78 armazena os dados em formato little endian)! Isto significa que após a execução de flash_write32(0x12345678,0xFC00), o endereço 0xFC00 irá receber o valor 0x78, 0xFC01 irá receber 0x56, 0xFC02 irá receber 0x34 e 0xFC03 irá receber 0x12!

A seguir temos o código fonte do restante da aplicação.

Tópicos Avançados 249

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

#include "flash.c"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define LED3_RSK P6_bit.no3

#define LED_RPB P7_bit.no7

#define SW1 P5_bit.no0

// Tempo para debounce da tecla 5 = 50ms

#define KEY_TIMER 5

volatile unsigned char save_status;

#pragma vector = INTIT_vect

__interrupt void trata_IT(void)

static unsigned char debounce_counter, key_release;

// faz o debounce da tecla SW1

if (!SW1)

// se a tecla está pressionada

if (debounce_counter) debounce_counter--; else

if (key_release) // se a tecla estava liberada

LED3_RSK = !LED3_RSK; // inverte o estado do led

LED_RPB = !LED_RPB; // inverte o estado do led

key_release = 0; // tecla não liberada

save_status = 1; // solicita salvamento do estado do led

else

// se a tecla não está pressionada

debounce_counter = KEY_TIMER; // novo tempo de debounce

key_release = 1; // tecla está liberada

void MCU_init(void)

PM7_bit.no7 = 0; // P7.7 como saída

Microcontroladores RL78: Guia Básico 250

PM6_bit.no3 = 0; // P6.3 como saída

LED_RPB = 1; // led da RPB desligado

LED3_RSK = 1; // led 3 da RSK desligado

// configura o LOCO (15kHz) como fonte de clock do IT/RTC

OSMC = bWUTMMCK0;

RTCEN = 1; // habilita o RTC e o IT

// Configura o IT para uma interrupção a cada 150 contagens, ou seja:

// 150/15000 = 10ms -> uma interrupção a cada 10ms

ITMC = bRINTE | 149;

ITMK = 0; // habilita a interrupção do IT

__enable_interrupt(); // habilita as interrupções do RL78

// restaura o estado do led conforme o conteúdo da flash

if (flash_read8(0xFC00)==0) LED_RPB = LED3_RSK = 0; else

LED_RPB = LED3_RSK = 1;

void main(void)

MCU_init(); // inicializa o microcontrolador

flash_init(); // inicializa a FSL

while (1)

if (save_status) // se há requisição de salvamento na flash

save_status = 0; // limpa a requisição

flash_erase(); // apaga a flash

// se o led está ligado, salva 0 no endereço 0xFC00

// se o led está desligado, o endereço 0xFC00 permanece com 0xFF

if (!LED_RPB) flash_write32(0,0xFC00);

Exemplo 10.2

A figura 10.4 mostra a aparência do ambiente EWRL78 durante uma sessão de depuração deste exemplo. Observe que o programa foi parado (botão break). Antes da paralisação do programa a tecla SW1 havia sido pressionada, fazendo com que o led 3 da placa acendesse.

Figura 10.4

Tópicos Avançados 251

A janela memory foi configurada para apresentar o endereço 0xFC00 (opção Goto 0xFC00) e o conteúdo das quatro primeiras posições (0xFC00 a 0xFC03) é zero, demonstrando que o conteúdo da flash foi efetivamente alterado. Para se verificar isso, basta executar a aplicação (botão run) pressionar o botão SW1 novamente (o led 3 irá se apagar) e paralisar novamente a aplicação (botão break): o conteúdo das posições 0xFC00 a 0xFC03 deverá ter sido alterado para 0xFF!

10.5. Hardware de Multiplicação e Divisão

Como já foi dito na parte introdutória deste livro, os microcontroladores RL78/G13 incluem hardware interno para multiplicação e divisão. Este hardware permite realizar operações de multiplicação inteira com e sem sinal (16 bits por 16 bits, com resultado de 32 bits), multiplicação inteira e acúmulo (MAC) com e sem sinal (16 bits por 16 bits mais 32 bits, com resultado de 32 bits) e divisão inteira sem sinal (32 bits por 32 bits, com resultado e resto de 32 bits).

A operação de multiplicação é completada em um ciclo de clock, a operação de multiplicação e acúmulo necessita de dois ciclos para ser completada e a divisão necessita de dezesseis ciclos.

É possível utilizar este hardware de duas formas:

1. Transparente: habilitando-se a opção de utilização do multiplicador por hardware na janela de opções do projeto (vide figura 10.1) o compilador IAR irá utilizar o hardware para acelerar as operações de multiplicação e divisão feitas em C. O aumento de performance é muito significativo, mas o consumo de flash é aumentado em cerca de 260 bytes em razão da adição de funções para manipulação do multiplicador. Vale lembrar que não é possível utilizar a modalidade de multiplicação e acúmulo diretamente em C (ou seja, ao se escrever uma declaração do tipo x += y * z o compilador utilizará o hardware apenas para a multiplicação, mas o acúmulo será feito por software e não por hardware). Operações de multiplicação e acúmulo inteiramente por hardware somente são possíveis manipulando-se diretamente o hardware multiplicador, conforme veremos a seguir. Lembre-se de que neste caso a opção de utilização do hardware multiplicador pelo compilador não deve ser utilizada!

Figura 10.5

Microcontroladores RL78: Guia Básico 252

2. Manual: a aplicação deve manipular diretamente os registradores do multiplicador. Nesta modalidade as operações de multiplicação e divisão em C continuam sendo feitas inteiramente por software e cabe ao programador escrever código para utilizar o hardware multiplicador. Esta opção é útil para se obter o máximo de performance, especialmente em aplicações DSP (processamento digital de sinais).

A manipulação direta do hardware de multiplicação é feita utilizando-se os registradores MDAH, MDAL, MDBH, MDBL, MDCH, MDCL e MDUC.

Nas operações de multiplicação com ou sem sinal, o multiplicando de 16 bits é carregado no registrador MDAL e o multiplicador de 16 bits é carregado no registrador MDAH, após um ciclo de clock o resultado da multiplicação (32 bits) pode ser lido nos registradores MDBH (16 bits mais significativos) e MDBL (16 bits menos significativos).

Nas operações de multiplicação e acúmulo (MAC) com ou sem sinal, o multiplicando de 16 bits é carregado no registrador MDAL e o multiplicador de 16 bits é carregado no registrador MDAH, após dois ciclos de clock o resultado da multiplicação (32 bits) pode ser lido nos registradores MDBH (16 bits mais significativos) e MDBL (16 bits menos significativos) e o resultado acumulado é armazenado nos registradores MDCH (16 bits mais significativos) e MDCL (16 bits menos significativos).

Após uma operação MAC os bits MACOF e MACSF do registrador MDUC são modificados de acordo com o resultado da operação:

MACOF indica se houve ou não overflow (estouro) do valor representado no acumulador (MDC). Nas operações sem sinal este bit é setado quando o resultado acumulado ultrapassa o valor 0xFFFFFFFF. Nas operações sinalizadas este bit é setado quando o resultado é menor que 0x80000000 ou maior que 0x7FFFFFFF.

MACSF é o indicador de sinal do valor acumulado (MDC).

Nas operações de divisão de 32 por 32 bits, o dividendo de 32 bits deve ser carregado nos registradores MDA (MDAH com os 16 bits mais significativos e MDAL com os 16 bits menos significativos) e o divisor carregado nos registradores MDB (MDBH com os 16 bits mais significativos e MDBL com os 16 bits menos significativos). Após dezesseis ciclos de clock o resultado da divisão é armazenado nos registradores MDA (MDAH com os 16 bits mais significativos e MDAL com os 16 bits menos significativos) e o resto da divisão é armazenado nos registradores MDC (MDCH com os 16 bits mais significativos e MDCL com os 16 bits menos significativos).

A seleção da operação a ser realizada pelo multiplicador deve ser feita no registrador MDUC antes de carregar os operandos nos registradores MDA/MDB.

No caso das operações de multiplicação e multiplicação e acúmulo, a operação selecionada no MDUC é iniciada automaticamente depois de carregados os dois operandos nos registradores MDA/MDB (a ordem de carga dos operandos não é importante).

No caso da operação de divisão, os operandos devem ser carregados nos registradores MDA e MDB e a operação é iniciada setando-se o bit DIVST no registrador MDUC.

Tópicos Avançados 253

Quando a operação de divisão é completada (dezesseis ciclos de clock depois) o bit DIVST é apagado pelo hardware e opcionalmente o flag MDIF é setado e uma interrupção INTMD é gerada (conforme o modo de divisão selecionado).

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita DIVMODE MACMODE 0 0 MDSM MACOF MACSF DIVST

MDUC

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Símbolo C Seleção do modo de operação do multiplicador por hardware:

000 – multiplicação sem sinal MAC_MUL_UNS

001 – multiplicação com sinal MAC_MUL_SIG

010 – multiplicação e acúmulo (MAC) (sem sinal) MAC_MAC_UNS

011 – multiplicação e acúmulo (MAC) (com sinal) MAC_MAC_SIG

100 – divisão (com interrupção INTMD) MAC_DIV_INT

DIVMODE MACMODE MDSM

110 – divisão (sem interrupção INTMD) MAC_DIV_NOINT

MACOF

Indicador de estouro do resultado acumulado (modo MAC): 0 – não houve estouro 1 – houve estouro (no modo sem sinal, significa que o resultado foi maior que 0xFFFFFFFF, no modo com sinal, significa que o resultado foi maior que 0x7FFFFFFF ou menor que 0x80000000)

bMACOF

MACSF Indicador do sinal do resultado acumulado: 0 – positivo 1 – negativo

bMACSF

DIVST Indicador de andamento da operação de divisão: 0 – operação completada 1 – operação em andamento

bDIVST

10.6. DMA

O acesso direto à memória (DMA) é um circuito que permite que um periférico acesse diretamente os barramentos de dados e de endereços, de forma a transferir dados de/para a memória RAM.

O DMA permite automatizar operações que, de outra forma, ocupariam a CPU desnecessariamente, tomando tempo precioso que poderia ser gasto com trabalho útil para a aplicação.

Um exemplo típico é a comunicação serial: suponha um protocolo de comunicação composto de quadros de 8 bytes e com velocidade de comunicação assíncrona de 115.200bps. A esta velocidade, um caractere (8 bits de dados, mais um bit de partida e outro de parada) é recebido em 86,8µs. Se num quadro os dados forem transmitidos em uma sequencia contínua, isto significa que a CPU é interrompida a cada caractere recebido ou aproximadamente a cada 86,8µs. A cada interrupção a CPU efetua a transferência do caractere recebido para um buffer em memória. Somente após receber 8 caracteres é que a aplicação pode analisar o quadro e efetivamente fazer processamento útil do protocolo.

Microcontroladores RL78: Guia Básico 254

É fácil perceber que em altas velocidades de comunicação a CPU é ocupada desnecessariamente com trabalho bruto, ou seja, movimentar os dados recebidos da UART para um buffer em memória. Neste caso, o uso do DMA pode liberar a CPU para efetuar processamento em outras áreas da aplicação, pois a transferência dos dados recebidos para um buffer em memória é feita automaticamente pelo DMA e, somente após a recepção de 8 caracteres é que o DMA irá gerar uma interrupção, notificando a CPU do término da transferência. Isto significa que uma interrupção será gerada somente após 694,4µs e não a cada 86,8µs!

O controlador DMA dos RL78 é construído de forma que pode movimentar 8 ou 16 bits por ciclo de transferência e cada transferência necessita de dois ciclos de clock para ser completada. Durante uma transferência a CPU é mantida paralisada, prosseguindo com sua operação normal assim que a transferência é completada.

As transferências DMA podem ser feitas em duas direções: de um registrador SFR (periférico) para a RAM e da RAM para um registrador SFR.

É possível configurar o DMA para realizar até 1024 transferências e, depois de completado este valor uma interrupção DMA (INTDMA) é gerada.

Após habilitado o canal de DMA, o disparo de uma transferência pode ser realizado por software ou por um sinal de interrupção vindo de um dos seguintes periféricos (conversor A/D, canais 0, 1, 2 e 3 da TAU0 e TAU1, interrupções de transmissão ou de recepção das UARTs ou interrupções de transferência de qualquer um dos canais CSI).

Tipicamente a interrupção do periférico que irá provocar o disparo da transferência DMA deverá estar desabilitada! O disparo da transferência ocorre independentemente da interrupção estar habilitada ou não.

A tabela 10.2 mostra a disponibilidade de canais DMA nos microcontroladores da linha RL78/G13.

DMA 80 a 128 pinos

20 a 64 pinos

Número de Canais 4 2

Tabela 10.2

Os passos para configuração do DMA são muito simples:

1. O canal de DMA deve ser habilitado (o bit DEN no registrador DRCn deve ser setado);

Não é possível alterar os registradores do canal de DMA quando o bit DEN está apagado!

2. No registrador DSAn deve ser configurado o endereço do registrador SFR que será a fonte ou destino da transferência. Para atribuir o endereço de um registrador SFR ao registrador DSA podemos escrever: DSAn=(char)&REG onde REG é no nome do registrador SFR desejado. Vejamos alguns exemplos:

Tópicos Avançados 255

DSA2 = (char)&TXD0; // atribui o endereço do TXD0 ao DSA2

DSA0 = (char)&TDR01; // atribui o endereço do TDR01 ao DSA0

3. No registrador DRAn deve ser configurado o endereço da primeira posição de memória RAM onde os dados serão armazenados ou lidos. Para atribuir um endereço da RAM ao registrador DRAn podemos escrever: DRAn=(int)&MEM onde MEM é a variável na memória RAM. Como normalmente se utiliza um array para o armazenamento do bloco de memória a ser transferido pelo DMA, a atribuição assume a seguinte forma: DRAn=(int)array onde “array” é o nome da array utilizada na transferência. Vejamos alguns exemplos:

// atribui o endereço da variável “var” ao DRA1

DRA1 = (int)&var;

// atribui o endereço da array “buffer” ao DRA3

unsigned char buffer[16];

...

DRA3 = (int)buffer;

Lembre-se que a referência apenas ao nome de um array retorna o endereço do seu primeiro elemento!

4. O número total de transferências que o canal deverá fazer deve ser configurado no registrador DBCn;

O array que irá armazenar os dados transferidos pelo DMA deve ser dimensionado de acordo com o número total de transferências configurado no registrador DBCn! Caso o array seja menor que o número de transferências, poderão ocorrer problemas de corrupção de memória.

5. Configura-se, no registrador DMCn as características de operação do DMA:

a. Direção (de um SFR para a RAM ou da RAM para um SFR);

b. Tamanho (8 bits ou 16 bits);

O array que irá armazenar os dados transferidos pelo DMA deve declarado conforme o tamanho da transferência: char para transferências de 8 bits e int para transferências de 16 bits!

c. Tipo de disparo (por software ou por hardware);

d. Fonte de disparo (no caso do hardware): ADC, TAU, CSI.

6. Em seguida o bit DST (registrador DRCn) deve ser setado, de forma que o DMA entre no modo de transferência de dados;

7. Quando um periférico é utilizado como destino da transferência, pode ser necessário iniciar a mesma através de um disparo por software. Isto pode ser feito setando-se o bit STG (registrador DMCn).

O bit DST (registrador DRCn) pode ser utilizado para monitorar o andamento da operação do DMA: quando em “0” indica que as transferências foram completadas e quando em “1” indica

Microcontroladores RL78: Guia Básico 256

que a operação do DMA ainda não foi completada (o número de transferências programadas no registrador DBCn ainda não foi atingido).

Quando o DMA está habilitado e há transferências pendentes (DST=1), a aplicação pode cancelar as operações pendentes escrevendo “0” em DST.

Quando todas as transferências programadas foram completadas o canal de DMA irá gerar uma interrupção INTDMA e a ISR deverá providenciar a desativação do mesmo (DEN=0) ou a reconfiguração do canal para novas transferências (seguindo-se os passos mostrados acima).

A seguir apresentamos os registradores associados aos canais de DMA dos RL78.

10.6.1. Registradores dos Canais de DMA

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita Endereço do registrador SFR (8 bits inferiores da faixa compreendida entre 0xFFF00 e 0xFFFFF)

DSAn

Reset 0 0 0 0 0 0 0 0

* n é o número do canal de DMA (0 a 3)

A alteração deste registrador somente pode ser realizada quando uma transferência não está em andamento.

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita Endereço de memória RAM alvo/destino da transferência DMA

DRAn

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*n corresponde ao número do canal de DMA (0 a 3)

Este registrador contém o endereço da RAM onde será escrito ou lido o dado na próxima transferência DMA. O conteúdo do registrador é automaticamente incrementado após cada transferência (incrementado em um para transferências de 8 bits ou 2 para transferências de 16 bits).

A alteração deste registrador somente pode ser realizada quando uma transferência não está em andamento.

Nome BIT 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Leitura

Escrita 0 0 0 0 0 0 Número de transferências DMA

DBCn

Reset 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

*n corresponde ao número do canal de DMA (0 a 3)

Este registrador armazena o número de transferências a serem realizadas pelo DMA. O conteúdo do mesmo é automaticamente decrementado após cada transferência e ao atingir zero uma interrupção INTDMA é gerada.

Caso este registrador esteja carregado com zero no instante em que o canal de DMA é habilitado, serão realizadas 1024 transferências até que seja gerada uma interrupção.

A leitura deste registrador permite que a aplicação determine o número de transferências já realizadas.

A alteração deste registrador somente pode ser realizada quando uma transferência não está em andamento.

Tópicos Avançados 257

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita STGn DRSn DSn DWAITn IFCn3 IFCn2 IFCn1 IFCn0

DMCn

Reset 0 0 0 0 0 0 0 0

*n corresponde ao número do canal de DMA (0 ou 1)

Nome do Bit Descrição Bit C Símbolo C

STGn Disparo por software da transferência DMA: 0 – nenhum disparo 1 – dispara a transferência

STGn bSTG

DRSn Seleção da direção da transferência DMA: 0 – do periférico para a RAM 1 – da RAM pra o periférico

DRSn bDRS

DSn Tamanho de cada transferência do DMA: 0 – 8 bits 1 – 16 bits

DSn bDS

DWAITn

Controle de paralisação da transferência DMA: 0 – executa a transferência DMA quando ocorre a solicitação 1 – paralisa a transferência, DWAIT deve ser apagado para que a transferência ocorra normalmente

DWAITn bDWAIT

Seleção da fonte de disparo do DMA:

0000 – disparo por software - DMA_TRIG_SOFT

0001 – disparo pelo ADC - DMA_TRIG_ADC

0010 – disparo pelo canal 0 da TAU0 - DMA_TRIG_T00

0011 – disparo pelo canal 1 da TAU0 - DMA_TRIG_T01

0100 – disparo pelo canal 2 da TAU0 - DMA_TRIG_T02

0101 – disparo pelo canal 3 da TAU0 - DMA_TRIG_T03

0110 – disparo pela UART0 (TX) ou CSI00 - DMA_TRIG_TX0

0111 – disparo pela UART0 (RX) ou CSI01 - DMA_TRIG_RX0

1000 – disparo pela UART1 (TX) ou CSI10 - DMA_TRIG_TX1

1001 – disparo pela UART1 (RX) ou CSI11 - DMA_TRIG_RX1

1010 – disparo pela UART2 (TX) ou CSI20 - DMA_TRIG_TX2

IFCn3 IFCn2 IFCn1 IFCn0

1011 – disparo pela UART2 (RX) ou CSI21 - DMA_TRIG_RX2

Microcontroladores RL78: Guia Básico 258

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita STGn DRSn DSn DWAITn IFCn3 IFCn2 IFCn1 IFCn0

DMCn

Reset 0 0 0 0 0 0 0 0

*n corresponde ao número do canal de DMA (2 ou 3)

Nome do Bit Descrição Bit C Símbolo C

STGn Disparo por software da transferência DMA: 0 – nenhum disparo 1 – dispara a transferência

STGn bSTG

DRSn Seleção da direção da transferência DMA: 0 – do periférico para a RAM 1 – da RAM pra o periférico

DRSn bDRS

DSn Tamanho de cada transferência do DMA: 0 – 8 bits 1 – 16 bits

DSn bDS

DWAITn

Controle de paralisação da transferência DMA: 0 – executa a transferência DMA quando ocorre a solicitação 1 – paralisa a transferência, DWAIT deve ser apagado para que a transferência ocorra normalmente

DWAITn bDWAIT

Seleção da fonte de disparo do DMA:

0000 – disparo por software - DMA_TRIG_SOFT

0001 – disparo pelo ADC - DMA_TRIG_ADC

0010 – disparo pelo canal 0 da TAU1 - DMA_TRIG_T10

0011 – disparo pelo canal 1 da TAU1 - DMA_TRIG_T11

0100 – disparo pelo canal 2 da TAU1 - DMA_TRIG_T12

0101 – disparo pelo canal 3 da TAU1 - DMA_TRIG_T13

0110 – disparo pela UART3 (TX) ou CSI30 - DMA_TRIG_TX3

0111 – disparo pela UART3 (RX) ou CSI31 - DMA_TRIG_RX3

1000 – disparo pela UART1 (TX) ou CSI10 - DMA_TRIG_TX1

1001 – disparo pela UART1 (RX) ou CSI11 - DMA_TRIG_RX1

1010 – disparo pela UART2 (TX) ou CSI20 - DMA_TRIG_TX2

IFCn3 IFCn2 IFCn1 IFCn0

1011 – disparo pela UART2 (RX) ou CSI21 - DMA_TRIG_RX2

Nome BIT 7 BIT 6 BIT 5 BIT 4 BIT 3 BIT 2 BIT 1 BIT 0

Leitura

Escrita DENn 0 0 0 0 0 0 DSTn

DRCn

Reset 0 0 0 0 0 0 0 0

Nome do Bit Descrição Bit C Símbolo C

DENn Controle de habilitação do canal DMA: 0 – DMA desabilitado 1 – DMA habilitado

DENn bDEN

DSTn Indicador de transferência DMA: 0 – transferência DMA completada 1 – transferência DMA em andamento

DSTn bDST

Tópicos Avançados 259

10.6.2. Exemplo

O exemplo a seguir demonstra como utilizar um canal de DMA para automatizar a transmissão de dados com a UART.

Um buffer de 32 bytes é utilizado para o armazenamento dos dados a serem transmitidos.

A função tx_UART2() é utilizada para escrever uma string no buffer e configurar o DMA para realizar a transferência dos dados através da UART2.

Toda a transferência é realizada automaticamente pelo DMA, ou seja, após cada caractere ser transmitido o flag de transmissão da UART2 (STIF2) é setado, provocando o disparo do DMA que transfere um novo caractere do buffer para o registrador TXD2.

Este processo segue até que todos os caracteres tenham sido transmitidos (registrador DBC0 chegue a zero e bit DST seja apagado no registrador DRC0).

Adicionalmente a aplicação também responde aos caracteres recebidos pela UART2, invertendo o estado do led D2 da placa RPB a cada caractere recebido e enviando a string “Teste!” ao receber o caractere ‘t’ e “RL78!” ao receber o caractere ‘r’.

Os procedimentos de configuração da placa RPB e teste da aplicação são os mesmos vistos para o exemplo 9.1. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

// Configura watchdog = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão = desligado

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define __9600BPS 51 << 9

#define LED P7_bit.no7

#define TX_BUF_SIZE 32

unsigned char tx_buffer[TX_BUF_SIZE];

void tx_UART2(unsigned char *string);

#pragma vector = INTSR2_vect

__interrupt void trata_rx_UART2(void)

unsigned char temp;

Microcontroladores RL78: Guia Básico 260

temp = RXD2; // lê o caractere recebido

// se recebeu 't' envia "Teste!"

if (temp=='t') tx_UART2("Teste!\r\n");

// se recebeu 'r' envia "RL78!"

if (temp=='r') tx_UART2("RL78!\r\n");

LED = !LED; // a cada caractere recebido, inverte o estado do led

#pragma vector = INTDMA0_vect

__interrupt void trata_DMA_tx_uart2(void)

DEN0 = 0; // desabilita o DMA

void MCU_init(void)

PM1_bit.no3 = 0; // P13/TXD2 como saída

P1_bit.no3 = 1; // coloca TXD2 em 1 (importante!!!)

PM1_bit.no4 = 1; // P14/RXD2 como entrada

PM7_bit.no7 = 0; // P77 como saída (led)

LED = 1; // desliga o led

SAU1EN = 1; // ativa a SAU1

// Clock CK0 da SAU1 = 32MHz / 32 = 1MHz

SPS1 = SAU_CK0_DIV32;

// Configura o canal 0 da SAU1 (transmissão da UART2)

SMR10 = SAU_MD_UART;

SCR10 = SAU_COMM_TX|SAU_NO_PARITY|SAU_LSB_FIRST|SAU_ONE_STOP|SAU_8BITS;

SDR10 = __9600BPS; // seta o baud rate do transmissor

// Configura o canal 1 da SAU1 (recepção da UART2)

SMR11 = bSAU_STS | SAU_MD_UART;

SCR11 = SAU_COMM_RX|SAU_NO_PARITY|SAU_LSB_FIRST|SAU_ONE_STOP|SAU_8BITS;

SDR11 = __9600BPS; // seta o baud rate do receptor

SOE1 = SAU_CH0; // habilita a saída da UART2

SO1 = SAU_CH0; // seta a saída TXD2

NFEN0 = SNFEN20; // ativa o filtro digital da entrada RXD2

// Dispara os canais 0 e 1 da SAU1

SS1 = SAU_CH1 | SAU_CH0;

SRMK2 = 0; // habilita a interrupção de recepção da UART

DMAMK0 = 0; // habilita a interrupção do DMA0

__enable_interrupt(); // habilita as interrupções do RL78

// envia uma string pela UART2 utilizando o DMA

void tx_UART2(unsigned char *string)

unsigned char index;

index = 0;

// copia a string para o buffer de transmissão

while (string)

tx_buffer[index++] = *string++;

// se atingiu o final da string ou o tamanho do buffer, encerra a cópia

if (index==TX_BUF_SIZE || !*string) break;

// se o buffer contém caracteres, configura o DMA para a transferência

if (index)

DRC0 = bDEN; // habilita o DMA0

DBC0 = index; // configura o número de bytes a transferir

Tópicos Avançados 261

DSA0 = (char)&TXD2; // configura o endereço do registrador alvo

DRA0 = (int)tx_buffer; // configura o endereço do buffer com os dados

DMC0 = bDRS | DMA_TRIG_TX2; // configura o canal de DMA

DRC0 = bDEN | bDST; // seta DST para iniciar a transferência

STG0 = 1; // dispara o DMA e inicia a transferência

void main(void)

MCU_init();

// transmite uma string de saudação

tx_UART2("Teste da UART com DMA!");

while (1); // aguarda uma interrupção

Exemplo 10.3

10.7. Otimizando Aplicações para o RL78

Neste tópico veremos algumas técnicas de programação e características especiais do compilador que permitem extrair maior desempenho e eficiência das aplicações utilizando os microcontroladores RL78.

10.7.1. Tamanho do Dado

A arquitetura dos RL78 privilegia os dados com tamanho de 1, 8 e 16 bits, por isso, é interessante que a aplicação utilize, sempre que possível, variáveis de no máximo 16 bits.

O uso de variáveis inteiras de 32 bits pode ser feito sem problemas, mas é importante considerar que a aplicação funcionará melhor e mais rapidamente se for possível utilizar variáveis de 16 bits ou menos. A figura a seguir demonstra o código assembly gerado para operações comuns no cotidiano (atribuição e incremento) para variáveis de 8, 16 e 32 bits. unsigned char v8;

v8 = 5;

MOV N:v8,#5 (4)

v8++;

INC N:v8 (3)

unsigned int v16;

v16 = 5;

MOV X,#5 (2)

MOVW N:v16,AX (3)

v16++;

INCW N:v16 (3)

unsigned long v32;

v32 = 5;

MOVW HL,#0xEF0A (3)

MOVW [HL],AX (1)

CLRW AX (1)

MOVW [HL+2],AX (2)

V32++;

MOVW BC,N:0xEF0C (3)

MOVW AX,N:v32 (3)

ADDW AX,#1 (3)

SKNC (2)

INCW BC (1)

MOVW [HL],AX (1)

MOVW AX,BC (1)

MOVW N:0xEF0C,AX (3)

Figura 10.6

Perceba que a atribuição e incremento de um variável de 8 bits consomem 7 bytes de flash, ao passo que para uma variável de 16 bits as mesmas operações consomem 8 bytes e no caso de uma variável de 32 bits o consumo de memória flash aumenta para 24 bytes!

Microcontroladores RL78: Guia Básico 262

No caso das variáveis de ponto flutuante (float e double), o seu uso é totalmente desencorajado e deve ser evitado ao máximo, pois implica em grande aumento no tamanho do código e significativa redução na performance.

10.7.2. Endereçamento Rápido

Como já vimos no tópico 3.1.3 os microcontroladores possuem um modo de endereçamento especial que acelera o acesso a uma pequena porção da memória RAM e SFRs. Este modo de endereçamento, chamado de “short address”, possibilita que as instruções sejam menores e com isso mais eficientes. A limitação deste modo de endereçamento é que ele pode ser utilizado apenas para os endereços compreendidos na faixa entre 0xFFE20 e 0xFFF1F.

Considerando que a memória RAM disponível para o usuário termina no endereço 0xFFEDF, conclui-se que há 192 bytes de RAM disponíveis para utilização neste modo de endereçamento.

Apesar de o compilador utilizar esta área naturalmente, sem a necessidade de utilização de diretivas especiais, ele não utilizará o modo de endereçamento rápido para as variáveis alocadas nesta região, a menos que o programador o instrua para tal.

Para instruir o compilador a armazenar uma variável na região de endereçamento rápido, basta utilizar o modificador de atributo __saddr antes da declaração da variável:

__saddr unsigned char myvar;

Observe que o aumento na eficiência de código (especialmente na redução do espaço ocupado em flash) ao se utilizar este modo de endereçamento é substancial:

__saddr unsigned char va;

va = 10;

CD200A MOV S:va,#0x0A (3 bytes)

va++;

A420 INC S:va (2 bytes)

unsigned char va;

va = 10;

CF0AEF0A MOV N:va,#0x0A (4

bytes)

va++;

A00AEF INC N:vb (3 bytes)

Figura 10.7

10.7.3. Campos de Bit

O conjunto de instruções dos RL78 favorece a utilização de variáveis com tamanho de um bit, como no caso das estruturas com campos de bit.

Para obter a máxima eficiência de código é importante utilizar campos de bit com tamanho de apenas um bit e utilizar o modificador __saddr para forçar estas estruturas a serem armazenadas na área de endereçamento rápido.

Desta forma, o compilador consegue traduzir atribuições de bits em apenas uma instrução assembly (CLR1 para apagar um bit e SET1 para setar um bit). O teste de bit também é traduzido em uma única instrução assembly (BF), garantindo o máximo de eficiência de código.

Observe que por padrão o compilador IAR irá armazenar os membros de uma estrutura da bits iniciando do bit menos significativo para o mais significativo. Por exemplo:

Tópicos Avançados 263

__saddr struct

unsigned char primeiro : 1;

unsigned char segundo : 1;

unsigned char terceiro : 1;

bits;

Na estrutura acima, o elemento “primeiro” será armazenado no bit 0 da posição de memória alocada para a estrutura “bits”. O elemento “segundo” será armazenado no bit 1 e assim por diante.

É possível utilizar a diretiva #pragma bitfields=reversed para forçar o compilador a armazenar a estrutura iniciando pelo bit mais significativo, assim o elemento “primeiro” seria armazenado no bit 7 da posição de memória alocada para a estrutura “bits”, seguido pelo elemento “segundo” no bit 6 e assim por diante.

Para retornar ao método de alocação padrão para campos de bits, utiliza-se a diretiva #pragma bitfields=default.

10.7.4. Funções CALLT

Como já vimos no tópico 3.1.3 os microcontroladores RL78 incluem uma área de 64 bytes destinada ao armazenamento de uma tabela de endereços de funções.

Esta tabela pode ser acessada através das instruções assembly CALLT e permite que se faça a chamada de funções de uma forma mais eficiente, já que as instruções CALLT são menores, porém um pouco mais lentas (uma instrução CALLT ocupa dois bytes e executa em cinco ciclos de clock, ao passo que uma instrução CALL ocupa tipicamente três bytes e executa em três ciclos de clock).

A principal utilidade das instruções CALLT é na redução do tamanho do código e o seu uso é recomendado no caso das funções que são chamadas com muita frequência.

Para instruir o compilador a utilizar estas instruções, tudo o que é necessário fazer é declarar a função utilizando o modificador __callt antes da declaração da variável:

__callt void minha_func(void);

A seguir mostramos uma comparação do código assembly gerado com e sem a utilização deste modificador.

__callt void teste(void)

...

teste();

6184 CALLT [__T_teste] (2

bytes)

void teste(void)

...

teste();

FD2C01 CALL N:teste (3 bytes)

Figura 10.8

Note que a função modificada com __callt deverá ser obrigatoriamente alocada nos primeiros 64k de flash do microcontrolador (isso é feito automaticamente pelo compilador). No mais, funções __callt podem retornar qualquer tipo de dado e receber qualquer quantidade de parâmetros (como qualquer outra função C tradicional).

Microcontroladores RL78: Guia Básico 264

10.8. Utilizando o Applilet3

O Applilet3 for RL78 é uma aplicação desenvolvida pela Renesas para facilitar a criação de código para o RL78. A tela inicial do Applilet pode ser vista na figura 10.9.

A vantagem de se utilizar o Applilet é que ele facilitar grandemente a utilização dos periféricos internos do RL78, gerando todo o código para inicialização e tratamento de interrupções.

Figura 10.9

Para iniciar um novo projeto no Applilet, basta clicar em File>New no menu principal. Será apresentada a janela da figura 10.10A. Selecione o microcontrolador desejado (no caso da Promotion board do RL78, devemos selecionar o R5F100LE), o compilador (Build Tool), que no nosso caso é o IAR , o nome do projeto e o local onde ele será salvo (figura 10.10B).

Figura 10.10A Figura 10.10B

Clicando-se em OK, o novo projeto será criado e será apresentada a tela da figura 10.11. Inicialmente a ferramenta espera que o usuário selecione a função primária dos pinos com

Tópicos Avançados 265

capacidade de redirecionamento de função (aba Pin Assignment). Esta seleção deve ser feita e não poderá mais ser alterada no decorrer do projeto.

Figura 10.11

Nos exemplos deste livro não será necessário nenhum redirecionamento de função. Todas as caixas de seleção nesta aba devem ser mantidas desmarcadas. Pressione o botão FIX SETTINGS para que a configuração seja armazenada.

Nas outras abas desta tela é possível configurar outras opções do microcontrolador, como o sistema de clock (aba Clock setting), depurador interno (aba On-chip debug setting), geração de função para identificação da fonte de reset (aba Confirming reset source) e funções de segurança avançadas (aba Safety functions).

No painel da esquerda é possível selecionar os diversos módulos internos do microcontrolador (dentro de Peripheral): Clock generator (a tela inicial), Port (para configuração dos pinos de E/S, Interrupts (para configuração das interrupções externas INTPx e de teclado), Serial (para configuração das unidades SAU e IICA), A/D Converter (para configuração do conversor A/D), Timer (para configuração das unidades TAU), etc. Para selecionar uma das opções é necessário um duplo clique do mouse (ou selecioná-la no na entrada Peripheral no menu principal).

Uma vez que o usuário tenha configurado todas as opções e periféricos desejados, basta clicar no botão “Generate Source Code” para que o Applilet gere automaticamente um projeto para o IAR contendo todo o código de inicialização e funções necessárias para programação em alto nível do microcontrolador e dos seus periféricos.

Os arquivos gerados pelo Applilet estarão armazenados dentro da pasta applilet_src. A estrutura de arquivos irá conter um arquivo principal da aplicação (r_main.c), um arquivo principal de inicialização do microcontrolador (r_systeminit.c) e outros arquivos relacionados aos módulos e periféricos do chip.

É interessante notar que o Applilet normalmente gera dois arquivos para cada módulo ou periférico do chip: um arquivo contém as funções internas utilizadas para inicialização e operação do periférico e o outro contém as funções que podem ser programadas pelo usuário e que irão formar a aplicação propriamente dita.

Como exemplo podemos citar o módulo CGC (gerador de clock), o Applilet gera dois arquivos para o mesmo, r_cg_cgc.c e r_cg_cgc_user.c. O primeiro arquivo contém a função

Microcontroladores RL78: Guia Básico 266

R_CGC_Create() utilizada para inicialização do sistema de clock, ao passo que o segundo contém a função R_CGC_Get_ResetSource() que pode ser modificada pelo usuário para identificar a origem do reset e executar alguma ação. O código padrão desta função pode ser visto a seguir:

void R_CGC_Get_ResetSource(void)

uint8_t reset_flag = RESF;

/* Start user code. Do not edit comment generated here */

/* End user code. Do not edit comment generated here */

Observe que há dois comentários dentro da função, o primeiro marca o ponto inicial para entrada de código do usuário e o segundo marca o ponto final para entrada de código do usuário. O código da função deve ser inserido entre os dois comentários (mantendo os comentários conforme gerados pelo Applilet).

Atenção: somente modifique ou adicione código dentro da área compreendida entre os dois comentários mostrados acima! O Applilet está configurado para preservar tudo o que é escrito nestas áreas, mesmo quando o usuário reconfigurar um projeto já existente. Caso o programador opte por inserir código fora das áreas permitidas, o projeto não poderá ser modificado posteriormente no Applilet!

Uma outra característica importante acerca do Applilet é que a inicialização principal do microcontrolador é administrada automaticamente pelo Applilet na função R_Systeminit() que é chamada dentro da função __low_level_init(). Esta última é chamada automaticamente pelo compilador imediatamente antes do controle do programa ser passado para a função main().

10.8.1. Configuração do Timer de Intervalo

Como primeiro exemplo do uso do Applilet veremos como implementar um pisca-pisca utilizando o timer de intervalo (IT) e o led D2 da placa de promoção do RL78/G13.

Primeiramente é necessário criar um novo projeto no Applilet. Após fixar as configurações de redirecionamento de E/S (mantendo a configuração padrão), verifique na aba “Clock setting” se o oscilador interno High Speed está selecionado e o clock está ajustado para 32MHz (padrão no Applilet).

Na aba “On-chip debug setting”, configure “On-chip debug operation setting” para “Used” e caso queira configurar algum código de segurança, insira-o no campo Security ID.

Em seguida devemos configurar a pino de E/S ao qual o led D2 está conectado. Na Promotion board do RL78/G13 o led D2 está conectado ao pino P7.7 e, portanto, o mesmo deve ser configurado como saída.

Um duplo-clique sobre o item “Port” (listado na caixa à esquerda) irá abrir as abas de configuração dos pinos de E/S (figura 10.4). Selecione a aba “Port7” e configure P77 como saída (Out). Opcionalmente é possível clicar na caixa ao lado direito, onde aparece o número “1”, isto fará com que o estado inicial do pino seja “1”. Caso a caixa permaneça desmarcada o estado inicial será “0”.

Tópicos Avançados 267

Figura 10.12

Em seguida devemos configurar o timer de intervalo do RL78 para controlar a frequência de piscadas do led, gerando interrupções a cada 100ms. Para configurá-lo, dê um duplo-clique sobre o item “Interval Timer” e ajuste as opções conforme a figura 10.13.

Figura 10.13

Feito isso, basta clicar no botão GENERATE CODE para que o Applilet3 gere o código necessário para configurar a CPU e os periféricos da nossa aplicação.

Agora podemos abrir o projeto no EWRL78 e inserir o código necessário para que a nossa aplicação pisque o led. A figura 10.14 mostra a janela do EWRL78 com o projeto gerado pelo Applilet aberto. Perceba a estrutura de arquivos gerada para a aplicação (dentro de applilet_src), ela contém arquivos para o módulo CGC (gerador de clock), IT (timer de intervalo), Port (portas

Microcontroladores RL78: Guia Básico 268

de E/S), WDT (watchdog), além do arquivo r_main.c (arquivo principal da aplicação) e r_systeminit.c (que contém a inicialização principal do microcontrolador).

Para a nossa aplicação, deveremos fazer três alterações no código gerado pelo Applilet: a primeira é inserir no arquivo r_main.c uma chamada a função R_IT_Start(), responsável por iniciar o temporizador de intervalo. Esta chamada, conforme ilustra a figura 10.14 deve ser realizada antes do while na função main().

Figura 10.14

A outra alteração consiste em inserir uma linha de código no arquivo r_cg_it_user.c, que contém a função de tratamento da interrupção do timer de intervalo. Este código (LED_D2 = !LED_D2) deve ser inserido conforme ilustra a figura 10.15.

Figura 10.15

A terceira e última alteração consiste em definir o símbolo LED_D2. Preferencialmente, devemos definir os símbolos e variáveis globais do programa no arquivo r_cg_userdefine.h. A figura 10.16 ilustra o ponto onde deve ser inserida a linha de código #define LED_D2

P7_bit.no7 no arquivo citado.

Figura 10.16

Tópicos Avançados 269

Depois de realizadas todas as alterações mencionadas, basta compilar o programa e fazer o download para a Promotion board para observar o seu correto funcionamento! Lembre-se de configurar o depurador para “TK” nas opções do projeto.

10.8.2. Configuração da UART

Neste exemplo mostramos como utilizar o Applilet para configurar e utilizar a UART2 da placa de promoção do RL78/G13 (YRPBRL78G13).

Após criar um novo projeto no Applilet, a tela de configuração inicial das unidades SAU e IICA é acessada com um duplo clique sobre a entrada “Serial” na árvore de projeto (project tree). Feito isso, basta selecionar a unidade SAU1 e clicar na aba Channel para configurar os canais da SAU1. A figura 10.17 mostra esta etapa.

Figura 10.17

Após selecionar o modo UART2 no canal 0 da SAU1 e configurá-la para transmissão e recepção, o próximo passo é fazer as configurações de transmissão e de recepção da UART, para isso basta clicar na aba UART2. Será apresentada a tela da figura 10.18A.

Nas telas mostradas nas figuras 10.18A e 10.18B o programador pode configurar as diversas características das etapas de recepção e transmissão da UART: velocidade, número de bits, sentido, polaridade, paridade, etc. Também é possível configurar o Applilet para gerar funções de callback para o fim de recepção, erro de recepção e fim de transmissão.

Figura 10.18A

Figura 10.18B

Após a configuração da UART (e do pino P7.7 como saída) basta clicar no botão “Generate code” para que o Applilet gere o projeto C com o código fonte de inicialização e utilização da UART.

Conforme já visto no tópico 9.1.2.4, o Applilet irá gerar automaticamente um conjunto de funções para manipulação da UART2:

• R_UART2_Start() – para disparar a UART2;

Microcontroladores RL78: Guia Básico 270

• R_UART2_Send() – para envio de dados pela UART2;

• R_UART2_Receive() – para recepção de dados pela UART2.

Após a geração do código, é necessário abrir, no IAR, o projeto criado pelo Applilet e alterar a função main() do arquivo r_main.c conforme mostrado a seguir. Este código fará com que a string “Teste” seja transmitida periodicamente através da UART, ao mesmo tempo em que o led D2 troca de estado.

void main(void)

/* Start user code. Do not edit comment generated here */

unsigned long int temp;

R_UART2_Start();

while (1U)

R_UART2_Send("Teste\r\n",7);

for (temp=0;temp<2000000;temp++);

P7_bit.no7 = !P7_bit.no7;

/* End user code. Do not edit comment generated here */

Feito isso, basta compilar o projeto no IAR e fazer o download para a placa. Observe que para testar o exemplo é necessário sair da depuração e modificar a posição dos jumpers J6, J7, J8 e J9 para a posição 2-3 de forma a conectar o RL78/G13 ao computador através da porta COM virtual integrada a placa de promoção.

Após modificar os jumpers, um programa de terminal serial (como o Termite, disponível em http://www.compuphase.com/ software_termite.htm) deverá ser aberto e configurado para acessar a porta COM virtual criada pelo driver da Renesas (no presente caso a porta COM criada foi a COM8). A figura a seguir mostra o resultado final da aplicação.

Figura 10.19

Exemplos de Aplicação 271

11

Exemplos de Aplicação 11. Exemplos de Aplicação

Neste último capítulo apresentamos alguns exemplos de aplicação dos RL78. Estes exemplos possuem caráter apenas didático e foram desenvolvidos para demonstrar e aplicar os conhecimentos apresentados neste livro

11.1. Utilização de Módulos LCD Alfanuméricos

Os módulos LCD são elementos de apresentação de dados muito versáteis e com custo bastante reduzido, por esta razão são encontrados nos mais variados equipamentos eletrônicos. Os módulos dividem-se em duas categorias básicas: os alfanuméricos, que podem apresentar textos e números e os gráficos que podem apresentar textos, números e gráficos a cores ou em preto e branco.

Os módulos alfanuméricos consistem num controlador (normalmente o HD44780, KS0066 ou equivalente), drivers e um display de cristal líquido (LCD). Estes displays são encontrados em diversos tamanhos e com capacidades de apresentação deste 8 caracteres em uma linha até algumas dezenas de caracteres e várias linhas. Nos próximos exemplos veremos como utilizar um módulo LCD de 8 caracteres por 2 linhas para apresentar alguns dados.

Pino Nome RL78 Função 1 VSS - Terra 2 VDD - +5V 3 VO - Contraste 4 RS P5.5 Seleção do registro: comandos (0) ou dados (1) 5 WR/ - Operação de leitura (1) os escrita (0) 6 E P5.4 Pino de habilitação (quando E=1 o display pode receber comandos ou dados) 7 DB0 - Bit 0 comando/dados. Não utilizado no modo de 4 bits 8 DB1 - Bit 1 comando/dados. Não utilizado no modo de 4 bits 9 DB2 - Bit 2 comando/dados. Não utilizado no modo de 4 bits

10 DB3 - Bit 3 comando/dados. Não utilizado no modo de 4 bits 11 DB4 P7.4 Bit 4 comando/dados 12 DB5 P7.5 Bit 5 comando/dados 13 DB6 P7.6 Bit 6 comando/dados 14 DB7 P7.7 Bit 7 comando/dados

Tabela 11.1 – Pinagem do módulo LCD ACM0802

A tabela 11.1 mostra a pinagem do módulo ACM0802 da AZ Displays, utilizado na placa RSK RL78/G13. Este módulo encontra-se conectado ao RL78 através da porta 7 (barramento de dados de 4 bits) e dos pinos P5.5 e P5.4 (RS e ENABLE respectivamente).

Microcontroladores RL78: Guia Básico 272

A comunicação do microcontrolador com o módulo LCD deve seguir um protocolo definido pelo fabricante do chip controlador. A linha RS permite definir se a informação presente no barramento de dados é um dado (RS=1) ou comando (RS=0), R/W permite definir se a operação é uma escrita no display (R/W=0) ou leitura do mesmo (R/W=1) e a linha ENABLE é utilizada para controlar o fluxo de dados com o display.

A tabela 11.2 apresenta a lista de comandos possíveis. No caso da placa RSK, o pino WR/

do display está conectado a um resistor pull-down de 1kΩ, de forma que o módulo somente pode operar no modo de escrita, não sendo possível ler dados do mesmo.

Comando RS R/W D7 D6 D5 D4 D3 D2 D1 D0 Descrição Tempo de Execução

Apaga o display 0 0 0 0 0 0 0 0 0 1 Apaga o display e retorna o cursor para a primeira coluna da primeira linha

1.64ms

Retorno ao início 0 0 0 0 0 0 0 0 1 x Retorna o cursor a primeira coluna da primeira linha e cancela qualquer deslocamento de mensagem

1.64ms

Seleção do modo inicial

0 0 0 0 0 0 0 1 I/D S

I/D – seleciona a direção de deslocamento do display: 1 – desloca o cursor à direita a cada caractere escrito. 0 – desloca o cursor à esquerda a cada caractere escrito. S – liga (S=1) ou desliga (S=0) o deslocamento do display a cada leitura da DDRAM.

40µs

Liga/desliga o display

0 0 0 0 0 0 1 D C B Liga (D=1) ou desliga (D=0) o display, liga (C=1) ou desliga (C=0) o cursor e habilita (B=1) ou desabilita (B=0) a piscagem do cursor.

40µs

Deslocamento do display ou cursor

0 0 0 0 0 1 S/C R/L x x

S/C – seleciona entre o deslocamento do cursor (S/C=0) e o deslocamento do cursor e mensagem (S/C=1). R/L – direção do deslocamento: direita (R/L=1) ou esquerda (R/L=0).

40µs

Configuração 0 0 0 0 1 DL N F x x

DL – largura do barramento: 8 bits (DL=1) ou 4 bits (DL=0). N – número de linhas: uma linha (N=0) ou duas linhas (N=1). F – tamanho do caractere: 8x5 (F=0) ou 10x5 (F=1).

40µs

Seta endereço CGRAM

0 0 0 1 A A A A A A Especifica o endereço corrente de 6 bits da CGRAM. 40µs

Seta endereço DDRAM

0 0 1 A A A A A A A Especifica o endereço corrente d 7 bits da DDRAM

40µs

Lê o contador de endereços (AC) e o busy flag

0 1 BF AC6

AC5

AC4

AC3

AC2

AC1

AC0

Lê o conteúdo do contador de endereços (AC) e o estado do busy flag (BF): BF = 1, controlador ocupado. BF = 0, controlador disponível.

40µs

Escreve um dado na DDRAM ou CGRAM

1 0 D7 D6 D5 D4 D3 D2 D1 D0 Escreve um dado no endereço atual da CGRAM ou DDRAM apontada pelo registrador AC. 40µs

Lê um dado da DDRAM ou CGRAM

1 1 D7 D6 D5 D4 D3 D2 D1 D0 Lê um dado do endereço atual da CGRAM ou DDRAM apontada pelo registrador AC. 40µs

Tabela 11.2 – Comandos do controlador HD44780

Exemplos de Aplicação 273

Figura 11.1

A figura 11.1 apresenta a tabela padrão de caracteres disponível na maioria dos módulos LCD vendidos no Brasil. Observe que a maioria dos caracteres possui o mesmo código da tabela ASCII. Os caracteres com códigos 0x00 a 0x0F são gerados conforme os dados armazenados na RAM do gerador de caracteres (CGRAM). Mais adiante veremos como programar caracteres e símbolos especiais nestas posições

O controlador HD44780 e os seus compatíveis apresentam uma pequena quantidade de memória RAM interna destinada ao armazenamento dos dados a serem apresentados (DDRAM) e ao gerador de caracteres de usuário (CGRAM). A figura 11.2 apresenta a organização dos endereços da DDRAM e a sua relação com a tela do display.

Microcontroladores RL78: Guia Básico 274

Linha Endereço

0 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

1 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83

2 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39

3 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

Figura 11.2 – Endereços da DDRAM

Para apresentar um caractere na segunda linha e terceira coluna do display é necessário configurar o endereço da DDRAM (através do registrador AC do controlador) para o endereço 66 decimal.

Para facilitar a utilização do módulo LCD, incluímos um conjunto de funções dedicadas especificamente ao controle do display. Este conjunto de funções encontra-se dentro do arquivo “lcd_8x2.c” que é utilizado por outros exemplos no decorrer deste capítulo. Este arquivo deve estar localizado na mesma pasta onde encontra-se o código fonte da aplicação. //************************************************************************

//* LCD.C - Biblioteca de manipulação de módulo LCD no RL78

//* Autor: Fábio Pereira

//************************************************************************

// As definições a seguir são utilizadas para acesso aos pinos do display

#ifndef PIN_LCD_EN

#define PIN_LCD_EN P5_bit.no4 // pino enable do LCD

#define PIN_LCD_EN_DIR PM5_bit.no4 // direção do pino enable

#define PIN_LCD_RS P5_bit.no5 // pino rs do LCD

#define PIN_LCD_RS_DIR PM5_bit.no5 // direção do pino rs

#define PORT_LCD_DATA4 P7

#define PORT_LCD_DATA4_DIR PM7

#endif

#define CPU_CLOCK 32000

// Endereço da segunda linha na RAM do LCD

#define LCD_LIN2 0x40

// Definições utilizadas para configuração do display

#define CURSOR_ON 2

#define CURSOR_OFF 0

#define CURSOR_BLINK 1

#define CURSOR_FIXED 0

#define DISPLAY_ON 4

#define DISPLAY_OFF 0

#define DISPLAY_8x5 0

#define DISPLAY_10x5 4

#define _2LINES 8

#define _1LINE 0

//**************************************************************************

//* Função de atraso (aproximadamente em ms)

//**************************************************************************

void LCD_delay_ms(unsigned char time)

unsigned int temp;

Exemplos de Aplicação 275

for (;time;time--) for (temp=CPU_CLOCK/9;temp;temp--) __no_operation();

//**************************************************************************

//* Função de envio de um nibble para o display

//**************************************************************************

void LCD_send4(char data)

// coloca os quatro bits nas saídas

PORT_LCD_DATA4 = data & 0x0F;

// pulsa a linha enable

PIN_LCD_EN = 1;

PIN_LCD_EN = 0;

//**************************************************************************

//* Escreve um byte no display

//**************************************************************************

//* Argumentos de chamada:

//* char endereco : 0 se instrução, 1 se dado

//* char dado : dado ou comando a ser escrito

//**************************************************************************

void LCD_send8(char addr, char data )

// configura a linha rs dependendo do modo selecionado

PIN_LCD_RS = addr;

LCD_delay_ms(1);

// envia a primeira parte do byte

LCD_send4(data >> 4);

// envia a segunda parte do byte

LCD_send4(data & 0x0f);

//**************************************************************************

//* Inicializa o display

//**************************************************************************

//* Argumentos de chamada:

//* char modo1 : modo do display (número de linhas e tamanho dos caracteres

//* char modo2 : modo do display (estado do cursor e do display)

//**************************************************************************

void LCD_init(char md1, char md2 )

unsigned char temp;

// configura os pinos como saídas

PIN_LCD_EN_DIR = 0;

PIN_LCD_RS_DIR = 0;

PORT_LCD_DATA4_DIR = 0xF0;

// coloca os pinos em nível lógico 0

PORT_LCD_DATA4 = 0;

PIN_LCD_RS = 0;

PIN_LCD_EN = 0;

LCD_delay_ms(15);

// envia uma seqüência de 3 vezes 0x03 e depois 0x02 para configurar o

// módulo no modo de 4 bits

for(temp=3;temp;temp--)

LCD_send4(3);

LCD_delay_ms(5);

Microcontroladores RL78: Guia Básico 276

LCD_send4(2);

// envia códigos de inicialização do display

LCD_send8(0,0x20 | md1);

LCD_send8(0,0x08 | md2);

LCD_send8(0,1);

LCD_send8(0,6);

//**************************************************************************

//* Posiciona o cursor no display

//**************************************************************************

//* Argumentos de chamada:

//* char x : coluna a ser posicionado o cursor (iniciando de 0)

//* char y : linha a ser posicionado o cursor (0 ou 1)

//**************************************************************************

void LCD_pos_xy(char x, char y)

unsigned char addr;

addr = y * 64 + x;

LCD_send8(0,0x80|addr);

//**************************************************************************

//* Função de escrita de um caractere no display

//**************************************************************************

//* Argumentos de chamada :

//* char c : caractere a ser escrito

//**************************************************************************

//* Observações :

//* \f apaga o conteúdo do display

//* \n e \r retornam o cursor para a primeira coluna da segunda linha

//**************************************************************************

void LCD_write_char(char data)

// envia um caractere para o display

switch (data)

case '\f' :

LCD_send8(0,1);

LCD_delay_ms(5);

break;

case '\n' :

case '\r' :

LCD_pos_xy(1,2);

break;

default :

LCD_send8(1,data);

//**************************************************************************

//* Escreve uma string no display

//**************************************************************************

//* Argumentos de chamada:

//* char *c : um ponteiro para um caractere

//**************************************************************************

void LCD_write_string (char *data)

while (*data)

Exemplos de Aplicação 277

LCD_write_char(*data);

data++;

Listagem 11.1 – Arquivo lcd_8x2.c

A seguir apresentamos um pequeno exemplo de utilização das funções para manipulação do display LCD da placa RSK do RL78/G13. Este exemplo demonstra como inicializar o display e apresentar mensagens no mesmo.

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

#include "lcd_8x2.c"

// Configura watchdog

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

void main(void)

LCD_init(DISPLAY_8x5|_2LINES,DISPLAY_ON|CURSOR_OFF|CURSOR_FIXED);

LCD_write_string("RL78/G13");

LCD_pos_xy(0,1);

LCD_write_string("LCD 8x2");

while(1);

Exemplo 11.1

Também é possível configurar uma área de memória RAM do controlador de forma a se construir caracteres e símbolos definidos pelo usuário. Esta área de RAM é chamada de CGRAM e é composta de 64 bytes. Cada conjunto de 8 bytes forma um caractere, resultando num máximo de 8 caracteres programáveis pelo usuário. A tabela 11.3 mostra os endereços da CGRAM para cada um dos possíveis caracteres definidos pelo usuário.

Microcontroladores RL78: Guia Básico 278

Caractere do Usuário Código do Caractere Primeiro endereço

CGRAM Último endereço

CGRAM 0 ou 8 0 7 1 ou 9 8 15

2 ou 10 16 23 3 ou 11 24 31 4 ou 12 32 39 5 ou 13 40 47 6 ou 14 48 55 7 ou 15 56 63

Tabela 11.3 – Endereços da CGRAM

A programação de um caractere definido pelo usuário consiste basicamente em se setar o apontador de endereços do controlador de display (AC) para o endereço inicial do caractere desejado e em seguida enviar-se os oito bytes com a representação binária do mesmo.

Bits Dado 7 6 5 4 3 2 1 0

0x1F 0 0 0 1 1 1 1 1 0x1F 0 0 0 1 1 1 1 1 0x1F 0 0 0 1 1 1 1 1 0x1F 0 0 0 1 1 1 1 1 0x1F 0 0 0 1 1 1 1 1 0x1F 0 0 0 1 1 1 1 1 0x1F 0 0 0 1 1 1 1 1 0x1F 0 0 0 1 1 1 1 1

Figura 11.3 – Um caractere definido pelo usuário

11.2. Mostrador Analógico no LCD

O próximo exemplo mostra como utilizar caracteres definidos pelo usuário para construir um mostrador em barra com um “visual analógico”. O gráfico é atualizado a cada 125ms, utilizando o canal 0 da TAU0 e apresenta um barra com tamanho proporcional ao valor lido no canal 6 do conversor A/D. Na placa RSK do RL78/G13 esta entrada está conectada a um trimpot (RV1). Variando-se a posição do mesmo podemos variar o tamanho da barra apresentada no display.

Note que um caractere totalmente preenchido é composto de 5 colunas com todas as 8 linhas preenchidas (como mostra a figura 11.3). Lembre-se de cada caractere é desenhado numa matriz de 5 colunas por 7 linhas (a última linha é normalmente mantida em branco, pois é dedicada ao cursor, que não é utilizado neste exemplo).

O exemplo também demonstra a utilização de um canal DMA configurado para transferir 16 leituras do ADC para um buffer de amostras. Após cada transferência completa do DMA a aplicação calcula a média das mesmas para apresentação no display. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

#include "lcd_8x2.c"

Exemplos de Aplicação 279

// Configura watchdog

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

volatile __saddr struct

unsigned char display_update : 1;

bits;

unsigned int samples[16], result;

const char custom_char[] =

0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // uma coluna

0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // duas colunas

0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, 0x1C, // três colunas

0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, // quatro colunas

0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F // cinco colunas

;

#pragma vector = INTDMA0_vect

__interrupt void trata_DMA_ADC(void)

unsigned char aux;

DRC0 = bDEN; // habilita o DMA0

DBC0 = 16; // número de palavras a transferir

DSA0 = (char)&ADCR; // endereço do registrador fonte

DRA0 = (int)samples; // endereço do buffer para as amostras

// configura o canal de DMA: 16 bits, do SFR para a RAM, disparo pelo ADC

DMC0 = bDS | DMA_TRIG_ADC;

DRC0 = bDEN | bDST; // seta DST para iniciar a transferência

result = 0;

// soma todas as amostras (deslocando-as 6 bits à esquerda)

for (aux=0; aux<16; aux++)

result += samples[aux]>>6;

result >>= 4; // divide o resultado por 16

#pragma vector = INTTM00_vect

__interrupt void trata_TAU0_canal0(void)

bits.display_update = 1; // atualiza o display a cada 125ms

/*

Microcontroladores RL78: Guia Básico 280

Desenha um gráfico de barra no display LCD alfanumérico utilizando

os caracteres especiais criados: | || ||| |||| e |||||

O parâmetro pix é o número de pixels a desenhar

*/

void LCD_bargraph(unsigned char pix)

char cnt = 8; // número máximo de colunas

while (pix)

if (pix>=5) // se restar mais de 5 pixels a desenhar

LCD_write_char(4); // desenha um bloco preto

cnt--; // uma coluna a menos

pix -= 5; // cinco pixels a menos

else // se restar menos de 5 colunas a desenhar

LCD_write_char(pix-1); // desenha um bloco parcial

pix = 0; // não há mais pixels restantes

cnt--; // uma coluna a menos

// preenche as colunas restantes com espaços

while (cnt--) LCD_write_char(' ');

void init(void)

unsigned char aux;

ADPC = 8; // pinos P20, P21 e P22 no modo analógico

ADCEN = 1; // habilita o ADC

// Configura o ADC (conversões múltiplas, um canal, disparo por software)

ADM0 = ADCLK_DIV16 | ADC_LV0 | bADCE;

ADM1 = ADC_TRIG_SOFT;

ADS = ADC_CH6; // seleciona o canal 6 como entrada do ADC

ADCS = 1; // inicia uma conversão

DRC0 = bDEN; // habilita o DMA0

DBC0 = 16; // número de palavras a transferir

DSA0 = (char)&ADCR; // endereço do registrador fonte

DRA0 = (int)samples; // endereço do buffer para as amostras

// configura o canal de DMA: 16 bits, do SFR para a RAM, disparo pelo ADC

DMC0 = bDS | DMA_TRIG_ADC;

DRC0 = bDEN | bDST; // seta DST para iniciar a transferência

TAU0EN = 1; // habilita a TAU0

TPS0 = TAU_CK0_DIV1024; // CK0=31250Hz, CK1=32MHz, CK2=16MHz e CK3=125kHz

// configura o canal 0 da TAU0 no modo temporizador

TMR00 = TAU_CK0 | TAU_TRIG_SOFT | TAU_MD_TIMER;

TDR00 = 3905; // uma interrupção a cada 125ms no canal 0

TS0L = TAU_CH0; // Dispara o canal 0

LCD_init(DISPLAY_8x5|_2LINES,DISPLAY_ON|CURSOR_OFF|CURSOR_FIXED);

// configura os caracteres especiais na CGRAM

LCD_send8(0,0x40); // aponta para a área da CGRAM

for (aux=0; aux<sizeof(custom_char); aux++)

LCD_send8(1,custom_char[aux]); // envia os dados para o LCD

DMAMK0 = 0; // habilita a interrupção do DMA0

TMMK00 = 0; // habilita a interrupção do canal 0 da TAU0

__enable_interrupt(); // habilita as interrupções do RL78

Exemplos de Aplicação 281

void main(void)

init();

LCD_write_char('\f'); // apaga o display

LCD_pos_xy(0,0); // cursor na coluna 0 da linha 0

LCD_write_string("RL78/G13");

while(1)

if (bits.display_update)

bits.display_update = 0; // apaga o indicador de atualização

LCD_pos_xy(0,1); // cursor na coluna 0 da linha 1

LCD_bargraph(result/25); // desenha o gráfico de barras

Exemplo 11.2

11.3. Termômetro Digital

Neste exemplo demonstramos como utilizar o sensor interno de temperatura do RL78/G13. A aplicação configura o ADC para operar no modo contínuo, convertendo alternadamente a tensão proveniente da referência interna de tensão (1,45V) e do sensor de temperatura integrado.

A tensão de alimentação e a temperatura ambiente são apresentadas no display LCD da placa RSK do RL78/G13.

A tensão de alimentação é determinada através da medição da tensão da referência interna de 1,45V, utilizando os princípios apresentados no tópico 8.3. A medição da tensão de alimentação é necessária para correção do valor lido do sensor de temperatura, conforme mostrado no tópico 8.4.

Este exemplo aproveita diversos conceitos apresentados neste livro e ilustra também uma técnica de formatação de dados para apresentação em display (ou outro meio) utilizando variáveis inteiras para representar valores fracionários.

A aplicação utiliza um valor de offset fixo para a temperatura (variável “toff”). Este valor foi determinado através de ensaio, utilizando como referência um termômetro medindo a temperatura ambiente. Em aplicações profissionais cada placa deveria ser calibrada na linha de produção e o valor de calibração salvo na memória flash. #include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

#include "lcd_8x2.c"

// Configura watchdog

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão

Microcontroladores RL78: Guia Básico 282

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

volatile __saddr struct

unsigned char display_update : 1;

unsigned char adc_channel : 1;

bits;

unsigned int acc_vref, vref, acc_vtemp, vtemp, vdd;

int toff;

unsigned long long_data;

#pragma vector = INTAD_vect

__interrupt void trata_ADC(void)

unsigned int result;

result = ADCR >> 6; // lê o resultado da conversão

// o bit adc_channel controla qual o canal do ADC sendo convertido

if (bits.adc_channel)

// conversão da referência interna de tensão

acc_vref += result - vref; // acumula o novo valor, subtrai a média

vref = acc_vref >> 6; // calcula a média dos 64 últimos valores

ADS = ADC_CH_TEMP; // seleciona o sensor de temperatura

bits.adc_channel = 0;

else

acc_vtemp += result - vtemp; // acumula o novo valor, subtrai a média

vtemp = acc_vtemp >> 6; // calcula a média dos 64 últimos valores

ADS = ADC_CH_REF; // seleciona a referência interna

bits.adc_channel = 1;

#pragma vector = INTTM00_vect

__interrupt void trata_TAU0_canal0(void)

bits.display_update = 1; // atualiza o display a cada 500ms

void init(void)

ADPC = 0; // nenhum pino em modo analógico

ADCEN = 1; // habilita o ADC

// Configura o ADC (conversões múltiplas, um canal, disparo por software)

ADM0 = ADCLK_DIV64 | ADC_LV0 | bADCE;

ADM1 = ADC_TRIG_SOFT;

ADS = ADC_CH_REF; // seleciona a referência interna como entrada do ADC

ADMK = 0; // habilita interrupção do ADC

Exemplos de Aplicação 283

ADCS = 1; // inicia uma conversão

TAU0EN = 1; // habilita a TAU0

TPS0 = TAU_CK0_DIV1024; // CK0=31250Hz, CK1=32MHz, CK2=16MHz e CK3=125kHz

// configura o canal 0 da TAU0 no modo temporizador

TMR00 = TAU_CK0 | TAU_TRIG_SOFT | TAU_MD_TIMER;

TDR00 = 15624; // uma interrupção a cada 500ms no canal 0

TMMK00 = 0; // habilita a interrupção do canal 0 da TAU0

TS0L = TAU_CH0; // Dispara o canal 0

LCD_init(DISPLAY_8x5|_2LINES,DISPLAY_ON|CURSOR_OFF|CURSOR_FIXED);

acc_vref = vref = 0;

acc_vtemp = vtemp = 0;

bits.adc_channel = 1; // ADC convertendo tensão de referência

__enable_interrupt(); // habilita as interrupções do RL78

/*

Esta função escreve um valor inteiro no LCD. Ela utiliza uma formatação

especial para representar um valor fracionário através de inteiros.

Os dígitos de dezenas de milhares, milhares e centenas são impressos,

seguidos do ponto decimal e dos dígitos de dezenas e unidades.

Assim, o valor 1001 é apresentado como 10.01.

*/

void LCD_write_frac_int(unsigned int data)

unsigned char aux, space;

unsigned int sub = 10000;

aux = 0;

space = 1;

while (sub)

aux = 0;

while (data>=sub)

data -= sub;

aux++;

space = 0;

if (!space) LCD_write_char(aux+'0');

sub /= 10;

if (sub==10)

if (space) LCD_write_char('0');

LCD_write_char('.');

space = 0;

if (space) LCD_write_char('0');

void main(void)

init();

LCD_write_char('\f'); // apaga o display

toff = -500; // offset de temperatura (-5 graus)

while(1)

// caso exista uma solicitação de atualização do display

if (bits.display_update)

Microcontroladores RL78: Guia Básico 284

bits.display_update = 0; // apaga o bit de atualização de display

LCD_pos_xy(0,0); // cursor na linha 0, coluna 0

LCD_write_string("V=");

long_data = 148480 / vref; // calcula o VDD

vdd = long_data;

LCD_write_frac_int(vdd); // imprime o VDD (5V = 5.00)

LCD_write_string(" "); // apaga caracteres remanescentes

LCD_pos_xy(0,1); // cursor na linha 1, coluna 0

LCD_write_string("T=");

// calcula a temperatura atual

long_data = 2500 - ((long)vtemp*(long)vdd*100 - 10752000)/368 + toff;

LCD_write_frac_int(long_data); // imprime a temperatura

LCD_write_string(" "); // apaga caracteres remanescentes

Exemplo 11.3

11.4. Medidor de Distância por Ultrassom

Este exemplo demonstra como utilizar o modo de captura de nível da TAU para medir a largura de pulso de um sensor de distância ultrassônico (HC-SR04) e com isso determinar a distância de um objeto em relação ao sensor.

O sensor HC-SR04 é um módulo de baixo custo e fácil utilização. Ele possui um conector de 4 pinos (VCC, Trig, Echo e GND), opera com tensão de 5V e fornece uma saída digital com largura proporcional a distância entre o sensor e o objeto posicionado a sua frente.

Figura 11.4

A operação do sensor é bastante simples: basta gerar um pulso de disparo no pino Trig (duração mínima de 10µs) e aguardar pelo retorno do eco do ultrassom. O próprio módulo irá gerar um trem de pulsos com frequência na faixa dos 40kHz e processar o sinal de retorno dos mesmos.

O sinal de saída do sensor é apresentado no pino Echo e consiste num pulso ativo em nível lógico “1” com largura igual ao tempo entre a transmissão e a recepção do eco. O cálculo da distância pode ser facilmente realizado através da seguinte fórmula:

Exemplos de Aplicação 285

2

retorno_pulso*340)m(DIST =

Assim, se o pulso tiver uma largura de 1000µs, o alvo estará a 0,17m do sensor. Para obter a distância em cm:

58

retorno_pulso)cm(DIST =

Note que, para o cálculo, o pulso deverá sempre ser medido em µs. A seguir apresentamos a listagem do exemplo completo. O pino TRIG do módulo HC-SR04 deve ser conectado ao pino P4.1 do RL78 e o pino ECHO deve ser conectado ao pino P4.2 (entrada TI04) do RL78.

Figura 11.5

#include "ior5f100le.h"

#include "ior5f100le_ext.h"

#include "intrinsics.h"

#include "myRL78.h"

#include "lcd_8x2.c"

// Configura watchdog

#pragma location = "OPTBYTE"

__root __far const char opbyte0 = WDT_OFF;

// Configura detector de baixa tensão

#pragma location = "OPTBYTE"

__root __far const char opbyte1 = LVD_OFF;

// oscilador 32MHz flash high speed

#pragma location = "OPTBYTE"

__root __far const char opbyte2 = FLASH_HS | CLK_32MHZ;

// debug ativado, com apagamento em caso de falha de autenticação

#pragma location = "OPTBYTE"

__root __far const char opbyte3 = DEBUG_ON_ERASE;

Microcontroladores RL78: Guia Básico 286

/* Configura security ID */

#pragma location = "SECUID"

__root __far const char senha[10] = 0,0,0,0,0,0,0,0,0,0;

#define TRIGGER P4_bit.no1

volatile unsigned int interval;

unsigned long distance;

volatile __saddr struct

unsigned char display_update : 1;

unsigned char echo_received : 1;

unsigned char trig_mode : 1;

unsigned char aux : 1;

bits;

#pragma vector = INTTM00_vect

__interrupt void trata_TAU0_canal0(void)

if (bits.trig_mode)

TRIGGER = 1;

TDR00 = 9; // intervalo de 10us para o disparo

TS0L = TAU_CH0;

bits.echo_received = 0;

else

TRIGGER = 0;

TDR00 = 0xFFFF;

TS0L = TAU_CH0;

if (!bits.echo_received) interval=0xFFFF;

bits.trig_mode = !bits.trig_mode;

#pragma vector = INTTM04_vect

__interrupt void trata_TAU0_canal4(void)

interval = TDR04; // salva o valor capturado

bits.echo_received = 1; // sinaliza que recebeu um pulso de eco

bits.aux = !bits.aux;

if (bits.aux) bits.display_update = 1; // atualiza o display

/*

Esta função escreve um valor inteiro no LCD. Ela utiliza uma formatação

especial para representar um valor fracionário através de inteiros.

Os dígitos de dezenas de milhares, milhares e centenas são impressos,

seguidos do ponto decimal e dos dígitos de dezenas e unidades.

Assim, o valor 1001 é apresentado como 10.01.

*/

void LCD_write_frac_int(unsigned int data)

unsigned char aux, space;

unsigned int sub = 10000;

aux = 0;

space = 1;

while (sub)

aux = 0;

Exemplos de Aplicação 287

while (data>=sub)

data -= sub;

aux++;

space = 0;

if (!space) LCD_write_char(aux+'0');

sub /= 10;

if (sub==10)

if (space) LCD_write_char('0');

LCD_write_char('.');

space = 0;

if (space) LCD_write_char('0');

void TAU_init(void)

TAU0EN = 1; // habilita a TAU0

TPS0 = TAU_CK0_DIV32; // CK0=1MHz, CK1=32MHz, CK2=16MHz e CK3=125kHz

// configura o canal 0 da TAU0 no modo temporizador

TMR00 = TAU_CK0 | TAU_TRIG_SOFT | TAU_MD_ONECOUNT;

TDR00 = 9; // intervalo inicial de 10us

// configura o canal 4 da TAU0 no modo de captura de ciclo ativo

TMR04 = TAU_CK0|TAU_EDGE_RISE_FALL|TAU_TRIG_BOTH_EDGE|TAU_MD_CAPTURE_LEVEL;

TS0L = TAU_CH4 | TAU_CH0; // Arma os canais 0 e 4

TMMK00 = 0; // habilita a interrupção do canal 0 da TAU0

TMMK04 = 0; // habilita a interrupção do canal 4 da TAU0

void SYS_init(void)

PM4_bit.no1 = 0; // P41 como saída (TRIGGER)

TAU_init(); // inicializa a TAU0

LCD_init(DISPLAY_8x5|_2LINES,DISPLAY_ON|CURSOR_OFF|CURSOR_FIXED);

LCD_write_char('\f'); // apaga o display

__enable_interrupt(); // habilita as interrupções do RL78

void main(void)

SYS_init();

LCD_pos_xy(0,0); // cursor na coluna 0 da linha 0

LCD_write_string("Distanc");

TRIGGER = 1; // inicia um pulso de disparo para o módulo de ultrassom

bits.trig_mode = 0;

TS0L = TAU_CH0; // Dispara o canal 0

while(1)

if (bits.display_update)

bits.display_update = 0; // apaga o bit de atualização

LCD_pos_xy(0,1); // cursor na coluna 0 da linha 1

// calcula a distância em cm

distance = ((long)interval*100)/58;

if (distance<=40000) // se a distância for <= 400cm

Microcontroladores RL78: Guia Básico 288

LCD_write_frac_int(distance);

LCD_write_string("cm ");

else LCD_write_string("---.--cm");

Exemplo 11.4

Tabela ASCII 289

A

Tabela ASCII 12. Tabela ASCII

A tabela abaixo mostra o American Standard Code for Information Interchange (ASCII), um padrão internacional para codificação de texto e símbolos. A utilização da tabela é muito simples: supondo a letra “A”, basta localizá-la na tabela. Em seguida pegamos o valor da linha (64 decimal ou 4 hexadecimal) e o valor da coluna (1), assim, o código ASCII para “A” é 41 (hexadecimal) ou 64+1=65 (decimal), o código para DEL é 7F (hexadecimal) ou 112+15=127 (decimal) e assim por diante.

Dec 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Hex 0 1 2 3 4 5 6 7 8 9 A B C D E F

0 0 NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO SI

16 1 DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS US

32 2 SP ! “ # $ % & ‘ ( ) * + , - . /

48 3 0 1 2 3 4 5 6 7 8 9 : ; < = > ?

64 4 @ A B C D E F G H I J K L M N O

80 5 P Q R S T U V W X Y Z [ \ ] ^ _

96 6 ` a b c d e f g h i j k l m n o

112 7 p q r s t u v w x y z | ~ DEL

Microcontroladores RL78: Guia Básico 290

Microcontroladores RL78: Guia Básico 291

Índice Remissivo

!

! .......................................................................................... 71 !! .......................................................................................... 71

#

# .......................................................................................... 28 #pragma

bank.............................................................................. 129 location..................................................................... 75, 78 vector............................................................................ 125

$

$ .......................................................................................... 71 $! .......................................................................................... 71

_

__asm................................................................................... 234 __callt................................................................................... 263 __disable_interrupt() ............................................................ 125 __enable_interrupt() ............................................................. 125 __far ................................................................................. 75, 79 __halt() ................................................................................... 93 __saddr........................................................................... 64, 262 __stop() .................................................................................. 94

7

78K0R .................................................................................... 55

A

ADC .................................................... Consulte Conversor A/D API ....................................................................................... 240 Applilet3............................................................................... 264

CSI ............................................................................... 215 I2C ........................................................................ 223, 226 UART........................................................................... 208

ASCC ..................................................................................... 16 Assembly................................................................................ 46 AVREFM ............................................................................. 182 AVREFP .............................................................................. 182

B

Big Endian.............................................................................. 29 Boot loader ............................................................................. 63 Bootloader ............................................................................ 240 Breakpoint ........................................................................ 47, 48 Buzzer .................................................................................... 98 Bytes de opção ....................................................................... 76

C

Carry ...................................................................................... 57

CCTIMER1............................................................................ 50 CISC .....................................................................17, 30, 55, 65 Clock

fAD ................................................................................ 180 fCLK ................................................................................. 84 fIH ................................................................................... 83 fIL ................................................................................... 84 fMAIN ............................................................................... 83 fMX.................................................................................. 83 fSUB ................................................................................. 84 Gerenciamento ............................................................... 95 Saída .............................................................................. 98

Conversor A/D ......................................................177, 278, 281 Clock............................................................................ 180 Comparador Digital...................................................... 182 Disparo......................................................................... 184 Modo Snooze ............................................................... 187 Pinagem ....................................................................... 179 Referência Interna .................................................186, 281 Sensor de Temperatura ..........................................186, 281 Varredura ..................................................................... 184

CRC ..............................................................................235, 239 C-SPY.................................................................................... 43

D

Dataflash .............................................................................. 240 Debug..........................................................................43, 74, 78 Disassembly ........................................................................... 46 Display LCD ........................................................................ 271

CGRAM................................................................273, 277 Comandos .................................................................... 272 DDRAM....................................................................... 273 Pinagem ....................................................................... 271

DMA.............................................................................253, 278 DSP...................................................................................... 252

E

EEL................................................................................ 44, 240 EEPROM ............................................................................. 240 ELC...............................................................................175, 192 Embedded Workbench ........................................................... 41 EMI...................................................................................... 108 Endereço ilegal...........................................Consulte Reset:IAW ENIAC ................................................................................... 15 EWRL78 ................................................................................ 41

Criando um projeto......................................................... 41 Depuração ...................................................................... 51 Simulação....................................................................... 46

F

FDL...........................................................................44, 62, 240 Flag

AC.................................................................................. 57 CY.................................................................................. 57 Z..................................................................................... 57

Flash Apagamento ................................................................. 240 Gravação ...................................................................... 240

FSL .....................................................................44, 61, 62, 240 FSL_BlankCheck ................................................................. 242

Microcontroladores RL78: Guia Básico 292

FSL_Close ............................................................................241 FSL_Erase ......................................................................61, 242 FSL_GetBlockEndAddr........................................................244 FSL_GetFlashShieldWindow................................................244 FSL_Init................................................................................241 FSL_InvertBootFlag ...............................................................63 FSL_IVerify..........................................................................242 FSL_Open.............................................................................241 FSL_PrepareExtFunctions ....................................................244 FSL_PrepareFunctions..........................................................242 FSL_StandBy........................................................................243 FSL_StatusCheck..................................................................243 FSL_WakeUp .......................................................................244 FSL_Write ............................................................................243

H

Halt ..............................................................Consulte Modo halt Harvard ...................................................................................16 Hitachi ....................................................................................30

I

IE ......................................................Consulte Interrupções: IE IICA......................................................................................224 Instruções

ADD ...............................................................................66 ADDC.............................................................................66 ADDW............................................................................66 AND ...............................................................................67 AND1 .............................................................................71 BC...................................................................................72 BF ...................................................................................72 BH ..................................................................................72 BNC................................................................................72 BNH................................................................................72 BNZ ................................................................................72 BR.............................................................................27, 72 BRK..................................................................59, 73, 123 BT...................................................................................72 BTCLR .....................................................................65, 72 BZ.............................................................................27, 72 CALL........................................................................59, 72 CALLT ................................................. 59, 63, 64, 72, 263 CLR1 ..............................................................................71 CLRB........................................................................25, 65 CLRW.............................................................................66 CMP..........................................................................27, 67 CMP0..............................................................................67 CMPS .............................................................................67 CMPW............................................................................67 DEC ................................................................................68 DECW ............................................................................68 DI..............................................................................58, 74 DIVHU ...........................................................................67 DIVWU ..........................................................................68 EI ..............................................................................58, 74 HALT .......................................................................74, 93 INC ...........................................................................27, 68 INCW .............................................................................68 MACH ......................................................................57, 68 MACHU ...................................................................57, 68 Modos de Endereçamento ...............................................63 MOV...............................................................................65 MOV1.............................................................................71 MOVS.............................................................................65 MOVW ...........................................................................65 MULH ............................................................................67 MULHU..........................................................................67

MULU ............................................................................67 NOP................................................................................73 NOT1..............................................................................71 ONEB.............................................................................65 ONEW............................................................................65 OR ..................................................................................67 OR1 ................................................................................71 POP ........................................................................ 73, 129 PUSH................................................................ 59, 73, 129 RET ................................................................................73 RETB...................................................................... 73, 123 RETI............................................................... 73, 123, 130 ROL................................................................................70 ROLC .............................................................................70 ROLWC .........................................................................71 ROR................................................................................70 RORC.............................................................................70 SAR ................................................................................69 SARW ............................................................................69 SEL RBx........................................................... 58, 73, 130 SET1...............................................................................71 SHL ................................................................................69 SHLW.............................................................................69 SHR ................................................................................68 SHRW ............................................................................69 SKC ................................................................................73 SKH................................................................................73 SKNC .............................................................................73 SKNH.............................................................................73 SKNZ .............................................................................73 SKZ ................................................................................73 STOP ........................................................................74, 94 SUB ................................................................................66 SUBC .............................................................................66 SUBW ............................................................................66 Temporização .................................................................74 XCH ...............................................................................65 XCHW............................................................................65 XOR ...............................................................................67 XOR1 .............................................................................71

Interrupções Bancos de Registradores ...............................................129 CSI ...............................................................................214 DMA ............................................................................256 Externas ........................................................................130 Flags .............................................................................122 IE............................................................................ 58, 122 INTAD .........................................................................183 INTCSI .........................................................................214 INTIIC..........................................................................220 INTIT ...........................................................................136 INTKR..........................................................................133 INTMD.........................................................................253 INTPx...........................................................................130 INTRTC .......................................................................141 INTSREn......................................................................205 INTSRn ........................................................................205 INTSTn.........................................................................205 INTTMmn ....................................................................151 ISR ....................................................... 121, 123, 125, 129 Latência ........................................................................128 LVD..............................................................................101 Mascaramento ..............................................................123 Prioridades....................................................................126 SAU.............................................................. 204, 214, 220 Teclado .........................................................................133 Vetores ................................................................... 63, 123 Watchdog......................................................................105

ISP0........................................................................................58 ISP1........................................................................................58

Microcontroladores RL78: Guia Básico 293

ISR ....................................................Consulte Interrupções:ISR

K

Ki .......................................................................................... 38 KiB......................................................................................... 38 Kibit ....................................................................................... 38

L

Latch ...................................................................................... 24 LIN....................................................................................... 148 Linker..................................................................................... 43 Little endian ......................................................................... 248 Little Endian........................................................................... 29 LVD ....................................................................... 77, 100, 103

Interrupção ................................................................... 101 Reset............................................................................. 100

M

Memória Acesso ilegal .................................................................. 62 Bloco de boot.................................................................. 63 Blocos............................................................................. 61 Dataflash ........................................................................ 62 Espelhamento ................................................................. 60 Mapa ........................................................................ 61, 62 Modelo ........................................................................... 42 Modelo Far ..................................................................... 42 Modelo Near....................................................... 42, 75, 79 Paridade........................................................................ 236

Mi .......................................................................................... 38 MISO ................................................................................... 211 MISRA................................................................................. 235 Modo halt ......................................................................... 30, 93 Modo snooze .......................................................................... 94 Modo stop .............................................................................. 93 MOSI ................................................................................... 211 Multiplicador por hardware .................................................. 251 myRL78.h .............................................................................. 38

N

N: .......................................................................................... 28 NEC ....................................................................................... 30 Nibble..................................................................................... 20

O

OCD......................................................................... 74, 78, 108 Opbyte0.................................................................................. 76 Opbyte1.................................................................................. 77 Opbyte2.................................................................................. 78 Opbyte3.................................................................................. 78 Opcodes.................................................................................. 25 Option byte....................................................................... 48, 76 Oscilador ................................................................................ 78

HOCO ............................................................................ 86 LOCO............................................................................. 87 X1................................................................................... 84 XT1 ................................................................................ 85

P

Pipeline ............................................................................ 30, 74

Pooling..........................................................................106, 120 Princeton ................................................................................ 16 PWM.............................................................................149, 175

R

R5F100LEA........................................................................... 35 RBS0...................................................................................... 57 RBS1...................................................................................... 57 Registradores.......................................................................... 55

A .................................................................................... 55 ADCR .......................................................................... 190 ADLL........................................................................... 190 ADM0 .......................................................................... 188 ADM1 .......................................................................... 189 ADM2 .................................................................... 94, 189 ADPC............................................................111, 114, 178 ADS ............................................................................. 190 ADTES..................................................................191, 238 ADUL .......................................................................... 190 ALARMWH................................................................. 145 ALARMWM................................................................ 144 ALARMWW................................................................ 145 AX ................................................................................. 55 B .................................................................................... 55 Bancos...............................................................56, 57, 129 BC.................................................................................. 55 BCDADJ ...................................................................... 233 C .................................................................................... 55 CKC ..............................................................83, 84, 85, 87 CKSn.............................................................................. 98 CMC ...................................................................84, 85, 88 CRC0CTL.................................................................... 236 CRCD .......................................................................... 239 CRCIN ......................................................................... 239 CS ............................................................................ 56, 60 CSC.....................................................................84, 86, 88 D .................................................................................... 55 DAY............................................................................. 143 DBCn ........................................................................... 256 DE.................................................................................. 55 DMCn ...................................................................257, 258 DRAn........................................................................... 256 DRCn ........................................................................... 258 DSAn ........................................................................... 256 E..................................................................................... 55 EGN0 ........................................................................... 131 EGN1 ........................................................................... 131 EGP0............................................................................ 131 EGP1............................................................................ 131 ES............................................................................. 56, 60 GDIDIS.................................................................111, 115 H .................................................................................... 55 HIOTRM...........................................................86, 91, 239 HL.................................................................................. 55 HOCODIV ..........................................................81, 86, 90 HOUR .......................................................................... 143 IAWCTL................................................................ 62, 237 IFxH............................................................................. 122 IFxL ............................................................................. 122 IICAn ........................................................................... 228 IICCTLn0..................................................................... 228 IICCTLn1..................................................................... 230 IICCWHn..................................................................... 231 IICCWLn ..................................................................... 231 IICFn............................................................................ 230 IICSn............................................................................ 229 ISC ................................................................173, 202, 208 ITMC ........................................................................... 137

Microcontroladores RL78: Guia Básico 294

KRM .............................................................................133 L .....................................................................................55 LVIM....................................................................100, 102 LVIS .............................................................................102 MACR ......................................................................57, 68 MACRH..........................................................................57 MACRL..........................................................................57 MDAH..........................................................................252 MDAL ..........................................................................252 MDBH ..........................................................................252 MDBL...........................................................................252 MDCH ..........................................................................252 MDCL...........................................................................252 MDUC ..........................................................................253 MIN ..............................................................................142 MKxH...........................................................................123 MKxL ...........................................................................123 MONTH........................................................................144 NFEN0..........................................................................202 NFEN1..........................................................................173 NFEN2..........................................................................173 OSMC.................................................................86, 87, 89 OSTC........................................................................85, 89 OSTS ........................................................................85, 89 PC .............................................................................56, 58 PER0............................................... 95, 136, 178, 202, 225 PGCRCL.......................................................................235 PIMx.............................................................................110 PIOR .....................................................................111, 116 PMC..........................................................................56, 60 PMCx............................................................ 110, 114, 179 PMx ..............................................................................110 POMx ...........................................................................110 PR0xH ..................................................................126, 127 PR0xL...................................................................126, 127 PR1xH ..................................................................126, 127 PR1xL...................................................................126, 127 PSW.......................................................... 56, 57, 122, 130 PUx...............................................................................110 Px..................................................................................110 RESF....................................................... 83, 100, 105, 238 RPECTL .......................................................................236 RTCC0..........................................................................141 RTCC1..........................................................................142 RXD0............................................................................204 RXD1............................................................................204 RXD2............................................................................204 RXD3............................................................................204 SCRmn .........................................................................197 SDRmn .........................................................................198 SEC...............................................................................142 SEm ..............................................................................200 SEmL............................................................................200 SIOp..............................................................................211 SIRmn...........................................................................198 SIRmnL ........................................................................198 SMRmn.........................................................................196 SOEm ...........................................................................200 SOEmL .........................................................................200 SOLm ...........................................................................201 SOLmL .........................................................................201 SOm..............................................................................201 SOmL ...........................................................................201 SP .............................................................................56, 58 SPH.................................................................................59 SPL .................................................................................59 SPSm ............................................................................196 SPSmL..........................................................................196 SSCm..............................................................95, 201, 208 SSCmL .........................................................................201

SSm ..............................................................................199 SSmL............................................................................199 SSRmL .........................................................................199 SSRmn..........................................................................199 STm..............................................................................200 STmL............................................................................200 SUBCUD......................................................................144 SVAn............................................................................228 TEm..............................................................................170 TEmL ...........................................................................170 TIS0...................................................................... 171, 239 TMRmn ........................................................................168 TOEm...........................................................................172 TOEmL.........................................................................172 TOLm...........................................................................172 TOLmL.........................................................................172 TOm .............................................................................172 TOmL...........................................................................172 TOMm..........................................................................173 TOMmL .......................................................................173 TPSm............................................................................167 TSm..............................................................................170 TSmL............................................................................170 TSRmn .........................................................................169 TSRmnL .......................................................................169 TTm..............................................................................171 TTmL ...........................................................................171 TXD0............................................................................204 TXD1............................................................................204 TXD2............................................................................204 TXD3............................................................................204 Visualização ...................................................................47 WDTE ..........................................................................104 WEEK ..........................................................................143 X.....................................................................................55 YEAR ...........................................................................144

Regulador Interno de Tensão ................................................108 Reset.......................................................................................81

IAW.................................................................. 62, 82, 238 LVD................................................................................82 Paridade .................................................................. 82, 236 Pino ................................................................................81 POR ................................................................................81 RPE ................................................................................82 Trap ........................................................................ 82, 238 Vetor...............................................................................81 Watchdog................................................................ 82, 104

RFP ..................................................................................52, 79 RISC.................................................................................17, 65 RL78/D1x...............................................................................32 RL78/F1x ...............................................................................32 RL78/G12...............................................................................31 RL78/G13...............................................................................31 RL78/G14...............................................................................31 RL78/G1A..............................................................................31 RL78/G1C ..............................................................................31 RL78/I1x ................................................................................32 RL78/L12 ...............................................................................32 RL78/L13 ...............................................................................32 RTOS ...................................................................................121

S

SAR......................................................................................178 SAU......................................................................................193

Canais ...........................................................................194 CSI ....................................................................... 193, 211

Baud rate ...................................................................214 Modos .......................................................................213

Microcontroladores RL78: Guia Básico 295

FDC.............................................................................. 206 I2C ....................................................................... 193, 216

Baud rate ................................................................... 221 Endereçamento.......................................................... 221 Parada ....................................................................... 223 Partida ....................................................................... 221 Partida Repetida ........................................................ 222 Recepção................................................................... 222 Transmissão .............................................................. 222

Pinagem........................................................................ 194 UART........................................................... 193, 203, 269

Baud rate ................................................................... 205 Erros.......................................................................... 205 LIN............................................................................ 208 Snooze....................................................................... 208

SCK...................................................................................... 211 Security ID ............................................................... 63, 74, 266 Semáforos............................................................................... 65 SI ........................................................................................ 211 SO ........................................................................................ 211 Somador ................................................................................. 23 SPI................................................................................ 193, 211 SSEC...................................................................................... 16 Stop ............................................................ Consulte Modo stop

T

TAU Modo de Captura de Ciclo ............................................ 284

Timers Intervalo ............................................................... 136, 267 IT.................................................................................. 136 RD................................................................................ 175

RG................................................................................ 175 RJ ................................................................................. 175 RTC.............................................................................. 138 TAU ............................................................................. 148

Modo Contador de Eventos ....................................... 156 Modo de Captura de Ciclo......................................... 159 Modo de Captura de Período..................................... 158 Modo de Pulso Configurável..................................... 160 Modo Disparo Único................................................. 154 Modo Divisor de Frequência ..................................... 157 Modo Onda Quadrada ............................................... 151 Modo PWM .............................................................. 164 Modo Timer .............................................................. 151 Pinagem .................................................................... 150

U

UART ......................................................Consulte SAU:UART ULA....................................................................................... 15

V

Von Neumann ........................................................................ 16

W

Watchdog................................................................76, 104, 106 Janela ........................................................................... 104

WDT ........................................................... Consulte Watchdog Workspace ............................................................................. 42

Microcontroladores RL78: Guia Básico 296

Microcontroladores RL78: Guia Básico 297

Referências

1. DEAN, A. G., CONRAD J. M. Creating Fast, Responsive and Energy-Efficient Embedded Systems using the Renesas RL78 Microcontroller. USA: Micrium Press, 2012.

2. PEREIRA, F. HCS08 Unleashed: Designer’s Guide to the HCS08 Microcontrollers. USA: Booksurge, 2008.

3. PEREIRA, F. MSP430: Teoria e Prática. São Paulo: Érica, 2005.

4. BORGES DE LIMA, C. Técnicas de Projetos Eletrônicos com os Microcontroladores AVR. Florianópolis: Ed. Do autor, 2010.

5. GANSSLE, J. The Firmware Handbook: The Definitive Guide to Embedded Firmware Design and Applications. USA: Elsevier, 2004.

6. FUJISAWA, Y. The Introduction to the H8 Microcontroller. Japan: Ohmsha Ltd, 2003.

7. PREDKO, M. Handbook of Microcontrollers. USA: McGraw-Hill, 1999.

Manuais (download em www.renesas.com)

8. RL78/G13 User’s Manual: Hardware. R01UH0146EJ0210 Rev.2.10, 2012

9. RL78 family User’s Manual: Software. R01US0015EJ0100 Rev.1.00, 2011

10. RL78/G12 User’s Manual: Hardware. R01UH0200EJ0110 Rev.1.10, 2012

11. RL78/G14 User’s Manual: Hardware. R01UH0186EJ0100 Rev.1.00, 2011

12. 78K0R User’s Manual: Instructions. R01US0029EJ0600 Rev.6.00, 2011

Notas de Aplicação (download em www.renesas.com)

13. AN0603: RL78 Window Watchdog Timer. R01AN0603ED0100, 2011

14. AN0749: RL78 Family VDE Certified IEC60730/60335 Self Test Library. R01AN0749EG0100, 2011

15. AN0814: Minimizing Power Consumption when Sensing Switch Inputs. R01AN0814EU0100, 2012

16. AN0956: RL78/G13 Safety Function (Frequency Detection). R01AN0956EJ0100, 2012

17. AN0988: RL78 Internal Temperature Sensor Calibration. R01AN0988EU0100, 2012

Outros Documentos Eletrônicos

18. UM10204: I2C bus specification and user manual Rev. 5. Disponível em: http://www.nxp.com/documents/user_manual/UM10204.pdf . NXP, 2012