Aula X - ricardoteix.com

Propaganda
Aula 15
Prof. Ricardo Teixeira
Tecnologia em Mecatrônica Industrial
SENAI
Memória Flash
Memória Flash
• A memória Flash de programa pode ser escrita e lida
durante a operação normal do programa.
• A operação de gravação na memória Flash causa a parada
da execução do programa até que a gravação seja
completada.
• Ela não pode ser acessada durante a escrita.
• Durante a escrita os periféricos continuam a funcionar e as
interrupções são empilhada até que a escrita acabe.
Memória Flash
• Quando se precisa o espaço da memória de programa para
dados devemos tomar cuidado para não sobrescrever o
próprio programa.
• É preciso verificar o primeiro endereço livre. Para isto abra
o arquivo com extensão .lst após compilar seu programa no
CSS e verifique o endereço da instrução SLEEP, como na
imagem (0x011E).
• O primeiro endereço disponível será o endereço do
SLEEP + 1, neste caso 0x011F.
• Como a memória de programa no PIC18F4550 vai até o
endereço 0x7FFF, temos que nos certificar de utilizar
apenas até este ponto.
Acesso à Flash
• read_program_eeprom(address)
– Lê a memória de programa no endereço address (16 ou 32 bits, varia por
PIC).
– value = read_program_eeprom(address);
• write_program_eeprom(address, value)
– Escreve na memória de programa no endereço address o valor value.
– write_program_eeprom(0x1000, 0x1234)
• erase_program_eeprom(address)
– Apaga FLASH_ERASE_SIZE bytes na memória de programa.
– erase_program_eeprom(0x1000);
Exercício 1
• Crie um programa que exibe o conteúdo da memória
Flash no display LCD
– Na primeira linha o endereço
– Na segunda linha o conteúdo da memória
– O programa é controlado por dois botões
• um deles lê a posição anterior
• O segundo lê a posição posterior
Bootloader
• Bootloader é um programa
utilizado para gravar de forma
mais simples o
microcontrolador.
• Ao utilizar o bootloader não é
preciso utilizar um gravador
específico, o próprio chip
torna-se capaz de gravar o
programa em sua memória,
como é o caso dos chips com
USB nativamente .
• Em outros casos apenas um
circuito de conversão
USB/USART é necessário para
a gravação via USB.
Revisão
Estrutura básica do programa
• Arquivo de interface do microcontrolador
#include <18F4550.h>
• Bits de configuração
#fuses XT, NOWDT, MCLR
• Função principal e loop principal
// função principal
void main () {
// loop principal
while (true) {
}
}
Estrutura básica do programa
• Arquivo de interface do microcontrolador
#include <18F4550.h>
• Bits de configuração
#fuses XT, NOWDT, MCLR
• Delay do sistema
– Se usar o oscilador interno ( #fuses INTRC )
#use delay (clock=4HMz)
– Se usar um cristal como oscilador ( #fuses XT )
#use delay (crystal=4HMz)
Estrutura básica do programa
• Função principal e loop principal
// função principal
void main () {
// loop principal
while (true) {
}
}
Portas de Entrada e Saída
• Funções de saída:
– output_x (int valor), onde x representa a porta (a, b, c, d ou e).
– output_low (PIN_Px), coloca o bit especificado por PIN_Px em nível
baixo (0). Px é a letra da porta e o respectivo bit (A0, B1 etc.)
– output_high (PIN_Px), coloca o bit especificado por PIN_Px em nível
alto (1). Px é a letra da porta e o respectivo bit (A0, B1 etc.)
– output_toggle(PIN_Px), alterna o estado, alto e baixo do bit.
– output_bit( PIN_Px, bit), altera o pino Px para o valor de bit (0 ou 1).
Portas de Entrada e Saída
• Funções de entrada:
– input_x (), lê a porta representa por x (a, b, c, d ou e).
– intput(PIN_Px), lê o pino especificado.
– Intput_state(PIN_Px), lê o pino especificado sem mudar a direção.
Portas de Entrada e Saída
• Registradores TRIS
– Cada porta possui um registrador TRIS associado a ela
– O nome TRIS vem de Tri-state em alusão às portas de 3 estados
(alto, baixo e desconectado)
– Os bits de cada registrados TRIS configuram o bit da porta
respectiva como entrada ou saída.
– Para setar o valor do registrador, por exemplo da porta B, usamos
set_tris_b (0b00001111), os 4 primeiros bits estão
definidos como entrada(1) e o resto como saída (0).
Oscilação
• O oscilador determina a velocidade de execução das
instruções.
• Podemos utilizar o oscilador interno ou externo.
• O clock interno é o clock externo dividido por 4. Assim se
utilizamos um cristal de 4MHz para o clock externo, o clock
interno será de 1MHZ.
• O ciclo de máquina, ou seja, o tempo de execução de cada
instrução (ou pelo menos da maioria delas) é 1/’clock
interno’. Assim, com clock interno do 1MHz teríamos
1/1000000 de clock interno, ou 1μ𝑠 (0,000001𝑠).
Temporização
• Funções de Atraso
– Não são precisas
– São criadas a partir de instruções asm
• delay_cycles(int8 n)
– n – constante de 1 a 255
– Espera n ciclos de máquina
• delay_us(int16 time)
– Time – 0 a 65535
– Espera time microsegundos
• delay_ms(int16 time)
– Time – 0 a 65535
– Espera time milisegundos
Temporização
• As funções de atraso são a pior forma possível de se contar
ou esperar algum tempo!
• A forma correta é a utilização dos timers internos do
microcontrolador (Timer0 até Timer3, no caso do
PIC18F4550).
Módulo TIMER0 (8 ou 16 bits)
• Comumente conhecido como RTCC (Real Time Counter Clock).
• Temporização sem comprometer o processamento do
microcontrolador até ocorrência da interrupção.
• Incrementado pelo clock interno ou pelo pino externo T0CKI
(Timer zero clock input), pino RA4.
Módulo TIMER0 - Prescaler
• Diminui a velocidade do TIMER.
• Configurado no registrador T0CON<3:0> nos bits PSA e
T0PS2:T0PS0 e vai de 1:2 áté 1:256.
• Pode ser alterado em tempo de execução.
Módulo TIMER0 - Interrupção
• Ocorre quando há a contagem do TIMER0 no
registrador TRM0 chega ao valor máximo.
• Este valor depende do modo de operação. Em 8
bits o valor é 0xFF e em 16 bits 0xFFFF.
• A interrupção do TIMER0 pode ser habilitada ou
não.
• Mesmo que a interrupção esteja desligada é
possível olhar TRM0IF (timer zero interruption flag)
e saber se ocorreu um estouro.
Como calcular o tempo de interrupção?
• Vamos supor que temos um sistema com o cristal de 20MHz.
Teremos,
20.000.000
𝐶𝑙𝑜𝑐𝑘 𝑖𝑛𝑡𝑒𝑟𝑛𝑜 =
= 5.000.000 𝐻𝑧
4
1
𝐶𝑖𝑐𝑙𝑜 𝑑𝑒 𝑚á𝑞𝑢𝑖𝑛𝑎:
= 0,2𝑢𝑠
5.000.000
• Como o timer, em modo 16 bits, conta até de 0 até 65.535, são
65.536 períodos.
• Assim cada estouro do timer ocorre com
65.536 ∗ 0,2us = 13.107,2us.
• Com o prescaler 1:32, cada contagem do timer dura 32 ciclos de
máquina. Logo, cada estouro ocorre com
32 ∗ 65.536 ∗ 0,2 = 419.430,4us
• Então temos aproximadamente 420ms a cada estouro.
Circuito de Reset
• O pino Master Clear Reset permite a criação de uma
forma de reset via hardware.
• O pino é ativo em 0, isto é, quando seu nível for zero
estará em modo reset.
• É preciso que utilizar o fuse MCLR (#fuses MCLR).
Bounce
• Mas como podemos evitar este problema?
• Para evitar o problema causado pelo bounce pode-se:
– Comparar o estado novo com o antigo diversas vezes
– Ao se perceber a 1 primeira transição aguardar um
tempo antes de voltar a ler o botão.
Algoritmo do Debounce
• Leia o estado do botão
• Se o estado for ativo (em 0 ou em 1, depende do que você
precisa), aguarde algum tempo (ex.: 10ms)
• Leia novamente o estado do botão e se ele se mantiver no
estado ativo execute a ação desejada.
Código
int1 botao = input(PIN_B0);
If (botao == 1) {
delay_ms(10);
botao = input(PIN_B0);
If (botao == 1) {
// ações desejadas
}
}
Interrupções
• É uma forma de tratar determinados eventos que ocorrem,
seja por interferência do usuário ou por alguma fonte
interna ao hardware.
• Quando o evento observado pela interrupção ocorre o
código é interrompido e o processamento desviado para a
ação que deve ser tomada devido ao evento ocorrido.
Interrupções
• Quando devo usar interrupções?
– Contagem de tempo;
– Analisar a mudança de estado e/ou borda;
– Finalização da conversão A/D;
– Interrupção de chagada de dados seriais;
– Comunicação I²C e SPI;
Interrupções no PIC18F4550
• No PIC18F4550 temos várias possibilidades de interrupção.
– Interrupções externas;
– Interrupções de estouro dos Timers;
– Interrupções de mudança de entrada na Porta B;
– Recepção e Transmissão Serial;
– Conversão A/D etc.
Conversão Analógico Digital
• Converte uma tensão analógica em um número digital
binário proporcional.
• Dois parâmetros precisam ser conhecidos:
– Qual a faixa de tensões possíveis.
– Qual a quantidade de bits.
Conversão Analógico Digital
• O cálculo da conversão é feito pela proporção do valor lido
em relação ao valor máximo do conversor A/D.
• O módulo A/D do PIC18F4550 tem resolução de até 10 bits.
• Dessa forma quando fizermos a leitura de um pino A/D
teremos valor digital entre 0 e 1023, para o caso de 10 bits, e
não o valor da tensão de entrada.
• Para obter a leitura do valor analógico temos que fazer um
cálculo de proporção.
– Vamos supor que estamos utilizando o módulo A/D configurado
para 10 bits.
– Dada uma tensão de entrada Vin de um valor entre 0 e Vref, onde
Vref é a tensão de referência do conversor A/D, podemos calcular a
tensão de entrada pela proporção
Vin = leitura / 1023 * Vref
Conversor AD – Exemplo de Configuração
#include <18F4550.h>
#device ADC = 10
#fuses NOWDT, XT, MCLR
#use delay(crystal=4MHz)
#INT_AD
void conversaoAD () {
}
void main () {
setup_adc( ADC_CLOCK_INTERNAL );
setup_adc_ports( AN0 ); // Apenas o canal 0 será usado
set_adc_channel(0); // AN0
enable_interrupts(GLOBAL);
enable_interrupts(INT_AD);
while (true) {
// seu código
}
}
Memória EEPROM
• EEPROM (Electrically Erasable Programmable Read Only
Memory)
• Memória apenas de leitura programável e eletricamente
apagável, ou seja
• Ela não é uma memória apenas de leitura, não acham?
• O PIC18F4550 tem 256 bytes de memória de dados
EEPROM.
• A memória de dados EEPROM permite operações de
leitura e escrita de bytes sem interferência na operação do
microcontrolador.
• Memória não volátil separada das memória de dados e de
programa.
Aplicações da EEPROM
• Configurações do hardware
• Informações de uso de equipamentos
– Quantidade de impressões de uma impressora;
– Odômetro do carro (mesmo quando trocamos a bateria a
marcação não muda em odômetros digitais);
– Configurações de alarme, calendário etc;
• Logs de erro
• De forma geral, qualquer dado que se deseje!
CCS e a EEPROM
• Interrupção:
– INT_EEPROM
• Interrupção executada quando a escrita na EEPROM está completa.
• Funções
– read_eeprom(address)
• Lê o dado na posição de memória EEPROM
• Ex.: value = read_eeprom(0x0);
– write_eeprom(address, value)
• Apaga e escreve o dado value no endereço address da EEPROM.
• Ex.: write_eeprom(0x0, 0x12);
PWM
• Pulse Width Modulation, do inglês, Modulação por Largura
de Pulso.
• Gera uma onda quadrada em um pino digital do
microcontrolador.
• Sua principal função é controlar tensão de alimentação de
dispositivos como motores, lâmpadas, carregadores de
baterias de células solares etc.
PWM
• Observe o exemplo da lâmpada abaixo. Se a lógica um (1)
indica o lâmpada-ligada e a lógica zero (0) indica lâmpadadesligada. O consumo da lâmpada será diretamente
proporcional a duração do pulso. Essa proporção é chamada
normalmente de Duty Cycle.
Exemplo no CCS
#include <18F4550.h>
#FUSES NOWDT, XT, MCLR
#use delay(crystal=4MHz)
int16 valor = 0;
void main() {
output_low(PIN_C1);
setup_ccp1(CCP_PWM);
setup_timer_2(T2_DIV_BY_1, 255, 1);
set_pwm1_duty(valor);
while (true) {
set_pwm1_duty(valor);
valor += 5;
if (valor > 255) {
valor = 0;
}
delay_ms(100);
}
}
Comunicação Serial vs Paralela
Comunicação Serial
• Utiliza apenas duas linhas para comunicação TX e RX, onde,
RX representa a linha que recebe os dados e a TX a linha
que transmite os dados.
Comunicação Serial - CCS
• Funções importantes
– getc() ou getch() / getchar() ou fgetc()
• Obtém um caractere do pino de recepção (do stream especificado no caso do fgetc).
• Use o KBHIT() para checar se algum caractere está disponível.
– gets() or fgets()
• Obtém uma string do pino de recepção (do stream especificado no caso do fgets). Use
getc para receber cada caractere até return (\r) ser encontrado.
– putc() or putchar() or fputc()
• Envia um caractere para a linha de transmissão (do stream especificado no caso do
fputc).
– puts() or fputs()
• Envia uma string para a linha de transmissão (do stream especificado no caso do fputs).
– printf() or fprintf()
• Envia uma string formatada para linha de transmissão (do stream especificado no caso
do fprintf).
– kbhit()
• Retorna true quando um caractere for recebido e estiver disponível para a leitura.
ICSP (In-Circuit Serial Programming)
• Programação Serial no Circuito
– Refere-se a possibilidade de gravar o chip sem removê-lo do
circuito final.
– Desta forma não é preciso colocar o chip em um gravador.
– Evitar danificar o chip por não precisar movê-lo.
• Vários gravadores permitem este modo
– PIC Kit 2; PIC Kit 3; K150; ICD3; ICD3 etc.
• Não é específico da família PIC
– A placa Arduino Uno e Nano também tem este modo.
ICSP no PIC
Download