Anda di halaman 1dari 145

Microcontroladores AVR

Baseado no ATmega328
Prof. Eduardo G. Bertogna
DAELN/UTFPR

1
Sistema Microprocessado Mínimo

• Microprocessador;

• Circuito de Clock;

• Circuito de Reset;

• Circuito de Seleção;

• Memória de Programa - Somente de Leitura, não-volátil;

• Memória de Dados - Leitura e Escrita, volátil

• Portas de Entrada e Saída;

• Fonte de Alimentação.

2
Visão Geral da Família AVR
• Desenvolvido em 1996, no Instituto de Ciência e Tecnolo-
gia da Noruega, por 2 estudantes: Alf-Egil Bogen e Vergard
Wollan, sendo a sigla AVR para Advanced Virtual RISC;

• Possui arquitetura RISC de 8 bits com conceito Harvard, e


pipeline de um nível garantindo assim o paralelismo;

• Conjunto de 133 instruções, a maioria sendo executadas em


um único ciclo de clock;

• 32 registros de uso geral, todos conectados diretamente à


ULA, permitindo que dois registros quaisquer sejam acessados
em um único ciclo de clock ;

• Perto de 32 MIPS, com o clock máximo de 32 MHz: 1MIPS


por MHz, 10x mais rápido que os microcontroladores de ar-
quitetura CISC;

• Memória Flash ISP, 10.000 ciclos de escrita/apagamento;

• Tensões de alimentação em alguns elementos entre 1,8V e


5,5V, e possibilidade de operação em baixo consumo;

• Eciência na geração de código, tanto em C como em as-


sembly, comparável ao CISC;

• Grande suporte de hardware e software para o desenvolvi-


mento, muitos destes de natureza livre e aberta.

3
Elementos da Família AVR
• tinyAVR

• megaAVR

• XmegaAVR

• Battery Management

• Automotive AVR

Família AVR - tinyAVR e megaAVR

• tinyAVR - Entre 6 e 20 pinos de E/S linhas, pe-


quena área de memória Flash (1kB ou 2kB), poucos
periféricos internos, ideal para aplicações de baixa
complexidade, e baixo custo.

• megaAVR -Entre 8kB e 256kB de memória Flash,


entre 23 e 54 pinos de E/S, inúmeros periféricos
internos: Canais de ADC, Canais de PWM, Com-
parador Analógico, Canais TWI/I2C, UART e SPI,
ideal para as aplicações de média complexidade.

4
Componentes das Sub-Famílias tinyAVR, e megaAVR
Modelo* Características Principais
tiny11 1kB Flash, 1 T/C de 8bits, 6 Pinos de E/S.
tiny12 Idem ao tiny11, com 64B de EEPROM.
tiny13 Idem ao tiny12, com 64B de SRAM, e 4 ADC's.
tiny15 Idem ao tiny12, com 4 ADC's.
tiny26 2kB Flash, 128B EEPROM, 128B SRAM, 2 T/C
de 8bits, 16 Pinos de E/S, 11 ADC's de 8bits.
tiny28 2kB Flash, 1 Timer/Counter de 8bits, 20 Pinos de E/S.
tiny2313 2kB Flash, 128B de EEPROM, 128B de SRAM, 2 T/C
(1 de 8bits, 1 de 16bits), 18 Pinos de E/S, 1 Serial.
mega8 8kB Flash, 512B EEPROM, 512B SRAM, 3 T/C (2x8,1x16)
23 Pinos de E/S, 1 Serial, 3 PWM, 8 ADC' s,
mega8515 8kB Flash, 512B EEPROM, 512B SRAM, 2 T/C (1x8,1x16)
35 Pinos de E/S, 1 Serial, 3 Canais de PWM
mega8535 Idem ao mega8515, com 2 Timer/Counter de 8bits,
4 Canais de PWM, 8 ADC's, e 32 Pinos de E/S.
mega16 16kB Flash, 1KB EEPROM, 1KB SRAM, 3 T/C (2x8,1x16)
32 Pinos de E/S, 1 Serial, 6 Canais de PWM, 8 ADC' s,
mega162 Idem ao mega16, c/ 2 T/C de 16bits, 4 Canais de PWM,
2 Canais Seriais, 35 Pinos de E/S, porém sem ADC's.
mega32 Idem ao mega16, c/ 32kB de Flash, 2kB SRAM, 4 PWM.
mega64 64kB Flash, 2kB EEPROM, 4kB SRAM, 4 T/C (2x8,1x16)
54 Pinos de E/S, 2 Serial, 8 Canais de PWM, 8 ADC's.
mega128 Idem ao mega64, com 128kB Flash, 4kB EEPROM.
mega48 4kB Flash, 256B EEPROM, 512B SRAM, 3 T/C (2x8,1x16)
24 Pinos de E/S, 1 Serial, 5 Canais de PWM, 8 ADC's.
mega88 Idem ao mega48, c/ 8kB Flash, 512B EEPROM, 1kB RAM.
mega168 Idem ao mega88, c/ 16kB de Flash.
mega256 Idem ao mega128, c/ 256kB Flash, 8kB SRAM, 16 PWM.

5
Ambientes de Desenvolvimento p/ AVR
• CodeVisionAVR - apenas desenvolvimento em C,
sem simulador/depurador. Através de Wizard gera
código automático, com as congurações dos re-
gistros sendo função da seleção de periféricos es-
colhidos, bastando inserir os trechos de código que
o completam.

6
• AVR Studio 4 e Atmel Studio 7 - desenvolvi-
mento em assembly e C, com simulador/depura-
dor. Freeware fornecido pela Atmel. AVR Studio.
No desenvolvimento em C pode ser usado com o
compilador GNU GCC WinAVR e com o AVR To-
olchain da Atmel.

7
Núcleo da Arquitetura AVR RISC

8
Recursos do ATmega328
131 Instruções (maioria executada em 1 ciclo clock)
32 kB Memória Flash ISP 10.000 ciclos de escrita
2.048 B Memória SRAM
1.024 B Memória EEPROM 100.000 ciclos de escrita
32 Registros de 8 bits de uso geral
23 pinos de I/O programáveis individualmente
2 T/C de 8 bits, c/ prescaler separado e Modo de
Comparação
1 T/C de 16 bits, c/ prescaler separado e Modos de
Comparação e de Captura
6 Canais de PWM
Contador de Tempo Real c/ oscilador independente
Watchdog Timer c/ oscilador independente
6 Conversores A/D de 10-bits (8 ADCs em TQFP/MLF)
Multiplicador por Hardware (2 ciclos de clock)
1 Comparador Analógico
1 Serial TWI compatível c/ I2C Philips
1 USART
1 SPI Master/Slave
2 Interrupções Externas e 23 Interrupções/Wake-Up de I/O
6 Modos de Baixo Consumo
Detecção de Brown-out e Power-On Reset
Oscilador RC Interno Calibrado
Encapsulamentos DIP-28, TQFP-32, MLF-28
Tensões: 1,8V-5,5V
Clock: 0-20 MHz

9
Arquitetura Interna do ATmega328

10
Pinagem do ATmega328 (DIP-28)

Descrição dos Pinos do ATmega328


• Vcc - Tensão de Alimentação de 1,8 a 5,5V

• GND - Referência.

• AVcc - Entrada da Tensão do Conversor A/D, devendo ser


conectado externamente a Vcc. Se o ADC é usado deve ser
conectado a Vcc via ltro passa-baixas.

• AREF - Entrada da Tensão de Referência do Conversor A/D


11
• PORTAS B, C e D (PCINT0...PCINT22) - Todos os 23
pins de E/S das Portas B, C e D possuem a função alternativa
de ativar uma interrupção na mudança de estado do respec-
tivo pino, servindo assim como uma interrupção externa.

• PORTB (PB0...PB7) - Porta de 8 bits bidirecional de E/S.


Cada pino desta porta possui uma função alternativa, ver
tabela abaixo.

Pinos Funções Alternativas


PB0 CLK0 Saída de clock dividido
ICP1 Entrada de Captura do T/C1
PB1 OC1A Saída Comparação A do T/C1
PB2 OC1B Saída Comparação B do T/C1
SS Seleção Master/Slave da SPI
PB3 OC2A Entr. Inv. do Comp. Analógico
MOSI Saída Output/Slave da SPI
PB4 MISO Saída Input/Slave da SPI
PB5 SCK Entrada de Clock da SPI
PB6 XTAL1 Entrada Clock Externo 1
TOSC1 Entrada Clock T/C2 qdo Osc. RC
PB7 XTAL2 Entrada Clock Externo 2
TOSC2 Entrada Clock T/C2 qdo Osc. RC

12
• PORTC (PC0...PC6) - Porta de 7 bits bidirecional de E/S.
Cada pino desta porta possui uma função alternativa, ver
tabela a seguir.

Pinos Funções Alternativas


PC0...PC5 ADC0...ADC5 Entradas conversores A/D
PC4 SDA Entrada/Saída de Dados da I2C
PC5 SCL Entrada/Saída de Clock da I2C
PC6 RESET Entrada de Reset

• PORTD (PD0...PD7) - Porta de 8 bits bidirecional de E/S.


Cada pino desta porta possui uma função alternativa, ver
tabela a seguir.

Pinos Funções Alternativas


PD0 RXD Entrada de Recepção Serial
PD1 TXD Saída de Transmissão Serial
PD2 INT0 Entrada Interrupção Externa INT0
PD3 INT1 Entrada Interrupção Externa INT1
OC2B Saída de Comparação B do T/C2
PD4 T0 Entrada Contagem do T/C0
XCK Entrada/Saída Clock Externo da USART
PD5 T1 Entrada Contagem do T/C1
OC0B Saída de Comparação B do T/C0
PD6 AIN0 Entrada Positiva Comparador Analógico
OC0A Saída de Comparação A do T/C0
PD7 AIN1 Entrada Negativa Comparador Analógico

13
Placas da Família Arduino AVR

Pinagem do ATmega328p em relação Placa Arduino


Uno/Nano

Aduino - Pino ATmega328p Aduino - Pino ATmega328p


D0 PD0 D8 PB0
D1 PD1 D9 PB1
D2 PD2 D10 PB2
D3 PD3 D11 PB3
D4 PD4 D12 PB4
D5 PD5 D13 PB5
D6 PD6 A0..A5 PC0...PC5
D7 PD7 VIN ARef

14
Placa Atmel Xplained328

Gravadores ISP

15
Sistema de Clock do ATmega328

• Seleciona a fonte primária de clock de 5 fontes: Cristal Ex-


terno, Osc. RC Interno e Clock Externo. Fornece os sinais
de clock derivados da fonte primária;
16
• Sinais de clock derivados da fonte primária:

Clk CPU Núcleo AVR e RAM


Clk IO Módulo de E/S, T/C's, Canal SPI, e UART;
Clk Flash Memória Flash, ativado junto c/ clock da CPU;
Clk ADC Conversor A/D;
Clk ASY T/C2 clock assíncrono

• Arbitra a ativação dos sinais de clock, acima, não necessaria-


mente ativos simultaneamente, em razão dos modos de baixo
consumo.

Fontes de Sinal de Clock


São 5 diferentes possibilidades para a fonte de geração de sinal de
clock, listadas a seguir:

• Cristal/Ressonador Cerâmico Externo;

• Cristal de Baixa Freqüência Externo;

• Fonte de Clock Externa;

• Oscilador RC Interno de 128 kHz;

• Oscilador RC Interno Calibrado.

17
Seleção da Fonte Primária de Clock - Fuse-bits CKSEL3...0
A fonte primária de clock é selecionada quando da programação
do dispositivo, através dos fuse-bits CKSEL3...0 :

CKSEL3...0 Fonte de Clock Selecionada


1111-1000 Cristal Externo Baixa Potência
0111-0110 Cristal Externo Excursão Completa
0101-0100 Cristal Externo de Baixa Frequência
0011 Oscilador RC Interno de 128 kHz
0010 Oscilador RC Interno Calibrado
0000 Clock Externo
Seleção default de fábrica é p/ Oscilador RC interno

Obs: Maior atraso de inicialização (start-up time), possibilita usar


qualquer métodos de gravação ISP disponível.

Fontes Externas de Clock


• Cristal Quartz Oscilador - Figura (a)

 Pinos XTAL1/XTAL2: Entrada/Saída do amplicador in-


versor usado como oscilador interno.

 O cristal oscilador e dois capacitores, ou um ressonador


cerâmico devem ser conectados conforme a gura (a).

• Fonte de Clock Externa - Figura (b)


 Pino XTAL1: Entrada de fonte de clock externa;

 Pino XTAL2: Não conectado, conforme gura (b).

18
Oscilador Interno Calibrado
• Quando se deseja minimizar o uso de componentes externos,
e existe uma certa tolerância na precisão do sinal de clock;

• Por default 8 MHz a 25ºC e Vcc=3V ±10%, ou calibrado pelo


usuário de 7,3 a 8,1 MHz ±1%;

• Precisão é dependente de temperatura e tensão de alimenta-


ção;

• Registro de Calibração OSCCAL permite ajustar a calibração


do oscilador RC Interno, no Reset um valor associado ao byte
de assinatura é carregado neste registro.

Start-up do Oscilador Interno Calibrado


Os tempos de inicialização do Oscilador RC Interno, é feita através
dos fuse-bits SUT1 e SUT0:

Start-up Time para Oscilador Interno (Vcc=5V)


SUT0 Start-Up Time Adicional Recomen-
SUT1 após Power-Down após Reset* dação
00 6 Clocks 14 Clks BOD Habilit.
01 6 Clocks 14 Clk + 4,1 ms Fonte Rápida
10 6 Clocks 14 Clk + 65 ms Fonte Lenta
11 Reservado
19
Circuito de Reset

• Faz a carga dos Registros de E/S com seus valores iniciais e


carrega o PC com o vetor de Reset: 0000H;

• Após sua ativação, um atraso de tempo, Start-Up Time, é


gerado conforme seleção dos fuse-bits CKSEL3...CKSEL0;

• A execução do programa inicia no endereço RESET, e uma


instrução de desvio desvia a execução p/ a rotina principal.

• Modo de operação do Circ. de Reset, depende dos bits


de controle: WDRF , BORF , EXTRF , e PORF , do Reg.
MCUSR.

20
Fontes de Ativação do Reset

• Sinal de Ativação Externo: sinal de nível lógico


baixo por mais de 50ns no pino de RESET;

• Power-On Reset: tensão Vcc abaixo da tensão


limite de Power-On Reset (Power-On Threshold) -
VP OT , tipicamente entre 1,4V e 2,3V;

• Watchdog Timer Reset: período programado no


Temporizador Watchdog expira antes da instrução
WDR ser executada, com o WDT habilitado;

• Brown-Out Reset: tensão Vcc abaixo de um valor


limite, (Brown-Out Threshold) VBOT , c/ o detec-
tor de Brown-Out (BOD) habilitado pelo fuse bit
BODEN.
 VBOT é selecionada pelo fuse-bit BODLEVEL: Progra-
mado - VBOT = 4, 0V
Desprogramado, VBOT = 2, 7V .

 Por default BODEN estará desprogramado

 Bits BODSE e BODS no registro MCUCR permite desli-


gar o circuito de BOD em modo Sleep.

21
Registro de e Status da CPU - MCUSR
MCUSR
    WDRF BORF EXTRF PORF

• Bit PORF : Power-On Reset Flag, Sinalizador de


Power-On Reset, setado no Power-On, e resetado
somente por software;

• Bit EXTRF : External Reset Flag, Sinalizador de


Reset Externo, setado no reset externo e resetado
unicamente por software;

• Bit BORF : Brown-Out Reset Flag, Sinalizador de


Brown-Out Reset, setado no reset por Brown-Out,
e resetado por software ou Power-On;

• Bit WDRF : Watchdog Reset Flag, Sinalizador de


Watchdog Reset, setado pelo reset do WDT, e re-
setado por software ou no Power-On.

22
Registro de Controle da CPU - MCUCR
MCUCR
- BODS BODSE PUD - - IVSEL IVCE

• Bit IVSEL: Interrupt Vector Selection, setado move


os vetores de interrupção p/ o início do setor de
boot;

• Bit IVCE: Interrupt Vector Change Enable, setado


habilita a função do bit IVSEL. Resetado por hard-
ware 4 ciclos de clock após ter sido setado, ou
quando IVSEL é setado.

• Bit PUD: Pull-Up Disable, setado desabilita todos


os pull-ups em todos os pinos das portas;

• Bit BODSE: BOD Sleep Enable, setado permite


que o bit BODS desligue o circuito de detecção de
Brown-out durante estado Sleep;

• Bit BODS: Deve ser setado para desligar o circuito


de detecção de Brown-out durante estado alguns
modos Sleep;
23
Modos de Baixo Consumo - Sleep Modes
O modo de baixo consumo é ativado se o bit de Habilitação do
Modo Sleep, SE =1 (registro SMCR), e uma instrução SLEEP for
executada.

Modo Idle
- CPU é parada;
- Periféricos e Interrupções continuam funcionando;
- CPU retorna do modo Idle ao ocorrer uma destas interrupções;
- Circuito de BOD não pode ser desativado neste modo.

Modo Power-Down
- Oscilador externo é parado;
- Circuitos dos TWI, WDT, e Interrupções, permanecem funcio-
nando;
- Retorno do Power-Down através de uma interrupção destes cir-
cuitos, de um Reset externo, ou Reset por Brown-out.

Modo Power-Save
- Idêntico ao Power-Down, exceto que T/C2 continua ativo;
- Adicionalmente, pode retornar deste modo por interrupções do
T/C2;
- Se o T/C2 não será usado recomenda-se o modo Power-Down.

Modo Standby
- Idêntico ao Power-Down, exceto que o oscilador externo se man-
tém funcionando;
- Somente possível de ser usado com Cristal/Ressonador externo.

Modo Standyby Extendido


- Idêntico ao modo Power-Save, exceto que o oscilador externo se
mantém funcionando.
- Somente possível de ser usado com Cristal/Ressonador externo.

24
Reg. de Controle dos Modos de Sleep -
SMCR
SMCR
    SM2 SM1 SM0 SE

• Bit SE: Sleep Enable, setado bit permite que o AT-


mega328 entre em dos 5 modos de baixo consumo
disponíveis após a execução da instrução SLEEP.

• Bits SM0...SM2: Modos Sleep, seleciona um dos 5


modos de operação sleep conforme tabela abaixo.

Modos de Baixo Consumo


SM2 SM1 SM0 Modo
0 0 0 Modo Idle
0 0 1 Redução de ruído do ADC
0 1 0 Modo Power-down
0 1 1 Modo Power-save
1 0 0 Reservado
1 0 1 Reservado
1 1 0 Modo Standby
1 1 1 Modo Standby extendido

25
Registro de Status da CPU - SREG
SREG
I T H S V N Z C

• Flag T : Bit de alocação temporária usado p/ teste em bits,


através das instruções BLD e BST;

• Flag H: Half-Carry, vai-um do nibble inferior p/ o superior;

• Flag S: Indica o resultado: N ⊕V

• Flag V : Overow, indica se o byte sinalizado em complemento


de 2, está na faixa de -127 a 128;

• Flag N: Resultado negativo em operação aritmética/lógica;

• Flag Z: Resultado zero em operação aritmética/lógica;

• Flag C : Ocorrência de vai-um, em uma operação aritmética/-


lógica.

• Bit I : Setado p/ que qualquer fonte de interrupção possa ter


efeito.

Exemplo de declaração em C no WinAVR para habilitar e


desabilitar interrupções:
#include
...
<a v r / i n t e r r u p t . h> // Arq . h e a d e r i n t e r r u p .
/* D e s a b i l i t a i n t e r r u p ç õ e s */
cli ();
...
/* H a b i l i t a i n t e r r u p ç õ e s */
sei ();
26
Stack Pointer - SPH/SPL
• Pilha: região da SRAM onde endereços de retorno
de rotinas/rotinas de interrupção são guardados
pela CPU qdo ocorre uma chamada de rotina/ou
atendimento de um pedido de interrupção.

• Ao término da execução da rotina/rotina de inter-


rupção, o endereço de retorno é buscado na pilha,
e o programa retorna a execução do ponto onde es-
tava antes da chamada de rotina/atendimento da
interrupção.

• No ATmega328 o SP é designado por: SPH e SPL,


e que respectivamente guardam o byte superior e o
byte inferior do endereço da pilha.

• SPL/SPH devem ser sempre inicializados no início


do programa principal, sempre que subrotinas e/ou
interrupções são usadas

• A inicialização deverá conter um endereço acima de


0060H, que é o limite inferior da SRAM interna.

• Como prática comum o limite superior da SRAM é


utilizado, uma vez que o endereço será decremen-
tado em operações de escrita na pilha.
27
Organização de Memória do
ATmega328
Memória SRAM

• A área de memória SRAM Interna de 2.048 bytes


aloca a área dos Registros de Uso Geral e de E/S,
de forma contiguas, como na gura a seguir.

• R0 a R31 não se entrelaça com a área de SRAM


que começa no endereço 001FH.

• R26 a R31, proporcionam aos pares ponteiros para


acesso indireto à memória de dados, sendo deno-
minados de registros X, Y, e Z.

28
Memória FLASH
• Memória Flash de 32 kB, organizada como 16 kW,
instruções de 16 ou 32 bits, e PC de 14 bits.

• Programa Boot Loader, alocado na Seção de Boot,


possibilita carga/descarga de código, por qualquer
meio ou protocolo de comunicação disponível.

• Capacidade de autoprogração, atualização de apli-


cações, e até mesmo atuar na área do Boot Loa-
der, modicando-se a si próprio, ou mesmo se apa-
gando, caso não seja mais necessário.
29
Registros de E/S do ATmega328
Recursos Siglas Nome do Registro de E/S
Sinalizadores SREG Status Register
Stack Pointer SPH/SPL Stack Pointer
Fonte de Reset MCUSR MCU Status Reg
Brown-out MCUCR MCU Control Reg
Clock do Sist. CLKPR Clock Prescaler Reg
EIRCRA Ext. Interr. Control Reg A
Interrupções Ext. EIMSK Ext. Interr. Mask Reg
EIFR Ext. Interr. Flag Reg
Interrupções TIFR0/1/2 T/Cs Interrupt Flag Regs
dos Temp./Cont. TIMSK0/1/2 T/C Interr. Mask T/C0, 1 e 2
Temp./Cont.0 TCCR0A/TCCR0B T/C0 Control Register A e B
T/C0 (8 bits) TCNT0 T/C0 Counter Register
OCR0A/OCR0B T/C0 Output Comp. Reg A/B
TCCR1A/B/C T/C1Control Reg. A/B/C
Temp./Cont.1 TCNT1H/L T/C1 Reg. High/Low
T/C1 (16 bits) OCR1A/B H/L Output Compare 1A/1B H/L
ICR1H/L Input Capture 1 H/L
TCCR2A/B T/C2 Control Reg. A/B
Temp./Cont.2 TCNT2 T/C2 Reg. High/Low
T/C2 (8 bits) OCR2A/B Output Compare 2A/1B
ASSR Asyncronous Status Reg
GTCCR General T/C Control Reg
EEARH/EEARL EEPROM Address Registers
EEPROM EEDR EEPROM Data Register
EECR EEPROM Control Register
SPCR SPI Control Register
Canal SPI SPSR SPI Status Register
SPDR SPI Data Register

30
Registros de E/S do ATmega328 (cont.)
Recursos Siglas Nome do Registro de E/S
Modos Sleep SMCR Sleep Mode Control Register
Contr. Potência PRR Powe Reduction Register
Watchdog Timer WDTCSR WDT Control & Status Reg
UDRn UART Data Register
Canais USART UCSRnA/B/C UART Control/Status Regs
UCR UART Control Register
UBRRnH/UBRRnL UART Baud Rate Registers
Compar.Analóg. ACSR Analog Comp. Control/Status
ADCL/H ADC Data Registers L/H
Conversor A/D ADCSRA/B ADC Control/Status Reg A/B
ADMUX ADC Multiplexer Selection Reg
TWBR TWI Baud Rate Register
TWCR TWI Control Register
Canais TWI TWSR TWI Status Register
TWDR TWI Data Register
TWAR TWI Address Register
TWAMR TWI Address Mask Register
PORTB
PORTC Port B/C/D Data Regs
PORTD
Portas de E/S DDRB
B, C, e D DDRC Data Direction Registers
DDRD
PINB
PINC Input Pin Address Registers
PIND

31
Portas de Entrada e Saída
• São 3 as portas E/S do ATmega328 designadas como PORTB,
PORTC e PORTD

• Sendo: PORTB de 8 bits, PORTC de 7 bits e PORTD de 8


bits

• 23 linhas de E/S que podem ser usadas como pinos de En-


trada/Saída Digital de uso geral.

• Estas portas de E/S tem resistores de pull-up internos seleci-


onáveis individualmente.

• Buers de saída podem de drenar até 40 mA.

• Os pinos contam ainda com diodos de proteção para Vcc e


GND.

32
Registros Associados às Portas de E/S
• Registros de Direção de Dados - DDRB, DDRC, DDRD

• Registros de Dados - PORTB, PORTC, PORTD

• Pinos de Entrada das Portas - PINB, PINC, PIND

Porta Sigla Nome/Função


PORTB Dados Porta B
B DDRB Direção de Dados B
PINB Entrada do Pino B
PORTC Dados Porta C
C DDRC Direção de Dados C
PINC Entrada do Pino C
PORTD Dados Porta D
D DDRD Direção de Dados D
PIND Entrada do Pino D

Registros de Direção de Dados


(DDRX, X=B,C,D)
DDXn=1 => PORTXn será congurado como Saída.

DDXn=0 => PORTXn será congurado como Entrada.

PUD=0 => PORTXn terá o resistor de pull-up conectado

33
Modos de Operação dos Pinos das Portas

DDRXn PORTXn PUD Pull-UP Descrição da Operação


(DDRX) (PORTX) Interno
0 0 x OFF Entrada em Alta Impedância
0 1 0 ON Entrada fornecendo corrente em 0
0 1 1 OFF Entrada em Alta Impedância
1 0 x OFF Saída drenando corrente
1 1 x OFF Saída fornecendo corrente

• PORTX e DDRX são do tipo R/W, enquanto os PINX são


somente de leitura por serem registros de entrada de dados.

• Pino congurado como entrada - DDRXn=0, com PORTXn=1 ,


terá seu pul-up ativado, desde que PUD =0 em MCUCR (de-
fault de PUD após o Reset - Pull-ups ativos).

• Se o bit PUD =1 (Pull-UP Disable de MCUCR), todos os re-


sistores de Pull-Up serão desabilitados mesmo que DDRXn=0
e PORTXn=1 .

• O pull-up também será desconectado ao se resetar o bit


PORTXn quando entrada, ou congurar este pino como saída.

• Na condição de Reset, os pinos estarão em tri-state (pull-ups


desativados), mesmo sem pulso de clock ativo. Logo após o
Reset os pull-ups são reconectados por default (PUD =1).

• Entradas de pinos não usados não devem ser conectados a


Vcc ou GND para evitar corrente excessiva se congurados
acidentalmente como saída, para garantir isso os pull-ups de-
vem ser deixados em ON (PUD =1).

34
Exemplo de Conguração dos Pinos de E/S
O trecho de programa a seguir, congura os pinos PB0 e PB1
como saídas, e os pinos PB2 a PB7 como entradas, dene o
estado dos pinos PB0, PB1, PB6 e PB7, e então lê o estado da
porta B. Finalmente, escreve nos pinos PB0 e PB1, resetando
PB0 e setando PB1. PB0 e PB1 são denidos como RELE 1 e
RELE 2.

#include <avr/io.h> // Arq. header p/ família AVR

#define RELE_1 0 //Pino conectado ao relê 1


#define RELE_2 1 //Pino conectado ao relê 2

unsigned char i; // ou, ainda: uint8_t i;

int main(void)
{
// Define Pinos PB0, PB1 como saídas, PB2 a PB7 entradas
DDRB |= (1<<DDB1)|(1<<DDB0);

// Define estado dos Pinos PB0, PB1, PB6 e PB7 em nível alto
// e pinos PB2, PB3, PB4 e PB5 em nível baixo
PORTB |= (1<<PB7)|(1<<PB6)|(1<<PB1)|(1<<PB0);

// Leitura dos Pinos da Porta B


i = PINB;

// Leva pino PB0 para nível lógico 0


PORTB &= ~(1<<RELE_1);

// Leva pino PB1 para nível lógico 1


PORTB |= (1<<RELE_2);

return 0;
}

35
Sintaxe para Setar, Resetar, Complementar e
Testar bits em registros

• Setando-se um bit de um registro:


 Aplicar a operação OR do registro alvo com uma máscara de bits
montada com o operador de deslocamento à esquerda do c: <<,
tendo o operando à esquerda o valor 1, e o operando à direita, o
nr. de deslocamentos à esquerda correspondente à posição do bit no
registro.
Exemplo de como se setar o bit 2 (DDRB2 ) do registro DDRB :
7 6 5 4 3 2 1 0
1 0 0 0 0 0 0 0 1
1<<2 _ .
MSK 0 0 0 0 0 1 0 0
Com a máscara MSK como operando da direita do OR, aplica-se
este ao registro alvo:
DDRB |= (1<<DDB2);

• Resetando-se um bit de um registro:


 Aplicar a operação AND, ao invés de OR, do registro alvo com uma
máscara de bits montada como explicado acima, porém complemen-
tada pelo operador de complementação do C: ~ .
Exemplo de como se resetar o bit 2 (DDRB2 ) do registro DDRB :
7 6 5 4 3 2 1 0
1 0 0 0 0 0 0 0 1
~(1<<2) _ .
MSK 1 1 1 1 1 0 1 1
Com a máscara MSK como operando da direita do AND, aplica-se
este ao registro alvo:
DDRB &= ~ (1<<DDB2);

36
• Setando-se mais de um bit de um registro:
 Aplicar a operação OR do registro alvo com múltiplos ORs das várias
máscaras de bits correspondentes aos bits que se deseja setar.
Exemplo de como se setar os bits 2 e 3 (DDRB2 e DDRB3 ) do re-
gistro DDRB :
DDRB |= (1<<DDB3) | (1<<DDB2);

• Resetando-se um bit de um registro:


 Aplicar a operação AND do registro alvo com o complemento dos
múltiplos ORs das várias máscaras de bits correspondentes aos bits
que se deseja resetar.
Exemplo de como se resetar os bits 2 e 3 (DDRB2 e DDRB3 ) do
registro DDRB :
DDRB &= ~ ((1<<DDRB3) | (1<<DDB2));

• Complementando-se um bit de um registro:


 Aplicar a operação XOR do registro alvo com a máscara de bits cor-
respondente ao bit que se deseja complementar.
Exemplo de como se complementar o bits 2 (PORTB2 ) do registro
PORTB :
PORTB ^= (1<<PORTB2);

• Testando-se um bit de um registro:


 Aplica-se a operação AND do registro com a máscara de bits montada
com o operador de deslocamento à esquerda como descrito antes.
Exemplo de como se testar o bit 2 do port B:
PINB & (1<<PIN2);

37
Macros para Setar, Resetar, Complementar e Testar bits
Pode-se para efeito de clareza ou praticidade criar macros como as a mostradas
a seguir:
#define SetBit_Reg(Reg,Bit) (Reg|=(1<<Bit))

#define ClrBit_Reg(Reg,Bit) (Reg&=~(1<<Bit))

#define CplBit_Reg(Reg,Bit) (Reg^=(1<<Bit))

#define TstBit_Reg(Reg,Bit) (Reg&(1<<Bit))

#define _BV(Bit) (1<<Bit)

Controle de uxo usando teste de bit


Espera que bit de um registro seja Setado ou Resetado:
#define TstBit_Reg(Reg,Bit) (Reg&(1<<Bit))
...

while(TstBit_Reg(PINB,0)==0); // Loop é executado enquanto PB0=0


...

while(TstBit_Reg(PINB,0)==1); // Loop é executado enquanto PB0=1


...

Executa se bit de registro está Setado ou Resetado:


#define TstBit_Reg(Reg,Bit) (Reg&(1<<Bit))
...

if(TstBit_Reg(PINB,0)==0){ // Se PB0=0 executa o bloco entre { }


...

}
...

if(TstBit_Reg(PINB,0)==1){ // Se PB0=1 executa o bloco entre { }


...

38
Exemplo 1: Uso das macros para testar bits. Enquanto pino
PD0=0 o pino PB5=0, se PD0=1 pino PB5=1.

#include <io.h>
#include <delay.h>

#define SetBit_Reg(Reg,Bit) (Reg|=(1<<Bit))


#define ClrBit_Reg(Reg,Bit) (Reg&=~(1<<Bit))
#define CplBit_Reg(Reg,Bit) (Reg^=(1<<Bit))
#define TstBit_Reg(Reg,Bit) (Reg&(1<<Bit))

void main(void)
{
DDRB|=(1<<DDB5); // Pino PB5 como saída
PORTD|=(1<<PORTD2); // Pull-up em PD2
while (1)
{
ClrBit_Reg(PORTB,5);
while(TstBit_Reg(PIND,2)); // Espera Pino PD0 ir a 0
SetBit_Reg(PORTB,5);
while(!TstBit_Reg(PIND,2)); // Espera Pino PD0 ir a 1
}
}

Exemplo 2: pisca LED em PB5 a cada 1,0 segundo usando a


função delay ms(nr ms) da biblioteca delay.h.

#include <io.h>
#include <delay.h>

#define SetBit_Reg(Reg,Bit) (Reg|=(1<<Bit))


#define ClrBit_Reg(Reg,Bit) (Reg&=~(1<<Bit))
#define CplBit_Reg(Reg,Bit) (Reg^=(1<<Bit))

void main(void)
{
DDRB|=(1<<DDB5); // Pino PB5 como saída
while (1)
{
ClrBit_Reg(PORTB,5);
delay_ms(1000); // Espera 1,0 segundo
SetBit_Reg(PORTB,5);
delay_ms(1000); // Espera 1,0 segundo
}
}
39
Estrutura Geral dos Pinos de E/S

40
Exemplo 3: neste exemplo há a mudança de estado do LED em
PB5 cada vez que push button em PD2 é pressionado.

#include <io.h>
#include <delay.h>

#define SetBit_Reg(Reg,Bit) (Reg|=(1<<Bit))


#define ClrBit_Reg(Reg,Bit) (Reg&=~(1<<Bit))
#define CplBit_Reg(Reg,Bit) (Reg^=(1<<Bit))
#define TstBit_Reg(Reg,Bit) (Reg&(1<<Bit))

void main(void)
{
DDRB|=(1<<DDB5); // Pino PB5 como saída
PORTD|=(1<<PORTD2); // Pull-up em PD2
while(1){
if(!TstBit_Reg(PIND,2)){
while(!TstBit_Reg(PIND,2)); // Espera liberar push-button
delay_ms(100); // Atraso de 100 ms de debouncing
CplBit_Reg(PORTB,5); }} // Complementa estado do LED em PB5
}

41
Interrupções no ATmega328
Vetor Endereço Fonte Denição
1 0x0000 RESET Reset Ext., Power-On Reset,
2 0x0002 INT0 Int. Externa no pino INT0
3 0x0004 INT1 Int. Externa no pino INT1
4 0x0006 PCINT0 Mudança estado pino Req. 0
5 0x0008 PCINT1 Mudança estado pino Req. 1
6 0x000A PCINT2 Mudança estado pino Req. 2
7 0x000C WDT Watchdog Time-out
8 0x000E TIMER2 COMPA T/C2 Compare Match A
9 0x0010 TIMER2 COMPB T/C2 Compare Match B
10 0x0012 TIMER2 OVF T/C2 Overow
11 0x0014 TIMER1 CAPT T/C1 Evento de Captura
12 0x0016 TIMER1 COMPA T/C1 Compare Match A
13 0X0018 TIMER1 COMPB T/C1 Compare Match B
14 0X001A TIMER1 OVF T/C1 Overow
15 0x001C TIMER0 COMPA T/C0 Compare Match A
16 0x001E TIMER0 COMPB T/C0 Compare Match B
17 0x0020 TIMER0 OVF T/C0 Overow
18 0x0022 SPI, STC SPI Transfer. completa
19 0x0024 USART, RX USART Recep. completa
20 0x0026 USART, UDRE USART Reg. dados vazio
21 0x0028 USART, TX USART Transm. completa
22 0x002A ADC Conv. A/D completada
23 0x002C EE READY EEPROM Pronta
24 0X002E ANALOG COMP Comparador Analógico
25 0x0030 TWI 2-Wire serial interface
26 0x0032 SPM READY Memória Flash Pronta

42
Interrupções no ATmega328 (cont.)
• 26 fontes de interrupção, bit de Seleção de Vetores de In-
terrupção - IVSEL=1: vetores de interrup. no setor de pro-
grama; se IVSEL=0 estes ocupam início do setor de boot.

Interrupções Externas
• Solicitadas pelos pinos INT0, INT1, ou PCINT0...23, fun-
ções alternativas de PORTD: PD2 (INT0) e PD3 (INT1), e
PORTB, PORTC e PORTD (PCINT0...23).

• INT0 e INT1 podem ser ativadas por nível zero, mudança de


estado, na borda de descida e subida, e PCINT0...23 quando
ocorre uma mudança de estado.

• A seleção do modo de ativação de INT0 e INT1 é feita através


do Reg. EICRA: bits ISC00 /ISC01 , para INT0; ISC11 /ISC10 ,
para INT1

• Habilitadas/Mascaradas através dos bits INT0 e INT1 do Re-


gistro de Máscara de Interrupções - EIMSK, se o bit I do
SREG=1

• PCINT0...23 tem a seleção de ativação feita através do bit


de controle PCIE0...2 , do Registro PCICR.

• Quando a interrupção externa é atendida, o programa desvia


p/ o vetor de interrupção correspondente, o bit I é resetado,
assim como o respectivo bit dos registros EIFR e PCIFR.

• Pode-se deslocar os Vetores de Interrupção do inicio da me-


mória Flash, p/ o inicio do setor de boot, através dos bits
IVSEL e IVCE . Isso só será possível se o bit IVCE =1.

43
Reg. de Máscara de Interrup. Externa - EIMSK
EIMSK
      INT1 INT0

• Bits INT0, INT1: Setado habilita a interrupção ex-


terna correspondente, desde que o bit I do SREG
esteja setado;

Reg. de Controle de Interrup. Ext. A - EICRA

• Modo de Ativação das Interrupções Externas por


nível, borda de descida, ou borda de subida.

EICRA
    ISC11 ISC10 ISC01 ISC00

• Bits ISC00 /ISC01 e ISC10 /ISC11 : Interrupt Sense Control,


aos pares seleciona o modo de ativação das interrupções ex-
ternas INT0, e INT1, por nível, borda de descida, ou de su-
bida.

ISC01/ISC11 ISC00/ISC10 Ativação de INT0/INT1


0 0 Nível zero em INTn
0 1 Mudança de estado em INTn
1 0 Borda de descida em INTn
1 1 Borda de subida em INTn

44
Reg. de Sinalização de Interrup. Externa - EIFR
EIFR
      INTF1 INTF0

• Bits INTF0, INTF1: Interrupt Flag Bits 0 e 1, ou


Sinalizadores de Interrupção, qdo o pino INT0 ou
INT1 é ativado, o ag correspondente é setado,
sendo resetado por hardware no atendimento da
interrupção.

Reg. de Controle de Interrupção da Mudança de


Estado de Pino - PCICR
PCICR
     PCIE2 PCIE1 PCIE0

• Bits PCIE0, PCIE1 e PCIE2: Setados, desde que


o bit I do SREG também esteja setado, habilitam
as interrupçóes externas correspondentes aos pinos
PCI0...7, PCI8...14 e PCI16...23, respectivamente,
quando estes pinos mudam de estado. A máscara
de interrupção por mudança de estado é feita no
registro PCMSK0, PCMSK1 e PCMSK2, para os
pinos: PCI0...7, PCI8...14 e PCI16...23, respecti-
vamente.
45
Exemplo de uso das interrupções externas
Controle da temperatura de um forno

• Sensores de temperatura ligados aos pinos de interrupção


INT0 e INT1.

• Sensor de 120°C provoca interrupção INT0 e sensor de 100°C


provoca a interrupção INT1.

• Quando o sensor associado ao pino INT0 é ativado, na borda


de descida, então a temperatura do forno ultrapassou 120ºC,
e o forno deve ser desligado, uma vez que a temperatura
atingiu o seu valor máximo.

• Quando o sensor associado ao pino INT1 é ativado, na borda


de descida, indicando que a temperatura do forno está abaixo
de 100ºC, o forno deve ser ligado, por estar abaixo da tem-
peratura limite inferior.

46
Código em C editado no CodeVision:

#include <mega328p.h> // Definições de registros


#define ACIONADOR PORTB.0

void inicializa(void); // Protótipo da função

void main(void)
{
inicializa(); // Inicializa periféricos
ACIONADOR=1; // Inicia ligando o forno
if(INTF0==1)
ACIONADOR=0; // Desliga forno se T>120°C
while (1); // Espera ativação de sensores
}

// Rotina de Interrupção Externa 0 ativada pelo sensor de 120°C


interrupt [EXT_INT0] void ext_int0_isr(void)
{
ACIONADOR=0; // Desliga forno sensor 120°C ativo
}

// Rotina de Interrupção Externa 1 ativada pelo sensor de 100°C


interrupt [EXT_INT1] void ext_int1_isr(void)
{
ACIONADOR=1; // Liga forno sensor 100°C ativo
}

void inicializa(void)
{
// Pino PB0 saída
DDRB|=(1<<DDB0);
PORTB=0x00;
PORTD|=(1<<2)|(1<<3); // Pull-ups nos pinos INT0 e INT1
// INT0 e INT1: Ativos na borda de descida
EICRA=(1<<ISC11) | (0<<ISC10) | (1<<ISC01) | (0<<ISC00);
// Habilita INT0 e INT1 após I=1 (SREG)
EIMSK=(1<<INT1) | (1<<INT0);
// Habilitação Global de Interrupções, I=1
#asm("sei")
}

47
Interface com Módulo de LCD
A conexão do LCD com o microcontrolador pode ser feita através
de 4 bits de dados, utilizando os pinos D4 a D7 do LCD, ou em
8 bits de dados, utilizando os pinos D0 a D7. Além destes sinais
de dados, 3 sinais de controle são usados:

• Habilitação (EN) - Ativo na borda de descida;

• Seleção de escrita ou leitura (RW) - 0: WR; 1: RD;

• Seleção de reg. de comando ou de dado (RS) - 0: cmd; 1:


dado;

• Estes sinais de controle devem seguir uma temporização es-


pecíca.

A pinagem de um LCD padrão Hitachi é apresentada na tabela, a


seguir:

Pino Sigla Função


1 GND Terra
2 Vcc Alimentação de +5V
3 Pot Terminal central do trimpot
4 RS Register Select - Seleção de Registro
5 RW Read/Write - Sinal de Leitura e Escrita
6 EN Enable - Sinal de Habilitação
7 D0 Sinal de dados D0 (LSB)
8 D1 Sinal de dados D1
9 D2 Sinal de dados D2
10 D3 Sinal de dados D3
11 D4 Sinal de dados D4
12 D5 Sinal de dados D5
13 D6 Sinal de dados D6
14 D7 Sinal de dados D7 (MSB)
48
Funções da Biblioteca alcd.h do Codevision
• void lcd init(unsigned char lcd columns) - Inicializa o contro-
lador do LCD conforme tipo em nr de colunas;

• void lcd clear(void) - Limpa o LCD;

• void lcd gotoxy(unsigned char x, unsigned char y) - Posiciona


cursor do LCD na posição x,y (x=0..39 e y=0..3);

• void lcd putchar(char c) - Escreve no LCD um caracter;

• void lcd puts(char *str) - Escreve string de caracteres no


LCD;

• void lcd putsf(char ash *str) - Escreve no LCD string de


caracteres localizada na memória Flash;

• void lcd putse(char eeprom *str) - Escreve no LCD string de


caracteres localizada na memória EEPROM;

• unsigned char lcd read byte(unsigned char addr) - Lê da me-


mória de caracteres;

• void lcd write byte(unsigned char addr, unsigned char data) -


Escreve na memória de caracteres;

• Obs1: RS=RW=EN=0 selecionam escrita no registro de con-


trole;

• Obs2: RS=1 e RW=EN=0 selecionam escrita no registro de


dados;

• Obs3: Modo de operação do LCD: interface em 4.

49
Interface com LCD em 4 Bits no Codevision

• A mensagem que será apresentada é a clássica mensagem


ALO MUNDO na 1ª linha e HELLO WORLD! na 2ª linha.

Exemplo de código em C:
/*******************************************************
Chip: ATmega328P Clock: 16,000000 MHz
*******************************************************/
#include <mega328p.h>
#include <alcd.h>

// Protótipo da função inic()


void inic(void);

void main(void){
inic();
lcd_puts("ALO MUNDO!"); // Escreve string na coluna 0 linha0
lcd_gotoxy(0,1); // Posiciona cursor na coluna 0 linha1
lcd_puts("HELLO WORLD!"); // Escreve string na coluna 0 linha1
while (1);
}

void inic(void){
// LCD Alfanumerico: inicialização
// RS:PB4, RD:GND, EN:PB5, D4:PB0, D5:PB1, D6:PB2, D7:PB3
// Caracteres/linha: 16
lcd_init(16); // Inicializa o LCD conforme acima
}
50
Interface LCD em 8 Bits com Shift Register
Pode-se conectar o LCD ao ATmega328 em 8 bits utilizando um
shift register 74HC164. Neste caso os pinos D0 a D7 do LCD são
oriundo da saída do 74HC164, o qual recebe estes 8 bits de forma
serial pela linha de dados (A) sincronizados com o clock (CLK).
Os pinos de controle RS e EN do LCD são conectados a pinos
disponíveis de uma das portas, e o RD aterrado.

• No exemplo a seguir, novamente a mensagem que será apre-


sentada é a clássica mensagem ALO MUNDO na 1ª linha e
HELLO WORLD! na 2ª linha.

Exemplo de código em C:
/*******************************************************
Chip: ATmega328P Clock: 16,000000 MHz
*******************************************************/
#include <mega328p.h>
#include "shift_reg.h"

unsigned char msg1[]={"Hello World"};


unsigned char msg2[]={"Alo Mundo"};

void main(void){
lcd164_inic();
lcd164_puts(msg1); // Escreve string na coluna 0 linha0
lcd164_gotoxy(0,1); // Posiciona cursor na coluna 0 linha1
lcd164_puts(msg2); // Escreve string na coluna 0 linha1
while (1);
}
51
Código do arquivo de cabeçalho shift reg.h:
#include <io.h>
#include <delay.h>

// Definições p/ o Shift Register


#define SHT_REG PORTC // Porta usada pelo 74164
#define DBIT PORTC0 // Pino de dados do 74164
#define CLK PORTC1 // Pino de clock do 74164
#define DBIT_HI SHT_REG |= (1<<DBIT) // Macro seta bit de dado
#define DBIT_LO SHT_REG &= ~(1<<DBIT) // Macro reseta bit de dado
#define CLK_HI SHT_REG |= (1<<CLK) // Macro seta bit de clock
#define CLK_LO SHT_REG &=~ (1<<CLK) // Macro reseta bit de clock

// Pinos conectados ao LCD


#define CNTR PORTC
#define RS PORTC2
#define EN PORTC3
#define EN_HI CNTR |= (1<<EN)
#define EN_LOW CNTR &=~(1<<EN)
#define RS_CMD CNTR &=~(1<<RS)
#define RS_DAT CNTR |= (1<<RS)

// Parâmetros de configuração do LCD


#define CONFIG_LCD 0x38
#define LCD_ON 0x0E
#define ENTRY 0x06
#define CLR_LCD 0x01
#define HOME 0x02
#define LIN1 0xC0
#define DISP_ON 0x0C
#define DISP_OFF 0x08

// Função para deslocamento de bits via 74HC164 para envio ao LCD


void shift_reg(unsigned char dado){
unsigned char i;
CLK_HI;
for(i=0;i<8;i++){
if((dado & 0x80)==0x80)
DBIT_HI;
else
DBIT_LO;
CLK_LO;
CLK_HI;
dado=dado<<1;}
}

// Função de envio de comando ao LCD


void lcd164_cmd(unsigned char dado){
52
EN_HI;
RS_CMD;
shift_reg(dado);
EN_LOW;
delay_ms(5);
}

// Função de envio das palavras de controle ao LCD para sua inicia-


// lização para funcionar em 8 bits
void lcd164_inic(void){
DDRC|=(1<<DDC3)|(1<<DDC4)|(1<<DDC5);
DDRB|=(1<<DDB2);
PORTC=0;
EN_LOW;
RS_CMD;
CLK_HI;
lcd164_cmd(CONFIG_LCD);
lcd164_cmd(CONFIG_LCD);
lcd164_cmd(LCD_ON);
lcd164_cmd(ENTRY);
lcd164_cmd(CLR_LCD);
}

// Função para limpar o LCD


void lcd164_clear(){
EN_HI;
RS_CMD;
shift_reg(CLR_LCD);
EN_LOW;
delay_ms(5);
}

// Função para posicionar cursor do LCD em certa posição


void lcd164_gotoxy(unsigned char col,unsigned char lin){
unsigned char base,dado;
if(lin==0 || lin==1){
switch(lin){
case 0: base=0x80;
break;
case 1: base=0xC0;
break;
default: base=0;}}
else
return;
if(col>15) return;
EN_HI;
RS_CMD;
dado=base+col;
shift_reg(dado);
EN_LOW;
delay_ms(5);
}

// Função de escrita de caracter no LCD


void lcd164_putchar(unsigned char dado){
EN_HI;
RS_DAT;
shift_reg(dado);
EN_LOW;
delay_ms(5);
}

// Função de escrita de string no LCD


void lcd164_puts(unsigned char *s){
unsigned char i;
for(i=0;s[i]!='\0';i++)
lcd164_putchar(s[i]);
}

Interface com Teclado Matricial

Uma varredura deve ocorrer escrevendo zero em uma das 3 colunas


e então lendo-se o que há nas 4 linhas para vericar a linha/coluna
ativa.
• A mensagem Pressione tecla é apresentada na 1ª linha e o
caracter da tecla na linha 2ª linha.

#include <mega328p.h>
#include <delay.h>
#include <alcd.h>

#define COL1 PORTD4


#define COL2 PORTD5
#define COL3 PORTD6

#define C1L1 0b11101110


#define C1L2 0b11101101
#define C1L3 0b11101011
#define C1L4 0b11100111

#define C2L1 0b11011110


#define C2L2 0b11011101
#define C2L3 0b11011011
#define C2L4 0b11010111

#define C3L1 0b10111110


#define C3L2 0b10111101
#define C3L3 0b10111011
#define C3L4 0b10110111

void inic(void);
void le_tecla(void);
void print(unsigned char tecla);

void main(void)
{
inic();
lcd_puts("Pressione tecla");
lcd_gotoxy(0,1);
while(1){
le_tecla();
}
}

void le_tecla(void)
{
PORTD|=(1<<COL1)|(1<<COL2)|(1<<COL3);
PORTD&=~(1<<COL1);
delay_ms(100);
switch(PIND){
case C1L1:print('1');
break;
case C1L2:print('4');
break;
case C1L3:print('7');
break;
case C1L4:print('*');};
PORTD|=(1<<COL1);
PORTD&=~(1<<COL2);
delay_ms(100);
switch(PIND){
case C2L1:print('2');
break;
case C2L2:print('5');
break;
case C2L3:print('8');
break;
case C2L4:print('0');};
PORTD|=(1<<COL2);
PORTD&=~(1<<COL3);
delay_ms(100);
switch(PIND){
case C3L1:print('3');
break;
case C3L2:print('6');
break;
case C3L3:print('9');
break;
case C3L4:print('#');};
PORTD|=(1<<COL3);
}

void print(unsigned char tecla)


{
lcd_putchar(tecla);
while((PIND & 0x0F)!=0x0F);
}

void inic(void)
{
DDRD=0xF0; // Bits7..4=Saídas e Bits2..0=Entradas
PORTD=0xFF; // Bits7..4=0 e Bits3..0=Pullup
UCSR0B=0x00; // USART desabilitada
lcd_init(16); // LCD tipo 16 caracters/linhas
}
Interrupções dos Temporizadores/Contadores

• Interrupção por Overow: Quando o Registro de Conta-


gem do T/C atinge o máximo valor de contagem;

• Interrupção por Comparação de Valores: Quando uma


comparação entre o Registro de Contagem e o de Compara-
ção, resulta verdadeiro;

• Interrupção por Captura de Valores: Quando o pino de


Captura ICP é ativado, o valor de contagem corrente no Re-
gistro de Contagem, é capturado.

Interrupção por Overow na Contagem

• Ocorre se a contagem no registro de contagem de 8 bits


TCNT0 ou TCNT2, dos T/C0 e T/C2, ou no de 16 bits do
T/C1 - TCNT1, alcança o valor máximo/mínimo de conta-
gem, no caso: 255/0 ou 65535/0, respectivamente.

• O ag TOV0 , TOV1 ou TOV2 do registro TIFR0, TIFR1


ou TIFR2, é setado em resposta à ocorrência do overow na
contagem do T/C0, T/C1 ou T/C2, repectivamente.

• A interrupção deve ser habilitada setandos-se os bits:

 TOIE0 , TOIE1 ou TOIE2 => T/C0, T/C1 ou T/C2


Registros TIMSK0, TMSK1 ou TMSK2, respectivamente;

 E bit de Habilitação Global de Interrupções, I =1.

53
Interrupção por Comparação de Valores

• Ocorre quando os conteúdos do Reg. de Saída de Compara-


ção e do Registro de Contagem de um T/C se igualam:

T/C Reg. Comparação Reg. de Contagem


0 OCR0A/OCR0B TCNT0
1 OCR1A(H/L)/OCR1B(H/L) TCNT1(H/L)
2 OCR2A/OCR2B TCNT2

• As interrupções são individualmente habilitadas setando-se os


respectivos bits de habilitação de cada T/C, de acordo com
a tabela a seguir, devendo-se ainda, setar o bit I em SREG.

T/C Bit Reg. de Máscara de Interrupção


0 OCIE0A/OCIE0B TIMSK0
1 OCIE1A/OCIE1B TIMSK1
2 OCIE2A/OCIE2B TIMSK2
54
• O ags: OCF0A ou OCF0B do registro TIFR0, sinalizam a
ocorrência da igualdade na comparação do T/C0

• O ags: OCF1A ou OCF1B do registro TIFR1, sinalizam a


ocorrência da igualdade na comparação do T/C1

• O ags: OCF2A ou OCF2B do registro TIFR2, sinalizam a


ocorrência da igualdade na comparação do T/C2

Interrupção por Captura de Valores


• Ocorre quando o pino ICP é ativado, levando à captura do
valor de contagem corrente, no registro ICR1.

• Pode-se, ainda, utilizar a saída do comparador analógico como


sinal de disparo para a captura.

• Em resposta, o ag ICF1 é setado, e caso a interrupção por


captura esteja habilitada (bit TICIE1=1 em TIMSK, e I =1
em MCUCR), o programa desviará para o vetor de interrupção
localizado em 0003.
Reg. de Máscara de Interrup. dos T/C's
TIMSK0
     OCIE0B OCIE0A TOIE0
TIMSK1
  ICIE1   OCIE1B OCIE1A TOIE1
TIMSK2
     OCIE2B OCIE2A TOIE0

• Bits TOIE0, TOIE1 e TOIE2 :


Timer Overow Interrupt
Enable dos T/C0, T/C1 e T/C2, setado habilita a inter-
rupção do T/C correspondente por Overow na Contagem,
desde que o bit I também esteja setado;

• Bits OCIE0A/B, OCIE1A/1B e Output


OCIE2A/2B :
Compare Interrupt Enable A e B dos T/C0, T/C1 e T/C2,
setado habilita a interrupção do T/C correspondente, por
Comparação de Valores A ou B, respectivamente, desde que
o bit I também esteja setado;

• Bit ICIE1 : Input Capture Interrupt Enable do T/C1, setado


habilita a interrupção do T/C1 por Captura de Valores, desde
que o bit I também esteja setado

55
Reg. de Sinaliz. de Interrup. dos T/C's
TIFR0
     OCF0B OCF0A TOV0
TIFR1
  ICF1   OCF1B OCF1A TOV1
TIFR2
     OCF2B OCF2A TOV2

• Bit TOV 0 , TOV 1 e TOV 2 :


Timer Overow Interrupt
Flag do T/C1, setado por hardware quando ocorre Overow
na Contagem do T/C1. Resetado por hardware no atendi-
mento da interrupção;

• Bits OCF0A/B, OCF1A/B e OCF2A/B :


Output Com-
pare Interrupt Flag A e B dos T/C0, T/C1 e T/C2, setado
por hardware na Comparação de Valores A ou B do respectivo
T/C, quando verdadeira. Resetado por hardware no atendi-
mento da interrupção;

• Bit ICF1 : Input Capture Interrupt Flag do T/C1, setado na


captura de valores via pino ICP. Resetado por hardware no
atendimento da interrupção;

56
Temporizadores/Contadores - T/C's
- T/C0 de 8 bits.
- T/C2 de 8 bits.
- T/C1 de 16 bits.

Temporizador de Pré-Divisão de 10 bits


Circuito comum aos 2 T/C's que faz a pré-divisão sinal de clock
interno - CK , oriundo do circuito de clock, independentemente,
obtendo-se: CK/8 , CK/64 , CK/256 , ou CK/1024 .

Obs1: T0 e T1 não passam pelo bloco de pré-divisão, portanto


a ação do Prescaler Timer se restringe a operação dos T/C's no
modo temporizador.

Obs2: Os bits de controle de Seleção de Clock: CS00:2 e CS10:2 ,


são os responsáveis pela seleção da fonte do sinal de clock que
será efetivamente enviado a cada T/C.

57
Temporizador/Contador 0 de 8 Bits
Características Principais do T/C0:

• Temporizador/Contador de Eventos Bidirecional de 8 bits;

• Pré-Divisão (Prescaler) do clock da CPU de 10 bits;

• Unidade de Comparação de Valores c/ Recarga Automática;

• Gerador de Frequências;

• Saída PWM c/ Resolução de 8 bits;

• Duas fontes de interrupção: Overow e Comparação

58
Arquitetura Interna do T/C0

59
Registro de Contagem - TCNT0

• É onde ocorre a contagem em 8 bits, podendo con-


tar de forma crescente ou decrescente;

• Quando o valor de contagem chega em 255 (FFH),


na contagem crescente, ou 0 (zero), na contagem
decrescente, ocorre o Overow na contagem;

• Neste caso, bit de ag TOV0 é setado, e uma in-


terrupção por Overow será requisitada, se previa-
mente habilitada.

T/C0 como Temporizador ou Contador

• Se a origem do sinal de clock é o Temporizador


de Pre-Divisão, a operação do T/C0 será como
Temporizador;

• Se a origem deste sinal de clock é o pino T0, a


operação será como Contador de Eventos;

• A seleção do modo de operação, é feita através dos


bits: CS02, CS01, e CS00, do Registro de Controle
do T/C0 - TCCR0.
60
Modos de Operação do T/C0
Após selecionar a operação do T/C0 como: Tempo-
rizador (com um determinado fator de prescaler), ou
Contador de Eventos (ativo na borda de descida ou su-
bida), deve-se congurar, em seguida o modo de conta-
gem em TCNT0, através dos bits de Seleção de Modo
de Geração de Onda: WGM02, WGM01 e WGM00:

• Modo Normal: Contagem crescente até valor má-


ximo (255), sem recarga automática;

• Modo CTC: Sigla de Clear Timer on Compare


Match, onde a contagem crescente em TCNT0
ocorre até a comparação c/ o Reg. de Compara-
ção - OCR0, resultar verdadeiro, quando TCNT0
é zerado, e o pino OC0 será setado, resetado, ou
complementado, dependendo da programação efe-
tuada previamente nos bits COM01 /COM00 ;

• Modo PWM Rápido: Geração de sinal PWM no


pino OC0, c/ frequências de PWM cerca de duas
vezes mais altas, que no PWM Corrigido em Fase;

• PWM Corrigido em Fase: Geração de sinal PWM


no pino OC0, onde se obtém um sinal PWM com
fase corrigida, apesar de resultar em frequências
menores que o modo anterior.
61
62
Registro de Controle do T/C0 - TCCR0A

TCCR0A
COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00

• Bits COM0A1, COM0A0: Compare Output Mode,


ou Modo de Saída de Comparação, seleciona o
modo como o pino de saída OC0A se comportará.

Modo de Ativação da Saida OC0A


COM0A1 COM0A0 Modo Normal (WGM02...0=000)
0 0 OC0A Desconectado.
0 1 OC0A Muda de Estado na Comparação .
1 0 Reseta OC0A na Comparação.
1 1 Seta OC0A na Comparação.
COM0A1 COM0A0 Modo PWM Rápido (WGM02...0=011)
0 0 OC0A Desconectado.
0 1 Reservado.
1 0 OC0A=0 na Comparação, 1 no valor MÁX.
1 1 OC0A=1 na Comparação, 0 no valor MÁX.
COM0A1 COM0A0 PWM Fase Corrig. (WGM02...0=001)
0 0 OC0A Desconectado.
0 1 Reservado.
1 0 OC0A=0 na Comparação em contagem
crescente, OC0A=1 na contagem decres.
1 1 OC0A=1 na Comparação em contagem
crescente, OC0A=0 na contagem decres.

63
• Bits COM0B1, COM0B0: Compare Output Mode,
ou Modo de Saída de Comparação, seleciona o
modo como o pino de saída OC0B se comportará.

Modo de Ativação da Saida OC0B


COM0B1 COM0B0 Modo Normal (WGM02...0=000)
0 0 OC0B Desconectado.
0 1 OC0B Muda de Estado na Comparação .
1 0 Reseta OC0B na Comparação.
1 1 Seta OC0B na Comparação.
COM0B1 COM0B0 Modo PWM Rápido (WGM02...0=011)
0 0 OC0B Desconectado.
0 1 Reservado.
1 0 OC0B=0 na Comparação, 1 no valor MÁX.
1 1 OC0B=1 na Comparação, 0 no valor MÁX.
COM0B1 COM0B0 PWM Fase Corrig. (WGM02...0=001)
0 0 OC0B Desconectado.
0 1 Reservado.
1 0 OC0B=0 na Comparação em contagem
crescente, OC0=1 na contagem decres.
1 1 OC0B=1 na Comparação em contagem
crescente, OC0B=0 na contagem decres.

64
Registro de Controle do T/C0 - TCCR0B
TCCR0B
FOC0A FOC0B   WGM01 CS02 CS01 CS00

• Bits CS02, CS01, CS00 : Bits Clock Selection, selecionam


a operação do T/C0, como Temporizador ou Contador de
Eventos, o fator de prescaler (se no modo Temporizador),
e o modo Contador de Eventos, a ativação do sinal T0 na
borda de descida ou subida:

CS02 CS01 CS00 Clock do Contador


0 0 0 Para a contagem do T/C0
0 0 1 Clock proveniente do clock da CPU
0 1 0 Clock = clock da CPU/8
0 1 1 Clock = clock da CPU/64
1 0 0 Clock = clock da CPU/256
1 0 1 Clock = clock da CPU/1024
1 1 0 Clock = T0 na borda de descida
1 1 1 Clock = T0 na borda de subida

• Bits WGM01, WGM00 : Bits Wave Form Generator Mode, se-


lecionam o modo de operação: Normal, PWM Rápido, PWM
Corrigido em Fase, e CTC.

WGM02..1 Modo TOP OCRx Update


000 Normal (00->FF) 0xFF Imed.
001 PWM Corr. Fase 0xFF TOP
010 CTC OCRA Imed.
011 PWM Rápido 0xFF BOTTOM
100 Reservado - -
101 PWM Corr. Fase OCRA TOP
110 Reservado - -
111 PWM Rápido OCRA BOTTOM
65
• Bits FOC0A/B: Force Output Compare, quando
setado, força a saída de comparação OC0 a produ-
zir uma mudança, de acordo com o comportamento
selecionado nos bits COM01, COM00, porém so-
mente nos modos não PWM (bit WGM00=0).

66
Operação do T/C0 no Modo Normal - Timer Over-
ow

• Seleção operação modo normal em TCCR0A:


Bits WGM01/WGM00=00;

• Seleção do clock de contagem em TCCR0B:


Bits CS00/CS01/ CS02=00;

• Contagem em TCNT0 de modo crescente, por Over-


ow na Contagem;

• No Overow, o bit de ag TOV0 (Timer Overow


0) é setado no mesmo ciclo de clock em que a
contagem vai a 0;

• Interrupção habilitada através do bit TOIE0 (Ti-


mer Overow Interrupt Enable), do Reg. TIMSK0;

• Desvio para o endeerço 0007 se o bit I=1 (Habili-


tação Global de Interrupções) e TOIE0=1.

• Quando da execução da rotina de interrupção o ag


TOV0 é automaticamente resetado.
67
Exemplo: Piscando um Led a cada 1,0s via T/C0

• Usando o T/C0, c/ clock de contagem: fclk /1024, p/ um


cristal de 16,0MHz, o período de contagem do T/C0 caria:
Tclk = 0, 0625us.1024 = 64us

• Inicializando-se TCNT0 c/ 100, após 156 pulsos de contagem


de 64us, TCNT0=255, e um pedido de interrupção do T/C0
por Overow na Contagem é gerado, isso após um tempo de:
T=0,009984s = (156x64us) ' 10ms.

• A interrupção do T/C0, tendo sido habilitada através do regis-


tro TIMSK0, o programa desviará para o vetor de interrupção
do T/C0, no endereço 0x010.

• Para se chegar a 1,0 segundo, bastará repetir 100 vezes a


interrupção do T/C0, ou seja:
T' 10ms.100 = 1000ms = 1s.

• Após 100 repetições, um registro de contagem foi de 100 até


0, podendo-se mudar o estado do pino PB5 fazendo o LED
piscar. Deve-se então, reiniciar o registro de contagem em
100, para repetir o processo ciclicamente.

68
Código em C no CodeVision:
/* Chip: ATmega328 Clock: 16,000000 MHz */

#include <mega328.h>

void inicializa(void);
unsigned char i=100;

// Timer 0 overflow interrupt service routine


interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
TCNT0=100; // Valor de recarga p/ T=9,984 ms
i--;
if (i==0) {
i=100; // Após 100x T=0,9984 s
PORTB.5=~PORTB.5;} // Complementa pino PB0
}

void main(void)
{
inicializa();
while (1);
}

void inicializa(void)
{
DDRB=(1<<DDB5);
PORTB=0x00;
TCCR0A=0x00; // Clock source: System Clock; Mode: Normal top=0xFF
TCCR0B=(0<<WGM02)|(1<<CS02)|(0<<CS01)|(1<<CS00); // Clk T/C0=15,625 kHz
TCNT0=100; // Timer Period: 9,984 ms
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B)|(0<<OCIE0A)|(1<<TOIE0); // T/C0 Interrupção por overflow
#asm("sei") // Habilitação Global de Interrupções
}

69
Código em C no WinAVR:
/* Chip: ATmega328P Clock: 16,000000 MHz */

#include <avr/io.h>
#include <avr/interrupt.h>

void inializa(void);
unsigned char i=100;

// Timer 0 overflow interrupt service routine


ISR(TIMER0_OVF_vect)
{
TCNT0=100; // Valor de recarga p/ T=9,984 ms
i--;
if(i==0){
i=100; // Após 100x T=0,9984 s
PORTB ^= (1<<PB5); // Complementa pino PB5
}
else
return;
}

int main(void)
{
inializa();
while (1);
}

void inializa(void)
{
DDRB=(1<<DDB5);
PORTB=0x00;
TCCR0A=0x00; // Clock source: System Clock; Mode: Normal top=0xFF
TCCR0B=(0<<WGM02)|(1<<CS02)|(0<<CS01)|(1<<CS00); // Clk T/C0=15,625 kHz
TCNT0=100; // Timer Period: 9,984 ms
TIMSK0=(0<<OCIE0B)|(0<<OCIE0A)|(1<<TOIE0); // T/C0 Interrupção por overflow
sei(); // Habilitação Global de Interrupções
}

70
Exemplo: Piscando um Led a cada 1,0s via T/C0
sem interrupção
Neste caso o bit de overow (TOV0) deve ser continuamente
vericado para se saber quando o overow ocorreu (TOV0=1).
Este ag deve ser resetado por software (fazendo TOV=1) já que
não haverá interrupção para resetá-lo automaticamente.

Código em C no CodeVision:
/* Chip: ATmega328 Clock: 16,000000 MHz */

#include <mega328.h>

void inicializa(void);
unsigned char i=100;

void main(void)
{
inicializa();
while (1){
while(!(TIFR0 & (1<<TOV0)));
TIFR0|=(1<<TOV0);
TCNT0=100; // Valor de recarga p/ T=9,984 ms
i--;
if (i==0) {
i=100; // Após 100x T=0,9984 s
PORTB.5=~PORTB.5;} // Complementa pino PB0
}
}

void inicializa(void)
{
DDRB=(1<<DDB5);
PORTB=0x00;
TCCR0A=0x00;
// Clock: Clock da CPU/1024 (T/C0=15,625 kHz)
TCCR0B=(0<<WGM02)|(1<<CS02)|(0<<CS01)|(1<<CS00);
TCNT0=100; // Timer Period: 9,984 ms
// T/C0 Interrupções desabilitadas
TIMSK0=(0<<OCIE0B)|(0<<OCIE0A)|(0<<TOIE0);
}

71
T/C0 no Modo CTC - Clear Timer on Compare
Match

• Seleção feita nos Reg. de Controle do T/C0 - TCCR0A/B:


WGM02..00 =010;

• Contagem sempre de modo crescente;

• TCNT0, é comparado continuamente o c/ o Reg. de Compa-


ração - OCR0A ou OCR0B, fazendo TCNT0=0, e ativando
o pino OC0A ou OC0B, quando houver igualdade entre seus
conteúdos.

• O registros OCR0A ou OCR0B determina o valor máximo de


contagem (TOP), e portanto a resolução;

• O bit de ag: OCF0 é setado no próximo ciclo de clock.

• Interrupção de comparação habilitada, através do bit OCIE0 ;

• Desvio para o endereço 000E, se o bit I=1 (habilitação global


de interrupções), e OCIE0 =1.

• O ag OCF0 é automaticamente resetado, quando do aten-


dimento da interrupção.

• Pino OC0, poderá setar, resetar, ou complemetar seu estado,


de acordo com os bits de Seleção de Modo de Saída de Com-
paração: COM01 /COM00 .

72
• O ag de Overow na Contagem - TOV0 , poderá gerar in-
terrupções se o bit TOIE0=1, e o bit I=1;

• Na geração de forma de onda em OC0, esta saída deve ser


congurada p/ complementar seu estado a cada comparação,
sendo que:

 A frequência máxima gerada: fOC0 = fClkIO /2 quando


OCR0=0;

 A fórmula para outros valores de frequência em: OCR0,


poderá ser calculada como sendo:

fClkIO
fOC0A/B =
2.N.(1 + OCR0A/B)
Onde: N =fator de prescaler; e fClkIO = Clock de E/S

 Será necessário ainda, congurar a direção do pino OC0A


(PD6) ou OC0B (PD5), como pino de saída, através do
Registro de Direção de Dados - DDRB.

Exemplo: Geração de 20kHz em PD6 (OC0A) c/ T/C0 no


Modo CTC
Onda quadrada de 20kHz em PD6=OC0A. Frequência de clock
(fCLK ) do ATmega328 de 16MHz, e o fator de prescaler (N) do
T/C0 de 8. A frequência de 20kHz é gerada com o T/C0 funci-
onando no modo CTC, quando na comparação do reg. OCR0A
c/ o reg. TCNT0, o pino OC0A (PD6) complementa seu estado
sempre que OCR0A=TCNT0.

• A frequência gerada no pino OC0A será de:

fClkIO 16.000.000
f = = = 20.000Hz
2.N.(1 + OCR0A) 2.8.(1 + OCR0A)
o que leva a um valor para OCR0A de 49=0x31.

73
Código em C editado no CodeVision:

/*******************************************************
Chip: ATmega328P Clock frequency: 16,000000 MHz
*******************************************************/
#include <mega328p.h>
void inic(void);

void main(void)
{
inic();
while (1);
}

void inic(void)
{
DDRD=(1<<DDB6);
PORTD=(1<<PORTD6);
// Timer/Counter 0: Clock source: System Clock
// Clock value: 2 MHz
// Mode: CTC top=OCR0A
// OC0A output: Toggle OC0A on compare match
TCCR0A=(0<<COM0A1) | (1<<COM0A0) | (0<<COM0B1) | (0<<COM0B0)
| (1<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (0<<CS02) | (1<<CS01) | (0<<CS00);
TCNT0=0x00;
OCR0A=0x31; // Valor de OCR0A p/ f=20kHz (T/2: 0,025 ms)
}

74
Temporizador/Contador 1 de 16 Bits
Características principais do T/C1

• Contagem em 16 bits Bidirecional;

• Pré-Divisão (Prescaler) do clock da CPU de 10 bits;

• Geração de saída em PWM, com até 16 bits de resolução;

• Saída em PWM com período variável;

• Duas unidades comparadoras Independentes de 16 bits;

• Uma unidade de captura c/ cancelamento de ruído na entrada


ICP;

• Clear Timer on Compare Match (CTC - Auto reload);

• Quatro fontes de interrupção independentes (TOV1, OCF1A,


OCF1B e ICF1).

75
• O Registro de Contagem TCNT1 deve ser aces-
sado, em 2 acessos de 8 bits, através dos registros
TCNT1H e TCNT1L, usando-se as instruções de
IN e OUT.

• No T/C1 existem 2 registros de controle: TCCR1A


e TCCR1B, além do Registro de Entrada de Cap-
tura ICR1, e 2 Registros de Comparação OCR1A e
OCR1B.

• O clock de contagem (CLKT1) pode ser oriundo de


2 fontes distintas: do Prescaler Timer, ou do pino
externo T1, diferenciando o funcionamento como
Temporizador ou Contador de Eventos.

• Os bits de Seleção de Clock: CS12, CS11, e CS10,


do Registro de Controle B (TCCR1B) determina a
origem do sinal de clock e o fator de prescaler.

• Selecionada a operação como Temporizador ou Con-


tador de Eventos (bits CS12, CS11, e CS10), o
modo de contagem em TCNT1, e o comporta-
mento dos pinos OC1A/OC1B, será feito pelos
bits:
 WGM13 , WGM12 , WGM11 , WGM10 (TCCR1B/TCCR1A)

 COM1A1 , COM1A0 , COM1B1 , COM1B0 (TCCR1A)

76
Arquitetura Interna do T/C1
Controle PWM
#include <io.h>
#include <delay.h>

// Protótipo da função inic()


void inic(void);

// Constantes para o acionamento do display de 7-segmentos


unsigned char dado[]={0B11000000,0B11111001,0B10100100,0B10110000,
0B10011001,0B10010010,0B10000010,0B11111000,0B10000000, 0B10011000};

// Constantes para a carga do registro de comparação OCR2A para a geração


// dos ciclos de trabalho de 0 a 90% em passos de 10%
unsigned char pwm_cte[]={0,25,50,75,100,125,150,175,200,225};

// Variável de contagem dos passos de 10%


unsigned char counts=0;

// Trata a tecla de incremento de potência


void incrementa(void){
counts++;
if(counts==10) counts=9;
PORTD=dado[counts];
OCR2A=pwm_cte[counts];
delay_ms(500);
}

// Trata a tecla de decremento de potência


void decrementa(void){
counts--;
if(counts==255) counts=0;
PORTD=dado[counts];
OCR2A=pwm_cte[counts];
delay_ms(500);
}

// Função Proncipal
void main(void){
inic();
while(1){
if(!(PINB & 0b00000010)) incrementa();
if(!(PINB & 0b00000001)) decrementa();}
}

77
// Função de inicialização de periféricos
void inic(void){
// Porta D toda como saída
DDRD=0xFF;
PORTD=0x00;
// PB3 como saída PWM (OC2A) e PB0 e PB1 com pull-ups ativos
DDRB=0B00001000;
PORTB=0B00000011;
// T/C2 Clock: 2000,000 kHz
// Modo: Fast PWM; top=0xFF
// OC2A: PWM Não-Invertido; OC2B: Desconectado
// Pulso PWM: OC2A Periodo: 0,128 ms Largura: 0 us
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(1<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) |
(1<<WGM21) | (1<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
}
Modos de Operação do T/C1

• Modo Normal: Contagem crescente até valor má-


ximo (65.535), sem recarga automática;

• Modo CTC: Clear Timer on Compare Match, onde


a contagem ocorre crescentemente até que OCR1A
ou ICR1=TCNT1, quando TCNT1 é zerado;

• Modo PWM Rápido: Geração de sinal PWM no


pino OC0, com frequências mais elevadas;

• Modo PWM Corrigido em Fase: Geração de si-


nal PWM Corrigido em Fase, para melhor resolução
de sinal;

• Modo PWM Corrigido em Fase/Frequência:


Geração de sinal PWM Corrigido em Fase e em
Frequência, para aplicações que exigem um sinal
PWM de alta resolução.

78
T/C1 no Modo Normal
• Selecionado quando os bits WGM13:0=0000 ;

• A contagem em TCNT1 ocorre sempre no modo crescente,


por Estouro de Contagem (Overow);

• Se TCNT1=65.535 (FFFFH), ocorre o Overow na conta-


gem e o bit de ag TOV1 é setado.

• Interrupção de overow do T/C1 habilitada, através do bit


TOIE1 do registro TIMSK

• Desviar para 0006, se o bit I=1 , e TOIE1 =1.

• Quando da execução da rotina de interrupção o ag TOV1


é automaticamente resetado.

• As unidades de Entrada de Captura, e Saída de Compara-


ção, (Registros ICR1 e OCR1A/OCR1B), funcionam normal-
mente, podendo mesmo gerar interrupções se programadas
para tal.

• Quando a comparação resulta verdadeira a ativação dos pi-


nos OC1A (função alternativa de PD5) e OC1B poderá ser
setado, resetado, ou complemetado, sendo a seleção feita
através dos bits COM1A1 /COM1B1 , COM1A0 /COM1B0 ,
do Registro TCCR1A.

79
T/C1 no Modo CTC (Clear Timer on
Compare Match)

• Continuamente TCNT1 é comparado com o Reg.


de Comparação A: OCR1A, se os bits WGM13:0=4,
ou com o Registro de Captura: ICR1, se os bits
WGM13:0=12, fazendo TCNT1=0, e ativando o
pino externo OC1A (função alternativa de PD5),
sempre que TCNT1=OCR1A ou ICR1.

• OCF1A, ou ICF1, é setado no próximo ciclo de


clock.

• Interrupção de comparação A, ou de captura, ha-


bilitada através do bit OCIE1A ou TICIE1, respec-
tivamente,

80
• Desvio para 0004 ou 0005, se uma instrução SEI,
setou o bit I, e OCIE1A ou TICIE1=1;

• Quando da execução da rotina de interrupção o


bit de ag OCF1A ou TICF1, conforme o caso, é
automaticamente resetado.

• Quando TCNT1=OCR1A ou ICR1, o pino OC1A,


poderá ser setado, resetado, ou complemetado, se-
leção feita através dos bits COM1A1/COM1B1,
COM1A0/COM1B0, (Reg. de Controle TCCR1A).

• Na geração de forma de onda através da saída


OC1A, a frequência mínima gerada será de:

 fOC1A = fClkIO /2,quando OCR1A=0, e a fór-


mula para outros valores em: OCR1A, poderá
ser calculada como sendo:

fClkIO
fOC1A =
2.N.(1 + OCR1A)

Onde: N =fator de prescaler; e fClkIO = Sinal de clock


de E/S
81
T/C1 no Modo PWM Rápido

• A contagem crescente ocorre do valor inicial: 0, até


o máximo: TOP, denido pelo Reg. de Compara-
ção ou de Captura (OCR1A ou ICR1), reiniciando
a contagem em 0.

• No modo Inversor, qdo TCNT1=OCR1A/OCR1B,


o pino OC1A/OC1B, respect., é resetado, voltando
a ser setado quando o contador atinge o valor má-
ximo, reiniciando a contagem no valor 0.

• No modo Não-Inversor, ocorre o oposto: OC1A ou


OC1B é setado, voltando a ser resetado quando
o contador atinge o valor máximo, reiniciando a
contagem no valor 0.

82
Resoluções no modo PWM Rápido

• 3 Modos com resolução xa:


 8, 9, ou 10bits, sendo que os registros OCR1A ou ICR1
deverão ser carregados com valores de comparação que
deverão ser: 255, 511, ou 1023, p/ 8, 9 e 10 bits.

 Largura dos pulsos no pino OC1A dependem do valor em


OCR1A ou ICR1;

• 2 Modos com resolução variável:


 Resolução dada por OCR1A ou ICR1

 Resolução mínima de 2bits, quando o valor em OCR1A


ou ICR1 for 3;

 Resolução máxima de 16bits, quando OCR1A ou ICR1 for


de 65535.

 Outras resoluções dadas por: R = log(T OP +1)


log(2)

• Seleção do modo através dos bits:


 WGM13 , WGM12 , WGM11 , e WGM10 ∗

 Bits dos Regs. TCCR1A, e TCCR1B

 Além destes 5 modos de PWM Rápido, outros 10 modos


são possíveis, totalizando 15 modos de operação do T/C1.

∗ WGM12/WGM11/WGM10==CTC1/PWM11/PWM10 no AT90S8515.
83
Frequência do sinal PWM (OC1A/OC1B):
fClkIO
fOC1A =
N.(1 + T OP )

Onde: T OP =valor em OCR1A ou ICR1, de 3 a 65.536


fClkIO = Sinal de clock de E/S

• No modo PWM, os bits FOC1A e FOC1B , do registro TCCR1A, deverão


estar em nível lógico 0.

• O sinalizador de Overow - TOV1, será setado sempre que a contagem


atingir o valor máximo denido em OCR1A, e sempre que uma compara-
ção resulta verdadeira, o ag correspondente: OCF1A/OCF1B também
é setado no mesmo ciclo de clock.

• Interrupções de comparação do T/C1 são habilitadas, através do bit


OCIE1A, ou OCIE1B ;

• Desvio para 0004, ou 0005, respectivamente, se as interrupções foram


previamente habilitadas e o bit I=1 .

• O bit de ag OCF1A ou OCF1B é automaticamente resetado, quando


do atendimento da respectiva interrupção, onde pode-se atualizar o valor
máximo - TOP, e o valor de comparação.

• O uso do Registro de Captura - ICR1, para a denição do valor máximo


(TOP), de forma a manter este xo, é o modo mais apropriado para este
registro. Se for necessário a mudança da frequência do sinal PWM de
forma dinâmica, através da mudança deste valor máximo, deve-se usar o
Registro OCR1A, uma vez que este conta com um buer duplo.

84
T/C1 no Modo PWM Corrigido em Fase
• Contagem crescente/decrescente de 0 ao valor máximo res-
pectivo à resolução desejada, e voltando a contar de forma
decrescente até 0, ciclicamente.

• O PWM Corrigido em Fase opera com dupla inclinação, re-


duzindo com isto a frequência de operação.

• Quando TCNT1=OCR1A/OCR1B => PD5 (OC1A)/OC1B


serão setados ou resetados, conforme: COM1A1 /COM1A0
p/ OC1A, e COM1B1 /COM1B0 p/ OC1B (TCCR1A).

85
• No modo Não-Inversor, quando TCNT1=OCR1A
ou OCR1B, na contagem crescente, a saída OC1A
ou OC1B é resetada. Na contagem decrescente,
OC1A ou OC1B é setada.

• No modo Inversor da Saída de Comparação, a ope-


ração é inversa a descrita acima.

• O modo como se comportará o pino de saída OC1A,


ou OC1B, é determinada pelos bits de Seleção de
Modo de Saída de Comparação: COM1x1 e COM1x0.

Frequência/Resolução (OC1A/OC1B):
fClkIO
fOC1A =
2.N.T OP

Onde: fClkIO = Sinal de clock de E/S

T OP =valor em OCR1A ou ICR1, de 3 a 65.536

Resolução, é a mesma que para o PWM Rápido:

log(T OP + 1)
R=
log(2)
86
T/C1 no Modo PWM Corrigido em Fase
e Frequência

• Contagem de 0 ao valor máximo respectivo à reso-


lução desejada, e voltando a contar de forma de-
crescente até 0, ciclicamente repetindo o processo,
dando origem a dupla inclinação.

• Diferença em relação ao modo Corrigido em Fase:


atualização do Registro de Comparação - OCR1x,
que agora é atualizado no valor mínimo de con-
tagem, ou seja em 0. Com isto os instantes de
comparação serão simétricos.

• Resolução e frequência do sinal PWM são as mes-


mas do modo PWM Corrigido em Fase.

87
Reg. de Controle B do T/C1 - TCCR1B
TCCR1B
ICNC1 ICES1  WGM13 WGM12 CS12 CS11 CS10

• Bits CS12, CS11, CS10: Clock Selection do T/C1,


selecionam a operação como Temporizador com um
valor de prescaler (8/64/256/1024), ou Contador
de Eventos com ativação do sinal T1 na borda de
descida ou subida.
CS12 CS11 CS10 Clock do Contador
0 0 0 Para a contagem do T/C1
0 0 1 Clock proveniente do clock da CPU
0 1 0 Clock = clock da CPU/8
0 1 1 Clock = clock da CPU/64
1 0 0 Clock = clock da CPU/256
1 0 1 Clock = clock da CPU/1024
1 1 0 Clock=T1na borda de descida
1 1 1 Clock=T1 na borda de descida

• Bit ICNC1: Input Capture Noise Canceler, quando


setado, ativa o Circuito Cancelador de Ruído da En-
trada de Captura (ICP1). Produz um atraso nesta
entrada de 4 ciclos de clock;

• Bit ICES1: Input Capture Edge Select, setado sele-


ciona a ativação do pino ICP1, por borda de subida,
resetado por borda de descida.
88
• Bits WGM13, WGM12 : Wave Form Generator Mode, junto
com os bits WGM11, WGM10 , de TCCR1A, selecionam o
modo como operará o T/C1.

Operação WGM13..0 TOP Res. OCR1x TOV1


do T/C1 Obs.2 Obs.1 Atualiz. Ativo
Normal 0000 FFFFH - Imediato FFFFH
PWM c/ Cor- 0001 00FFH 8 bits TOP 0000
reção de Fase
PWM c/ Cor- 0010 01FFH 9 bits TOP 0000
reção de Fase
PWM c/ Cor- 0011 03FFH 10 bits TOP 0000
reção de Fase
CTC 0100 OCR1A OCR1A Imediato FFFFH
PWM Rápido 0101 00FFH 8 bits 0000 TOP
PWM Rápido 0110 01FFH 9 bits 0000 TOP
PWM Rápido 0111 03FFH 10 bits 0000 TOP
PWM Corrigido 1000 ICR1 ICR1 0000 0000
em Fase/Freq.
PWM Corrigido 1001 OCR1A OCR1A 0000 0000
em Fase/Freq.
PWM Corrigido 1010 ICR1 ICR1 TOP 0000
em Fase
PWM Corrigido 1011 OCR1A OCR1A TOP 0000
em Fase
CTC 1100 ICR1 ICR1 Imediato FFFFH
Reservado 1101 - - - -
PWM Rápido 1110 ICR1 ICR1 0000 TOP
PWM Rápido 1111 OCR1A OCR1A 0000 TOP
1 Resolução
2 CTC1/PWM11/PWM10 no AT90S8515

89
Reg. de Controle A do T/C1 - TCCR1A
TCCR1A
COM1A1 COM1A0 COM1B1 COM1B0 - - WGM11/10

• Bits WGM11, WGM10 : Wave Form Generator Mode, junto


com os bits WGM13, WGM12 , de TCCR1B, seleciona o
modo de operação do T/C1, como visto na tabela anterior.

• Bits COM1A1, COM1A0, COM1B1, COM1B0 : Compara-


tor Output Mode, selecionam o comportamento dos pinos
OC1A/OC1B.

Modos Não-PWM
Modo de Ativação das Saidas OC1A e OC1B
COM1X1 COM1X0 Comportortamento de OC1A e OC1B
0 0 OC1A/OC1B Desconectados.
0 1 OC1A/OC1B Muda de estado quando a Com-
paração resultar verdadeira.
1 0 OC1A/OC1B=0 quando a Comparação resul-
ta verdadeira.
1 1 OC1A/OC1B=1 quando a Comparação resul-
ta verdadeira.

90
Modo PWM Rápido
Modo de Ativação das Saidas OC1A e OC1B
COM1X1 COM1X0 Comportortamento de OC1A e OC1B
0 0 OC1A/OC1B Desconectados.
0 1 OC1A Muda de estado na Comparação quando
WGM13:0=15 , e OC1B em OFF. Nos demais
modos, OC1A/OC1B em OFF.
1 0 OC1A/OC1B=0 quando a Comparação resulta
verdadeira, seta no valor máximo (TOP).
1 1 OC1A/OC1B=1 quando a Comparação resulta
verdadeira, reseta no valor máximo (TOP).

Modo PWM c/ Correção de Fase/Freq.


Modo de Ativação das Saidas OC1A e OC1B
COM1X1 COM1X0 Comportortamento de OC1A e OC1B
0 0 OC1A/OC1B Desconectados.
0 1 OC1A Muda de estado na Comparação quando
WGM13:0=9 ou 14 , e OC1B em OFF. Nos
demais modos, OC1A/OC1B em OFF.
1 0 OC1A/OC1B=0 quando a Comparação resulta
verdadeira em contagem crescente.
OC1A/OC1B=1 na contagem decrescente.
1 1 OC1A/OC1B=1 quando a Comparação resulta
verdadeira em contagem crescente.
OC1A/OC1B=0 na contagem decrescente.

91
Exemplo de uso do PWM: Controle de Velocidade de Motor
Neste exemplo, a velocidade do motor CC varia de 0 a 90%
em passos de 10% de acordo com o indicado no display de 7-
segmentos, sendo o ajuste feito pelas teclas INCR e DECR. A
saída PWM usada é a correspondente ao pino PB3=OC2A, sendo
usado portanto, o T/C2 para a geração deste sinal que aciona o
motor via fotoacoplador 4N25 e transistor de potência TIP120.

Código em C no CodeVision:
#include <io.h>
#include <delay.h>

// Protótipo da função inic()


void inic(void);

// Constantes para o acionamento do display de 7-segmentos


unsigned char dado[]={0B11000000,0B11111001,0B10100100,0B10110000,
0B10011001,0B10010010,0B10000010,0B11111000,0B10000000, 0B10011000};

// Constantes para a carga do registro de comparação OCR2A para a geração


// dos ciclos de trabalho de 0 a 90% em passos de 10%
unsigned char pwm_cte[]={0,25,50,75,100,125,150,175,200,225};

// Variável de contagem dos passos de 10%


unsigned char counts=0;

92
// Trata a tecla de incremento de potência
void incrementa(void){
counts++;
if(counts==10) counts=9;
PORTD=dado[counts];
OCR2A=pwm_cte[counts];
delay_ms(500);
}

// Trata a tecla de decremento de potência


void decrementa(void){
counts--;
if(counts==255) counts=0;
PORTD=dado[counts];
OCR2A=pwm_cte[counts];
delay_ms(500);
}

// Função Proncipal
void main(void){
inic();
while(1){
if(!(PINB & 0b00000010)) incrementa();
if(!(PINB & 0b00000001)) decrementa();}
}

// Função de inicialização de periféricos


void inic(void){
// Porta D toda como saída
DDRD=0xFF;
PORTD=0x00;
// PB3 como saída PWM (OC2A) e PB0 e PB1 com pull-ups ativos
DDRB=0B00001000;
PORTB=0B00000011;
// T/C2 Clock: 2000,000 kHz
// Modo: Fast PWM; top=0xFF
// OC2A: PWM Não-Invertido; OC2B: Desconectado
// Pulso PWM: OC2A Periodo: 0,128 ms Largura: 0 us
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(1<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) |
(1<<WGM21) | (1<<WGM20);
TCCR2B=(0<<WGM22) | (0<<CS22) | (1<<CS21) | (0<<CS20);
}
Conversor Analógico p/ Digital do
ATmega328
Arquitetura Interna

93
• Faixa tensões de entrada entre 0 a Vcc, resolução de 10 bits
com erro de não linearidade de 1/2 LSB e erro absoluto de
±2 LSB;

• Conversor A/D por aproximações sucessivas com clock entre


50kHz e 200kHz, e tempo de conversão entre 13 e 260 µs;;

• Habilitado pelo bit ADEN=1 no Reg. de Status ADCSRA;

• Clock do ADC proveniente de um Prescaler alimentado pelo


clock da CPU e fator de prescaler selecionado pelos bits
ADPS2..0 no Reg. de Status ADCSRA;

• 6 Canais de entrada multiplexadas (8 p/ TQFP,QFN,MLF)


selecionados pelos bits MUX3..0 no Reg. de Multiplexação
ADMUX. Um canal de entrada com sensor de temperatura;

• Opções de tensão de referência: pino AREF, pino AVcc, ou


ref. interna de 1,1V;

• Seleção da tensão de referência pelos bits REFS1..0 no Reg.


de Multiplexação ADMUX; ;

• Inicio de conversão feita setando-se o bit ADSC no Reg. de


Status ADCSRA, ou auto-trigger via INT0, T/C0 ou T/C1;

• Final de conversão indicada pelo bit ADIF no Reg. de Status


ADCSRA;

• Resultado obtido no par de registros ADCL,ADCH:


VIN .1024
ADC =
VREF

• Interrupção por Conversão Completada;


Registro de Controle e Status A do ADC
- ADCSRA
ADCSRA
ADEN ADSC ADATE ADIF ADIE ADPS2 ADPS1 ADPS0

• Bits ADPS2, ADPS1, ADPS0 : Bits A/D Prescaler Selection,


selecionam o fator de prescaler para a divisão do clock da
CPU para alimentar o clock do ADC:

ADPS2 ADPS1 ADPS0 Clock do ADC


0 0 0 Clock = clock da CPU/2
0 0 1 Clock = Clock da CPU/2
0 1 0 Clock = clock da CPU/4
0 1 1 Clock = clock da CPU/8
1 0 0 Clock = clock da CPU/16
1 0 1 Clock = clock da CPU/32
1 1 0 Clock = clock da CPU/64
1 1 1 Clock = clock da CPU/128

• Bit ADIE : Bit A/D Interrupt Enable, juntamente com o bit I


de SREG, quando setados habilitam a interrupção por Con-
versão Completada do ADC;

• Bit ADIF : Bit A/D Interrupt Flag, setado por harware para in-
dicar a solicitação de interrupção por Conversão Completada
do ADC. Resetado por hardware quando do atendimento da
interrupção, ou por software se esta interrupção não foi ha-
bilitada;

• Bit ADATE : Bit A/D Auto Trigger Enable, quando setado


habilita o auto trigger na borda de subida de uma das fontes
de trigger possíveis e selecionados por ADTS em ADCSRB;

94
• Bit ADSC : Bit A/D Start Conversion, setado para iniciar a
conversão pelo ADC;

• Bit ADEN : Bit A/D Enable, quando setado habilita o ADC.

Registro de Controle e Status B do ADC


- ADCSRB
ADCSRAB
- ACME - - - ADTS2 ADTS1 ADTS0

• Bits ADTS2, ADTS1, ADTS0 : Bits A/D Trigger Selection,


selecionam a fonte de disparo do ADC:

ADTS2 ADTS1 ADTS0 Fonte de Trigger do ADC


0 0 0 Modo Free Running
0 0 1 Comparador Analógico
0 1 0 Interrupção Externa 0
0 1 1 T/C0 Comparação A
1 0 0 T/C0 Overow
1 0 1 T/C1 Comparação B
1 1 0 T/C1 Overow
1 1 1 T/C1 Evento de Captura

• Bit ACME: Analog Comparator Multiplex Enable - Qunado se-


tado habilita a multiplexação das entradas ADC0..7 para a en-
trada inversora do Comparador Analógico, nesse caso ADEN
deve car em 0 desabilitando o ADC. Resetado seleciona AN1
para a entrada inversora do Comparador Analógico.

95
Reg. Multiplex do ADC - ADMUX
ADMUX
REFS1 REFS0 ADLAR - MUX3 MUX2 MUX1 MUX0

• Bits MUX3, MUX2, MUX1, MUX0 : Bits Analog Channel Mul-


tiplexer 0...3, selecionam o canal de entrada analógica que
será conectado ao ADC:

MUX3..0 Entrada Analógica Selecionada


0000..0111 ADC0...ADC7
1 0 0 0 ADC8 - Sensor de Temperatura
1001...1101 Reservado
1 1 1 0 1,1V - Tensão de Bandgap
1 1 1 1 0V - GND

• Bit ADSC : Bit A/D Start Conversion, setado para iniciar a


conversão pelo ADC;

• Bits REFS1, REFS0 : Bits Reference Selection 0..1, selecio-


nam a fonte da tensão de referência que será conectado ao
ADC:

REF1..0 Tensão de Referência Selecionada


0 0 Pino AREF.
0 1 Pino AVcc c/ capacitor ext. em AREF.
1 0 Reservado
1 1 Tensão de Bandgap 1,1V c/ cap. ext. em AREF

96
Ex: Leitura de sensor LM35 via ADC7 a cada 1,0s

Código em C editado no CodeVision:

// Chip: ATmega328P Clock: 16 MHz


#include <mega328p.h>
#include <delay.h>
#include <alcd.h>
#include <stdio.h>
#include <stdlib.h>

// Vref: Int.1.1V, cap. em AREF


#define ADC_VREF_TYPE ((1<<REFS1)|(1<<REFS0)|(0<<ADLAR))

// Variáveis Globais
unsigned int conta_10ms=100;

// Protótipos das Funções


void inic(void);
unsigned int read_adc(unsigned char adc_input);

// Timer 0 overflow interrupt service routine


interrupt [TIM0_OVF] void timer0_ovf_isr(void){
unsigned int valor;
float grausC;
unsigned char s[5];
97
TCNT0=100;
conta_10ms--;
if(conta_10ms==0) {
conta_10ms=100;
lcd_gotoxy(2,0);
valor=read_adc(7);
grausC =valor/9.3; // Vin(V)=1,1*Valor lido/1024 => T(ºC)=Vin/10mV
ftoa(grausC,2,s); // Converte valor em string de ASCIIs
lcd_puts(s);}
else
return;
}

// Rotina de leitura do ADC


unsigned int read_adc(unsigned char adc_input){
ADMUX=adc_input | ADC_VREF_TYPE;
delay_us(10); // Atraso p/ estabilização da tensão em Vin
ADCSRA|=(1<<ADSC); // Sinal de Start Conversion (ADSC) ativado
while ((ADCSRA&(1<<ADIF))==0);// Espera final de conversão
ADCSRA|=(1<<ADIF); // Reseta flag de interrupção
return ADCW; // Valor de retorno da conversão
}

void main(void){
inic();
lcd_puts("T= (C)");
while(1);
}

void inic(void){
// T/C0: Clock: 15,625 kHz
// Mode: Normal to,0p=0xFF, Timer Period: 9,984 ms
TCCR0A=0x00;
TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=100;
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);
// ADC Clock: 1000,000 kHz, ADC VRef: Int., ADC Start: ADSC
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN)|(0<<ADSC)|(0<<ADATE)|(0<<ADIF)
|(0<<ADIE)|(1<<ADPS2)|(0<<ADPS1)|(0<<ADPS0);
// LCD: RS:PB4, RD:GND, EN:PB5, D4...D7:PB0..3
lcd_init(16); // Caracteres/linha: 16
#asm("sei") // Seta bit de habilitação global de interrupção
}
USART
Arquitetura Interna da USART

98
Características da USART:
• Comunicação Full Duplex, com registros de transmissão e
recepção separados;

• Operações Síncrona e Assíncrona;

• Em operação síncrona, seleção da origem do sinal de clock:


Mestre ou Escravo;

• Possibilidade de comunicação Multiprocessador;

• Taxas de transferência geradas por um circuito de geração de


Baud Rate (bps) de alta resolução;

• Quadros com 5, 6, 7, 8 ou 9 bits de dados, e 1 ou 2 Stop


Bits;

• Geração de Paridade Par ou Ímpar;

• Filtragem de ruído;

• Detecção de erros como: falso Start Bit, erro de quadro, e


Overrun;

• Três interrupções distintas ocorrendo nas seguintes condi-


ções: Transmissão Concluída, Recepção Concluída, e Regis-
tro de Transmissão Vazio;

• Seleção de Velocidade Dobrada no modo Assíncrono.

99
Transmissão de Dados via UART
• Habilitado pelo bit TXEN do Reg. UCSRB

• PD1 assume a função alternativa TXD, sendo conectado ao


transmissor da USART, e passa a ser um pino de saída, inde-
pendente do bit DDD1 em DDRD.

Passos da Transmissão
1. O Byte a ser transmitido deve ser escrito no Reg. de Dados da USART
(UDR);

2. Este passa p/ o Shift Register (SR) somente qdo o Stop Bit do último
byte enviado foi deslocado. Com SR vazio, o bit UDRE=>1 (Data Reg.
Empty no Reg. Contr./Status A da USART (UCSRA), o byte passa do
UDR p/ SR;

3. Se o bit UDRE=1 um novo byte pode ser enviado;


4. Qdo o byte passa do UDR p/ SR, o bit 0 deste registro de 10/11bits é
resetado, gerando o Start Bit, e o bit 9/10 é setado gerando o Stop Bit.

5. Se a USART opera c/ 9 bits de dados, o bit TXB8 de UCSRB é transferido


para o bit 9 do SR;

6. Com a taxa de transm. já programada (Reg. Baud Rate da USART -


UBRR), o Gerador de Baud Rate produz o clock p/ SR que de inicio
transmite o Start Bit, seguido de 8/9 bits da dados (LSB primeiro), e do
Stop Bit;

7. Se um novo dado não foi escrito no reg. UDR qdo o Stop Bit estiver
sendo enviado, o bit UDRE cará setado até que um dado seja ali escrito;

8. Se ao nal do envio do Stop Bit o dado ainda não foi escrito no registro
UDR o sinalizador de término de envio TXC do registro USR é setado.

100
Recepção de Dados via UART
• Habilitado através do bit RXEN do Registro UCR;

• PD0 assume a sua função alternativa (RXD) sendo conectado


ao receptor da USART, e passa a ser um pino de entrada
independente do bit DDD0 do registro DDRD.

Passos da Recepção
1. RXD é amostrado numa taxa 16x maior que Baud Rate, vericando a
ocorrência do Start Bit. Conrmações ocorrem nas amostras 8, 9, e 10
deste sinal amostrado. Não havendo ao menos 2 ocorrências positivas, o
Start Bit é descartado, sendo considerado ruído;

2. O Start Bit detectado corretamente, segue-se a amostragem dos bits de


dados da mesma forma, (amostras 8, 9, e 10), devendo haver coincidência
em pelo menos 2 dos 3 eventos. A medida que estes bits são amostrados
são imediatamente deslocados para o SR;

3. No nal da recepção, agora o Stop Bit é amostrado (amostras 8, 9, e


10). Não havendo ao menos 2 níveis lógicos 1, o Flag de Erro de Quadro
- FE=>1 (Framing Error do Reg. USR). Deve-se, então vericar o bit
FE antes de se ler UDR;

4. Após o dado ter sido recebido serialmente ele é enviado ao UDR mesmo
que um erro de quadro ocorra. Quando o dado já está presente do regis-
tro UDR o bit sinalizador de Recepção Completada - RXC , presente no
registro USR, é setado;

5. Se a leitura do UDR não foi executada após um novo byte de dados


ter sido recebido, ocorrerá um erro de Sobre-escrita, e o bit de Flag ed
Sobreescrita - OR=>1 (Over Run do USR).

6. Na operação da UART com 9 bits de dados (seleção feita pelo bit CHR9 ),
este bit adicional é enviado p/ RXB8 do Reg. UCR, podendo ser usado
como um bit extra de Stop Bit, ou outra informação qquer.

101
Reg. de Controle/Status A - UCSR0A
UCSR0A
RXC0 TXC0 UDRE0 FE0 DOR0 UPE0 U2X0 MPCM0

• Bit RXC0 : Receive Complete, setado quando o receptor tem


um dado pronto para ser lido no buer de recepção, podendo
ser usado para gerar uma interrupção de Recepção Comple-
tada;

• Bit TXC0 : Transmit Complete, setado quando o dado que


estava no buer de transmissão já foi completamente trans-
mitido através do registrador de deslocamento, podendo ser
usado para gerar uma interrupção de Transmissão Comple-
tada;

• Bit UDRE0 : USART Data Register Empty, setado quando


o o buer de recepção está vazio e pronto para receber um
novo dado, podendo ser usado para gerar uma interrupção de
Registro de Dados Vazio;

• Bit FE0 : Frame Error, setado quando um Erro de Quadro


ocorreu no dado recebido pelo buer de recepção. Este bit
deve ser resetado quando se escreve em UCSR0A. O bit FE0
é válido até que o registro de dados UDR0 é lido, sendo
resetado quando o Stop Bit é recebido.

102
• Bit DOR0 : Data Overrun, setado quando o buer de recep-
ção está cheio, um novo dado é recebido pelo registrador de
deslocamento, e um novo Start Bit é recebido. O bit DOR0
é válido até que o registro de dados UDR0 é lido, devendo
ser resetado quando se escreve em UCSR0A.

• Bit PE0 : Parity Error, setado quando um Erro de Paridade


ocorreu no dado recebido pelo buer de recepção, caso a
vericação de paridade tenha sido habilitada através do bit
UPM0 . Este bit deve ser resetado quando se escreve em
UCSR0A. O bit PE0 é válido até que o registro de dados
UDR0 é lido.

• Bit U2X0 : Sigla de USART Double Transmission Speed,


tendo efeito somente quando na operação Assíncrona, de-
verá ser resetado na operação síncrona. Se setado, este bit
permite dobrar a taxa de transmissão, pelo divisor do clock
que ao invés de 16 será 8.

• Bit MPCM0 : Sigla de Multi-Processor Communication Mode,


este bit quando setado habilita a Comunicação Multiproces-
sador, onde os quadros recebidos pelo circuito Receptor da
USART sem informações de endereço serão ignorados. O
circuito Transmissor da USART não é afetado por este bit.

103
Reg. de Controle/Status B - UCSR0B

UCSR0B
RXCIE0/TXCIE0 UDRIE RXEN0/TXEN0 UCSZ2 RXB80/TXB80

• Bit RXCIE0 : Sigla de RX Complete Interrupt Enable. Este


bit quando setado habilita a interrupção pelo ag RXC0 .

• Bit TXCIE0 : Sigla de TX Complete Interrupt Enable. Este


bit quando setado habilita a interrupção pelo ag TXC0 .

• Bit UDRIE0 : Sigla de USART Data Register Empty Interrupt


Enable. Este bit quando setado habilita a interrupção pelo
ag UDRE0 .

• Bit RXEN0 : Sigla de Receiver Enable, quando setado este


bit habilita a recepção de dados pela USART. O pino PD0,
que tem como função alternativa: RXD, que é o pino de
recepção serial, assume esta função, desconsiderando alguma
conguração anterior.

• Bit TXEN0 : Sigla de Transmitter Enable, quando setado


este bit habilita a transmissão de dados pela USART. O pino
PD1, que tem como função alternativa: TXD , que é o pino
de transmissão serial, assume esta função, desconsiderando
alguma conguração anterior.

• Bit UCSZ02 : Sigla de Character Size. Este bit, em conjunto


com os bits UCSZ1:0 do Registro UCSRC, seleciona o número
de bits da palavra de dados em um quadro a ser transmitido
ou recebido.
104
• Bit RXB80 : Sigla de Receive Data Bit 8, representa o nono
bit da palavra de dados recebida, quando operando com pa-
lavras de dados de 9 bits. Este bit deverá ser lido antes da
leitura dos demais bits em UDR0.

• Bit TXB80 : Sigla de Transmit Data Bit 8, representa o nono


bit da palavra de dados a ser transmitida, quando operando
com palavras de dados de 9 bits. Este bit deverá ser escrito
antes da escrita dos demais bits em UDR0.
Reg. de Controle/Status C - UCSR0C
UCSR0C
UMSEL01..0 UPM01..0 USBS0 UCSZ01..0 UCPOL0

• Bits UMSEL01..0 : Sigla de USART Mode Select, que per-


mite selecionar o modo de operação da USART, em operação
assíncrona, com UMSEL=00, síncrona, com UMSEL=01, ou
Master SPI com UMSEL=11.

• Bits USBS0 : Sigla de USART Stop Bit Select. Este bit


seleciona o número de Stop-Bits a ser inserido no quadro de
dados pelo transmissor. Se setado seleciona 2 Stop Bits, se
resetado, seleciona 1 Stop Bit.

• Bit UCPOL0 : Sigla de Clock Polarity, este bit seleciona a


polaridade do sinal de clock na operação Síncrona.

Seleção da Polaridade do Clock no Modo Síncrono


UCPOL0 Mudança de Dado Amostragem do Dado
em TXD em RXD
0 Borda de Subida Borda de Descida
1 Borda de Descida Borda de Subida

105
• Bits UPM01..0 : Sigla de Parity Mode. Este bit habilita e
seleciona o modo de geração do bit de vericação de paridade.
Na transmissão, o bit de paridade é gerado e transmitido
jundo com o dado, e na recepção o bit de paridade é gerado
pelo dado recebido, e comparado com o bit de paridade que
acompanha este dado. Se houver um erro de paridade este
será indicado pelo sinalizador PE , em UCSRA.

Habilitação e Seleção da Paridade


UPM01 UPM00 Mode de Paridade
0 0 Desabilita Paridade
0 1 Reservado
1 0 Habilita Paridade Par
1 1 Habilita Paridade Impar

• Bits UCSZ1:0 : Sigla de Character Size. Estes bits, em con-


junto com os bits UCSZ2 do Registro UCSRB, seleciona o
número de bits da palavra de dados em um quadro a ser
transmitido ou recebido.

Seleção do Tamanho da Palavra de Dados


UCSZ02 UCSZ01 UCSZ00 Tamanho da Palavra
0 0 0 5 Bits de Dados
0 0 1 6 Bits de Dados
0 1 0 7 Bits de Dados
0 1 1 8 Bits de Dados
1 0 0 Reservado
1 0 1 Reservado
1 1 0 Reservado
1 1 1 9 Bits de Dados

106
Baud Rate (bps) x Frequência do Cristal (MHz)
Conteúdos de UBRR0 para Erro ≤2%
Taxa 1,000 1,000 1,8432 1,8432 2,0000 2,0000
U2X0 0 1 0 1 0 1
2400 25 51 47 95 51 103
4800 12 25 23 47 25 51
9600 - 12 11 23 12 25
14,4K - - 7 15 - -
19,2K - - 5 11 - 12
28,8K - - 3 7 - -
38,4K - - 2 5 - -
57,6K - - 1 3 - -
76,8K - - - 2 - -
115,2K - - 0 1 - -
230,4K - - - 0 - -
250K - - - - - 0
Taxa 3,6864 3,6864 4,0000 4,0000 7,3728 7,3728
U2X0 0 1 0 1 0 1
2400 95 191 103 207 191 383
4800 47 95 51 103 95 191
9600 23 47 25 51 47 95
14,4K 15 31 - 34 31 63
19,2K 11 23 12 25 23 47
28,8K 7 15 - - 15 31
38,4K 5 11 - 12 11 23
57,6K 3 7 - - 7 15
76,8K 2 5 - - 5 11
115,2K 1 3 - - 3 7
230,4K 0 1 - - 1 3
250K - - 0 1 - -
0,5M - - - 0 - -
107
Taxa 8,000 8,000 11,0592 11,0592 14,7456 14,7456
U2X0 0 1 0 1 0 1
2400 207 416 287 575 383 767
4800 103 207 143 287 191 383
9600 51 103 71 143 95 191
14,4K 34 68 47 95 63 127
19,2K 25 51 35 71 47 95
28,8K - 34 23 47 31 63
38,4K 12 25 17 35 23 47
57,6K - - 11 23 15 31
76,8K - 12 8 17 11 23
115,2K - - 5 11 7 15
230,4K - - 2 5 3 7
250K 1 3 - - - -
0,5M 0 1 - - - -
1M - 0 - - - -
Taxa 16,000 16,000 18,4320 18,4320 20,000 20,000
U2X0 0 1 0 1 0 1
2400 416 832 479 959 520 1041
4800 207 416 239 479 259 520
9600 103 207 119 239 129 259
14400 68 138 79 159 86 173
19200 51 103 59 119 64 129
28800 34 68 39 79 42 86
38400 25 51 29 59 32 64
57600 - 34 19 39 21 42
76800 12 25 14 29 15 32
115200 - - 9 19 10 21
230,4K - - 4 9 - 10
250K 3 7 - - 4 9
0,5M 1 3 - - - 4
1M 0 1 - - - -
108
Equações para Baud Rate e UBRR da USART
Modo Cálculo de Baud Rate* Cálculo de UBRR*
Assíncr. Normal BAU D = fOSC
16.(U BRR+1)
U BRR = fOSC
16.BAU D
−1
(U2X=0)
Assíncr. Dobro BAU D = fOSC
8.(U BRR+1)
U BRR = fOSC
8.BAU D
−1
da Tx. (U2X=1)
Síncr. Mestre BAU D = fOSC
2.(U BRR+1)
U BRR = fOSC
2.BAU D
−1

*BAU D=Baud Rate, fosc=Freq. do Cristal, U BRR=Conteúdo de UBRR

Ex: Leitura de sensor LM35 via ADC7 a cada 1,0s


e envio de dados p/ USART

Código em C editado no CodeVision:

// Chip: ATmega328P Clock: 16,000000 MHz


#include <mega328p.h>
#include <delay.h>
#include <stdio.h>
#include <stdlib.h>

// Voltage Reference: Int., cap. on AREF


#define ADC_VREF_TYPE ((1<<REFS1)|(1<<REFS0)|(0<<ADLAR))

// Variáveis Globais
unsigned int temp1,time_ms;

// Rotina de Inicializações
void inic(void){
DDRB=(0<<DDB7) | (0<<DDB6) | (1<<DDB5) | (0<<DDB4) | (0<<DDB3)
| (0<<DDB2) | (0<<DDB1) | (0<<DDB0);
PORTB=0x00;
// Timer/Counter 0 Clock: System Clock (15,625 kHz)
// Mode: Normal top=0xFF
// Timer Period: 9,984 ms
TCCR0A=(0<<COM0A1) | (0<<COM0A0) | (0<<COM0B1) | (0<<COM0B0) |
(0<<WGM01) | (0<<WGM00);
TCCR0B=(0<<WGM02) | (1<<CS02) | (0<<CS01) | (1<<CS00);
TCNT0=0x64;
109
// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=(0<<OCIE0B) | (0<<OCIE0A) | (1<<TOIE0);
// USART: 8 Data, 1 Stop, No Parity
// USART Receiver: Off, Transmitter: On
// USART0 Mode: Asynchronous, Baud Rate: 9600
UCSR0A=(0<<RXC0) | (0<<TXC0) | (0<<UDRE0) | (0<<FE0) | (0<<DOR0)
| (0<<UPE0) | (0<<U2X0) | (0<<MPCM0);
UCSR0B=(0<<RXCIE0) | (0<<TXCIE0) | (0<<UDRIE0) | (0<<RXEN0) |
(1<<TXEN0) | (0<<UCSZ02) | (0<<RXB80) | (0<<TXB80);
UCSR0C=(0<<UMSEL01) | (0<<UMSEL00) | (0<<UPM01) | (0<<UPM00) |
(0<<USBS0) | (1<<UCSZ01) | (1<<UCSZ00) | (0<<UCPOL0);
UBRR0H=0x00;
UBRR0L=0x67;
// ADC Clock: 1000,000 kHz, VRef: Int., cap. on AREF
// ADC Auto Trigger Source: ADC Stopped
ADMUX=ADC_VREF_TYPE;
ADCSRA=(1<<ADEN) | (0<<ADSC) | (0<<ADATE) | (0<<ADIF) |
(0<<ADIE) | (1<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);
ADCSRB=(0<<ADTS2) | (0<<ADTS1) | (0<<ADTS0);
// Global enable interrupts
#asm("sei")
}

// Timer 0 overflow interrupt service routine


interrupt [TIM0_OVF] void timer0_ovf_isr(void){
unsigned int i, valor;
float grausC;
unsigned char s[5];
TCNT0=0x64;
time_ms--;
if(time_ms==0) {
PORTB.5=~PORTB.5; // Pisca LED em PB5
time_ms=temp1;
valor=read_adc(0);
grausC =valor/9.3; // Temp(ºC)=(1.1*Valor Lido)/(1023*10mV)
ftoa(grausC,2,s); // Converte valor em string de ASCIIs
for(i=0;i<=4;i++){
while(!(UCSR0A & (1<<UDRE0)));
UDR0=s[i];}
while(!(UCSR0A & (1<<UDRE0)));
UDR0=0x0a;} // ASCII do LF (New Linha)
else
return;
}

// Lê resultado da conversão do canal adc_input


unsigned int read_adc(unsigned char adc_input){
ADMUX=adc_input | ADC_VREF_TYPE;
delay_us(10); // Delay para estabilização de Vin
ADCSRA|=(1<<ADSC); // Start the AD conversion
while ((ADCSRA & (1<<ADIF))==0); // Espera final de conversão
ADCSRA|=(1<<ADIF);
return ADCW;
}

// Rotina Principal
void main(void){
inic();
time_ms=temp1=100;
while(1);
}

Memória EEPROM
• 1kB de capacidade com área separada da área de dados;

• Até 100.000 ciclos de apagamento e escrita;

• Usada como uma área de dados ocasionais, de conguração


do sistema, ou variáveis que devem ser lidas no re-início do
programa, ou quaisquer outras situações parecidas.

• Um circuito de temporização permite que o software possa


detectar quando um próximo byte pode ser escrito com segu-
rança.

• Quando um ciclo de escrita na EEPROM está em andamento


a CPU espera por dois ciclos de clock antes que a próxima
instrução possa ser executada, e no ciclo de leitura esta espera
é de quatro ciclos de clock.
Ciclo de Escrita na EEPROM
1. Esperar que o bit de habilitação de escrita EEWE (Reg.
EECR) vá a 0;

2. Esperar que o bit de habilitação de escrita na Flash SPMEN


(Reg. SPMCR) vá a 0;

3. Carregar os reg. de Endereço da EEPROM:


EEARL/EEARH c/ o endereço destino de escrita;

4. Carregar o dado a ser escrito no registro de Dados da EE-


PROM - EEDR (opcional);

5. Fazer bit mestre de habilit. de escrita: EEMWE=1 (Reg.


EECR);

6. Antes de quatro ciclos de clock, setar o bit de habilitação de


escrita EEWE ;

7. Após um tempo entre 2,5 e 4ms (conforme tensão Vcc) o bit


EEWE será resetado por hardware.

110
Ciclo de Leitura da EEPROM
1. Carregar os registros de Endereço da EEPROM: EEARL e
EEARH com o endereço fonte de leitura;

2. Setar o bit de habilitação de leitura: EERE e esperar até


que este bit seja resetado por hardware indicando a leitura do
dado requerido. Este bit encontra-se no registro de Controle
da EEPROM - EECR;

3. O bit EEWE deve ser recenseado pelo programa, antes de se


iniciar um ciclo de leitura de modo a evitar a perda do dado
em processo de escrita.

Reg. de Controle da EEPROM - EECR


EECR
- - - - EERIE EEMWE EEWE EERE

• Bit EERIE : EEPROM Ready Interrupt Enable, quando setado


habilita a interrupção quando o bit de escrita na EEPROM -
EEWE for a nível 0, indicando o nal do ciclo de escrita.

111
• Bit EERE : EEPROM Read Enable, deverá ser levado a 1,
após o endereço de leitura ter sido colocado nos Registros de
Endereço - EEARH/L.

 Após EERE ter sido setado, o dado estará disponível ime-


diatamente no Registro de Dados - EEDR, e a CPU é
parada por 4 ciclos até a próxima instrução ser executada,
quando EERE é automaticamente resetado.

 Quando uma operação de escrita na EEPROM está em


curso, não será possível ler a EEPROM, ou mesmo alterar
o endereço em EEAR, sendo portanto necessário vericar
o estado do bit EEWE .

• Bit EEWE : EEPROM Write Enable, deverá ser levado a 1,


após o dado a ser escrito estar disponível no Registro de
Dados, e o endereço de escrita ter sido colocado nos Registros
de Endereço - EEAH/L.

 Antes do bit EEWE ser setado, o bit EEMWE deverá


ser setado, caso contrário a operação de escrita não é
executada.

 Quando uma operação de escrita na memória Flash está


em curso, não será possível executar a operação de escrita
na EEPROM, sendo portanto necessário vericar o estado
do bit SPMEN .

 Após a escrita ter sido concluída, EEWE é automatica-


mente resetado.

112
• Bit EEMWE : Sigla para EEPROM Master Write, este bit
deverá ser setado, para permitir a escrita na EEPROM, sendo
automaticamente resetado após 4 ciclos de clock.

Registros de Endereço Superior e Inferior


da EEPROM - EEARH/EEARL
• Par de registros que constitui o endereço de acesso à EE-
PROM, podendo acessar até 512 posições da EEPROM. Seu
valor inicial é indenido, sendo portanto necessário sua inici-
alização quando se for acessar algum dos 512 endereços da
EEPROM.

Registro de Dados da EEPROM - EEDR


• Conterá o dado a ser escrito na EEPROM, na posição de
memória especicada no par de registros EEARH/L, quando
a operação for de escrita, e receberá o dado proveniente desta
posição de memória quando da operação de leitura.

Funções de Biblioteca do Codevision p/


Escrita e Leitura em EEPROM denidas
em eeprom.h
void eeprom write byte(addr,value);

unsigned char eeprom read byte(addr)


113
Comparador Analógico

• Compara os valores de tensão presentes no pinos de AIN0 e


AIN1, funções alternativas de PD6 e PD7, levando na saída
ACO=1 se AIN0>AIN1; ou alternativamente, compara AIN0
com ADCn, n selecionável pelos bits ACME em ADCSRB,
ADEN em ADCSRA, e MUX2..0 em ADMUX.

• Interrupção habilitada pelo bit ACIE=1 do Reg. de Contr.


do Comp. Analógico - ACSR, e I =1.

• Pode disparar a captura no T/C1, se o bit ACIC =1 no Reg.


ACSR, e TICIE1=1 no Reg. TIMSK.

• Desta forma, toda a lógica vista para o processo de captura


do T/C1 pode ser utilizada pelo Comparador Analógico.

114
• O bit ACD de ACSR, se setado desabilita o Comparador Ana-
lógico, desconectando-o da fonte de alimentação, reduzindo
o consumo de energia]

• Antes de se fazer a desconexão, a interrupção do Compara-


dor Analógico deve ser desabilitada, com bit ACIE-0 , caso
contrário, uma interrupção poderá ocorrer.

• Além disto, é importante observar que ACD , após o Reset


estará em 0, deixando o Comp. Analógico conectado a Vcc.

Reg. A de Controle e de Status do Com-


parador Analógico - ACSRA
ACSRA
ACD ACBG ACO ACI ACIE ACIC ACIS1 ACIS0

• Bit ACD : Setado desliga o Circuito do Comparador Analógico


da alimentação, diminuindo o consumo de energia. Após o
reset, ACD =0, ligando o Comparador Analógico a alimenta-
ção;

• Bit ACBG : Setado, coloca uma tensão de referência xa em


AIN0, em lugar da tensão proveniênte do circuito externo.

115
• Bit ACO : Saída do Comparador Analógico, setado se a tensão
em AIN0>AIN1, resetado em contrário. ACO será atrasado
de 1 a 2 clocks.

• Bit ACI : Setado por hardware quando a interrupção é dispa-


rada. Se o bit ACIE=1 e I=1 , uma requisição de interrupção
é gerada. Resetado quando a interrupção é atendida. Pode-se
resetar ACI por software, setando-se este bit.

• Bit ACIE : Setado habilita a interrupção do Comparador Ana-


lógico, desde que I=1 em SREG.

• Bit ACIC : Setado habilita a função de Captura do T/C1 a ser


disparada pelo Comparador Analógico. Resetado, desabilita
esta conexão.

• Bits ACIS0/1 : Seleção de que evento dispara a interrupção


do Comparador Analógico:

ACIS1 ACIS0 Modo de Interrupção*


0 0 Mudança de Estado de ACO
0 1 Reservado
1 0 Borda de Descida de ACO
1 0 Borda de Subida de ACO
* Quando se atua nos bits ACIS1/0, o bit ACIE deve estar
resetado caso contrário uma interrupção poderá ser gerada

116
Reg. B de Controle e de Status do Con-
versor Analógico p/ Digital - ADCSRB
ADCSRB
- ACME - - - ADTS2 ADTS1 ADTS0

• Bit ACME : Quando este bit é setado e o Circuito do Conver-


sor A/D está desligado da alimentação (ADEN=0 em ADCSRA),
o multiplex do ADC seleciona uma das entradas ADC0..7
como entrada negativa. Se resetado seleciona AIN1 como
entrada negativa, independente do estado de ADEN. Se am-
bos os bits ACME e ADEN estão setados AIN1 também é
selecionado como entrada negativa;

ACME ADEN MUX2..0 Entrada Negativa


0 x xxx AIN1
1 1 xxx AIN1
1 0 xxx=n ADCn

• Bits ADTS2..0 : Não inui no Comparador Analógico sendo


usado pelo Circuito do Conversor A/D para seleção do modo
de auto-trigger.

117
Temporizador Watchdog - WDT
O WDT conta com um oscilador interno independente de 128kHz.
Produzirá um Reset caso uma instrução WDR não seja executada
antes do timeout do WDT.

Registro de Controle e Status do Temporiz. Wat-


chdog - WDTCSR:

WDTCSR
WDIF WDIE WDP3 WDCE WDE WDP2 WDP1 WDP0

• Bit WDE: Watchdog Enable, quando setado habilita o


WDT. Só é possível resetar WDE, se o bit WDCE estiver
setado, imediatamente antes de se resetar WDE ;

118
• Bit WDCE: Watchdog Change Enable, quando setado
permite que o WDT possa ser desabilitado através do bit
WDE quando este for ser resetado.

• Bits WDP2, WDP1, WDP0: Watchdog Prescaler


Bits2...0, selecionam o fator de pré-divisão do clock de 1MHz:

Seleção do Período p/ o WDT


WDP3 WDP2 WDP1 WDP0 Ciclos do Time-out
Osc. WDT (5,0V)
0 0 0 0 2K 16 ms
0 0 0 1 4K 32 ms
0 0 1 0 8K 64 ms
0 0 1 1 16K 0,125 s
0 1 0 0 32K 0,25 s
0 1 0 1 64K 0,5 s
0 1 1 0 128K 1,0 s
0 1 1 1 256K 2,0 s

Seleção do Período p/ o WDT (Continuação)


WDP3 WDP2 WDP1 WDP0 Ciclos do Time-out
Osc. WDT (5,0V)
1 0 0 0 512K 4,0 s
1 0 0 1 1024K 8,0 s
1 0 1 0 Reservado
1 0 1 1 Reservado
1 1 0 0 Reservado
1 1 0 1 Reservado
1 1 1 0 Reservado
1 1 1 1 Reservado
Interface com RTC - DS1302

• O DS1302 é um Relógio de Tempo Real (RTC) que conta


segundos, minutos, horas, dia do mês, dia da semana, mês,
ano, e ano bissexto até 2100;

• Alimentado entre 2,0 e 5,5V consumindo 300nA em 2,0V;

• TTL Compatível e Interface com 3 linhas: RST, SCLK e I/O;

• Usa cristal externo de 32,768kHz conectado aos pinos X1 e


X2;

• 31 bytes de RAM não-volátil por bateria de 3,0V conectada


aos pinos Vcc1 e GND.

• Dados de relógio lidos dos registros estarão em BCD.

• Funções de biblioteca para controle do DS1302 fornecidas


pelo arquivo de cabeçalho <ds1302.h>.

119
RTC - DS1302
unsigned char ds1302 read(unsigned char addr);

void ds1302 write(unsigned char addr,unsigned char data);

void rtc init(unsigned char tc on,unsigned char diodes,unsigned


char res);

void rtc get time(unsigned char *hour,unsigned char *min,unsigned


char *sec);

void rtc set time(unsigned char hour,unsigned char min,unsigned


char sec);

void rtc get date(unsigned char *day,unsigned char *month,unsigned


char *year);

void rtc set date(unsigned char day,unsigned char month,unsigned


char year);

REGISTRO FUNÇÃO DADOS PERMITIDOS


0X80 Escrita Segundos 00-59
0X81 Leitura Segundos 00-59
0X82 Escrita Minutos 00-59
0X83 Leitura Minutos 00-59
0X84 Escrita Horas (bit 7 12/24) 00-23/01-12
0X85 Leitura Horas (bit 7 12/24) 00-23/01-12
0X86 Escrita Dia 00-28/29/30/31
0X87 Leitura Dia 00-28/29/30/31
0X88 Escrita Mês 00-12
0X89 Leitura Mês 00-12
0X8A Escrita Dia da Semana 00-07
0X8B Leitura Dia da Semana 00-07
0X8C Escrita Ano 00-99
0X8D Leitura Ano 00-99

120
Código em C editado no CodeVision:

/* Chip: ATmega328P Clock: 16 MHz */


#include <mega328p.h>
#include <stdlib.h>
#include <alcd.h> // Alphanumeric LCD functions
#include <delay.h>
// DS1302 Real Time Clock functions
#asm
.equ __ds1302_port=0x08 ;PORTC
.equ __ds1302_io=0
.equ __ds1302_sclk=1
.equ __ds1302_rst=2
#endasm
#include <ds1302.h>

void init();
unsigned char *bcd2string(unsigned char dado);
unsigned char s[3];

void main(void){
unsigned char temp;
init();
//rtc_set_time(13,50,0); Para setar a hora 13:50:00
//rtc_set_date(2,9,14); Para setar a data 02/09/14
temp=ds1302_read(0x87); // Leitura do Dia
121
lcd_puts(bcd2string(temp));
lcd_putchar('/');
temp=ds1302_read(0x89); // Leitura do Mês
lcd_puts(bcd2string(temp));
lcd_putchar('/');
temp=ds1302_read(0x8d); // Leitura do Ano
lcd_puts(bcd2string(temp));
lcd_gotoxy(0,1);
lcd_puts("Time:");
while(1){
lcd_gotoxy(5,1);
temp=ds1302_read(0x85); // Leitura das Horas
lcd_puts(bcd2string(temp));
lcd_putchar(':');
temp=ds1302_read(0x83); // Leitura dos minutos
lcd_puts(bcd2string(temp));
lcd_putchar(':');
temp=ds1302_read(0x81); // Leitura dos segundos
lcd_puts(bcd2string(temp));
delay_ms(1000);}
}

unsigned char *bcd2string(unsigned char dado){


s[1]=(dado & 0x0f)+0x30;
s[0]=((dado & 0xf0)>>4)+0x30;
return s;
}

void init(){
UCSR0B=0x00;
ACSR=0x80; // Analog Comparator: Off
// DS1302 Real Time Clock initialization
// Trickle charger: On
// Trickle charge resistor: None
// Trickle charge diode(s): 1
rtc_init(1,0,0);
lcd_init(16);
}
Interface SPI
• Serial Peripheral Interface, concebida para comunicação com
outras CPUs ou periféricos dotados com esta interface;

• Possibilita comunicação serial síncrona a 3 os full-duplex;

• 8 possibilidades para a taxa de transmissão de até fosc /2 (no


caso do ATmega328p pode chegar a 8MHz), e possibilidade
de dobrar o clock do Master;

• Operação pode ser como Mestre ou Escravo;

• Escolha de envio do LSB ou MSB como primeiro bit;

• Interrupção de m de transmissão;

• Sinalização de colisão na escrita.

122
Interconexão Master e Slave

Operação do Dispositivo Master


1. Quando o pino Slave Select (SS ¯ ) é habilitado pelo Mestre, tem inicio a
comunicação.
2. O Mestre não tem controle automático do pino SS ¯ , e portanto este deve
ser ativado pelo usuário antes do início da comunicação.
3. Mestre e Escravo preparam os dados a serem transferidos em seus respectivos
shift-registers;
4. Quando o Mestre escreve um byte no registro de dados (SPDR) o sinal de
clock é gerado pelo Mestre, e o byte de dados começa a ser deslocado.
5. Dados são sempre deslocados do Mestre p/ o Escravo no pino MOSI (Master
Out/Slave In) e do Escravo p/ o Mestre no pino MISO (Master In/Slave Out).
6. Após a transferência do byte a geração do sinal de clock é interrompido pelo
Mestre e o sinalizador SPIF é setado.
7. Se a interrupção da SPI estiver habilitada (SPIE=1) uma interrupção é
solicitada.
8. O Mestre pode continuar enviando outro byte escrevendo-o no SPDR ou
então encerrar a transmissão desativando o pinoSS ¯.

Operação do Dispositivo Master


1. Enquando o pino SS¯ for mantido desabilitado o Slave será mantido em modo
Sleep (MISO=z ↑).
2. O Slave em modo Sleep poderá ter um byte escrito no seu registro de dados
SPDR, porém este não será deslocado até que o pino SS ¯ vá a nível lógico 0.

3. Após a transferência do byte o sinalizador SPIF é setado, e se a interrup-


ção da SPI foi previamente habilitada (SPIE=1 em SPCR) uma interrupção é
solicitada.
Conguração de pinos da SPI
Quando a SPI for habilitada as direções dos pinos MOSI, MISO, SCK e SS
cam determinadas conforme a tabela a seguir:

Pino Direção no Master Direção no Slave


MOSI Denido pelo usuário Entrada
MISO Entrada Denido pelo usuário
SCK Denido pelo usuário Entrada
SS Denido pelo usuário Entrada

Reg. de Controle da SPI - SPCR


SPCR
SPIE SPE DORD MSTR CPOL CPHA SPR1 SPR0

• Bit SPIE : Setado habilita a interrupção da SPI, de forma a solicitar uma


interrupção quando o bit SPIF sinalizar um byte transferido. Se o bit I
em SREG estiver setado a interrupção é antendida;

• Bit SPE : Setado habilita a interface SPI;

• Bit DORD : Setado faz com que o LSB seja enviado primeiro, se resetado
o MSB será enviado primeiro;

• Bit MSTR : Setado habilita a operação da SPI no modo Master, se rese-


tado a operação será como Slave;

• Bit CPOL: Setado SCK ca em 1 quando inativo. Resetado SCK em 0


quando inativo.
CPOL Borda Inicial Borda Final

0 Subida Descida
1 Descida Subida

• Bit CPHA: Setado amostragem do dado ocorre na borda inicial, do con-


trário esta ocorre na borda nal do sinal SCK.

CPHA Borda Inicial Borda Final

0 Sample Setup
1 Setup Sample

• Bit SPR1..0 : Seleção da Frequencia de Clock da SPI

Frequencia de Operação
SPI2X SPR1 SPR0 SCK
0 0 0 fosc /4
0 0 1 fosc /16
0 1 0 fosc /64
0 1 1 fosc /128
1 0 0 fosc /2
1 0 1 fosc /8
1 1 0 fosc /32
1 1 1 fosc /64

Reg. de Status da SPI - SPSR


SPSR
SPIF WCOL      SPI2X

• Bit SPIF : Setado indica que uma transferência serial de um byte foi com-
pletada, e uma solicitação de interrupção da SPI é gerada. Se o bit I em
SREG estiver setado a interrupção é antendida;
• Bit WCOL: Setado indica que uma escrita em SPDR foi realizada durante
uma transferência de dados pela interface SPI;

• Bit SPI2X : Setado dobra a velocidade da taxa de transmissão no modo


Master da interface SPI.

Rotinas p/ congurar SPI como Master p/ transmitir um


byte:
void SPI_MasterInic(void)
{
// Configura MOSI e SCK como saída, demais entrada
DDR_SPI |= (1<<DD_MOSI)|(1<<DD_SCK);
// Habilita a SPI, modo Master, clock=fck/16
SPCR |= (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

void SPI_MasterTransmit(unsigned char cData)


{
// Inicia transmissão
SPDR = cData;
// Espera pelo final de transmissão
while((SPSR & (1<<SPIF)) == 0);
}

Rotinas p/ congurar SPI como Slave p/ receber um byte:


void SPI_SlaveInic(void)
{
// Configura MISO como saída, demais entrada
DDR_SPI |= (1<<DD_MISO);
// Habilita a SPI
SPCR |= (1<<SPE);
}

unsigned char SPI_SlaveReceive(void)


{
// Espera pelo final de recepção
while((SPSR & (1<<SPIF)) == 0);
// Returna byte em SPI Data Register
return SPDR;
}
123
124
125
126