aula 2 - programando – hc08 -1

Post on 16-Apr-2017

239 Views

Category:

Documents

1 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Programando – HCS08

Instruções básicas e programação

Programação ASSEMBLER: Para programar devemos lembrar que o

processador HCS08 possui 2 registradores: A => Acumulador de 8 bits H:X => registrador de bits

Acum.

H X

Zerando registradores Existem instruções explícitas para zerar os

registradores: CLRA; A = 0 CLRX; X = 0 CLRH; H = 0

O que segue o ponto-vírgula é comentário

Não é necessário usar o ‘;’Somente se for fazer comentário

Carregando nos registradores... Carrega algo no Acum.

LDA #10 ; A = 10 LDA var ; A = var, onde var é um end. de memória LDX #10 ; X = 10 LDX var ; X = var LDHX var ; H:X = mem[var] : mem[var] +1

Lembrando que H e X são cada um de 8 bits. H receberá a posição de memória onde está ‘var’; X receberá a posição de memória seguinte... Como se fosse uma

variável de 16 bits

H X

M[var] M[var+1]

Salvando os registradores Instruções para salvar o acumulador:

STA var ; var = A ou ‘var’ recebe o Acum. STA PTAD ; porta A = A STX var ; var = X STHXvar ; var = H e var+1 = X

‘var +1’ é a posição de memória seguinte à ‘var’

Instruções básicas As operações são sempre com os

registradores. Ex. soma sem carry

ADD #5 ; A = A + 5

Constantes Versus End. De Memória Quando se quer operar com constantes,

deve-se usar o símbolo ‘#’. Se não for usado o ‘#’, o compilador entende

como uma posição de memória.

Ex. ADD #80 ; A = A + 80 Ex. ADD 80 ; A = A + Mem[80]

‘#’ Indica que é uma constante

Sem ‘#’ Indica que é uma posição de memória

Formatos de números O compilador usa $ e % para representar

número sem Hexadecimal e binário, respectivamente. Ex. ADD #10 ; A = A + 10, em decimal Ex. ADD #$A ; A = A + 10, em hexadecimal Ex. ADD #%00001010 ; A = A+10 em binário

Então $ = hexadeximal % = binário

Outras funções Agora que já sabemos os formatos de números usados, vejamos

algumas instruções básicas. Já conhecemos a soma sem carry

Ex. ADD #5 ;A = A+5 No Reference Manual (pág. 157), tem-se a figura abaixo.

Aprendamos a interpretar:

Operação

O que faz: (A = A + operando que pode ser imediato (número) ou memória

Número de clocks gasto

Detalhando um pouco maisSoma um imediato no Acum. Ex. ADD #6

Soma um end. de mem. de 8 bits no Acum. Ex. ADD $80

Soma um end. de mem. de 16 bits no Acum. Ex. ADD $A1BC

Forma usada para trabalhar com vetor.Ex. Caso queira carregar o acumulador com a variável B[10]

CLRHLDX #10 ; X = 10ADD B,X ; A = A+B[x], ou A = A + B[10]

No exemplo acima, a var. B é como se fosse um ponteiro, que Indica uma posição de memória.X é o deslocamento a partir do endereço de B.

INSTRUÇÕES A lista completa de instruções está na

manual de referência, pg 157 em diante.

VOCÊ DEVE TER O MANUAL E CONSULTÁ-LO

PARA VER AS INSTRUÇÕES.

Vejamos outras funções Soma com carry

Ex. ADC var ; A = A + var + carry ADC #5 ; A = A + 5 + carry

Subtração Ex. SUB var ; A = A – var SUB #$F ; A = A - 15

Operações Lógicas Lógica AND (bit a bit)

Ex. AND #2 ; A = A and (0000 0010) Neste exemplo, se inicialmente A = 0000 0111, A 0000 0111 AND 0000 0010 Resulta 0000 0010, que é feito ‘and’ bit a bit

Outras instruções lógicas Lógica OR

Ex. ORA #7 ; A = A or 0000 0111 Lógica XOR

Ex. EOR #3 ; A = A xor 0000 0011 Complemento de 1

COMA ; COM var ; COMX ;

Outras instruções aritméticas Incremento

Ex. INCA ; A = A +1 Ex. INCX ; X = X+1 Ex. INC var ; var = var +1

Decremento DECA ; A = A -1 DECX ; X = X -1 DEC var ; var = var -1.

Somente para endereços de 8 bits...

Funções de desvio Desvios incondicionais

JMP algum_lugar ; pula pra algum_lugar

BRA L1 ; pula pra L1

Loop: LDA #10INCASTA varJMP Loop

Loop: LDA #10INCASTA varBRA Loop

BRA somente pula pra um local

próximo de onde está.

Multiplicação HCS08 possui multiplicação por hardware.

Vejamos o manual:

Faz o produto de X *A. Como X e A são de 8 bits, o resultado é de 16

bits. A parte alta fica em X ,e a parte baixa em A.X

A

AX

*

Multiplicação Vejamos um exemplo.

Leia a porta A e multiplique o valor por 10. A seguir, quarde o resultado em R_alto e R_baixo

Loop: LDA PTAD ;A = Porta ALDX #10 ;X = 10MUL ; faz o produtoSTX R_alto ; salva X em R_altoSTA R_baixo ; salva A em R_baixoJMP Loop ; pula pra Loop

Trabalhando com bits Setar um bit (posições de memória de 8 bits)

BSET 3,PTAD ; PTAD[3] = 1

Zerar um bit BCLR5,PTAD ; PTAD[5] = 0

BCLR7,var ; var[7] = 0

Setar Bit 3 Da porta A

Zerar Bit 5 Da porta A

Testes (IF) Várias instruções de desvio condicional

podem ser usadas. A maioria dos testes é feita, considerando-se

os bits de flag do CCR – ver p. 148.

Testes Desvia se bit for 1

BRSET 3, PTAD, L1

Ex.

Branch if set‘se for 1’

Bit3 da porta A

Então vai pra L1;Senão, segue na próxima linha

BRSET 3,PTAD,L1ADD #3JMP Fim

L1: SUB #5Fim:

Se PTA[3] = 1, então faz A = A – 5 senão, faz A = A + 3

Testes Desvia se bit for 0

BRCLR 3, PTAD, L1

Ex.

Branch if set‘se for 0’

Bit3 da porta A

Então vai pra L1;Senão, segue na próxima linha

BRCLR 3,PTAD,L1ADD #3JMP Fim

L1: SUB #5Fim:

Se PTA[3] = 0, então faz A = A – 5 senão, faz A = A + 3

Desvia se Z=1 Z é um bit do ccr, que fica =1 sempre que o resultado de uma operação for zero. Ex. CLRA; A = 0. Como o resultado deu zero, então Z=1

Testes

LDA var ; A = varSUB #3 ; A = A - 3BEQ Fim ; se ultimo resultado deu zero, vai pra FIMSUB #5 ; senão, A = A -5

Fim:

Testes Desvia se deu overflow (carry = 1)

Desvia se o resultado da última operação foi maior que zero

BCS Fim ; se carry =1, vai pra FIMSUB #5 ; senão, A = A -5

Fim:

BGT Fim ; se última op. deu > 0, vai pra FIMSUB #5 ; senão, A = A -5

Fim:

Testes Desvia se o resultado da última operação foi

maior ou igual a zero

Compara acumulador com número ou mem

BGE Fim ; se última op >= 0, vai pra FIMSUB #5 ; senão, A = A -5

Fim:

CBEQA $3,Fim ; se a=3, vai pra FIMSUB #5 ; senão, A = A -5

Fim:

CBEQA var,Fim ; se a=var, vai pra FIMSUB #5 ; senão, A = A -5

Fim:CBEQ = Compare and bra

nch if equal

Trabalhando com as PORTAS Em DSPs e Microcontroladores, os pinos de

entrada/saída são tratados como PORTAS. Sinais elétricos, na forma binária, são lidos e

escritos diretamente nas PORTAS.

Isso só pode ocorrer se a PORTA A for configurada como entrada.

LDA PTAD ; Acum. Recebe o valor digital da PORTA A

PORTAS Para ler um valor de uma porta, a porta deve

ser configurada como entrada. Para escrever em uma porta, ela deve ser

configurada como saída. Existe um registrador que define a direção

dos dados para cada porta. É o registrador de Direção de Dados

Ex. PTADD ; porta A Data Direction PTBDD ; porta B Data Direction e assim por diante, em todas as portas.

Portas

Exemplo de pinos ePortas em um

microcontrolador

PORTAS Por padrão, todas as portas são

consideradas entradas, no microcontrolador. Assim sendo, os pinos ficam em alta

impedância e aceitam que outros circuitos escrevam (0s ou 1s) na porta.

Isso evita que ocorra um curto-ciruito, ao inicializar o microcontrolador.

PORTAS Para definir um bit de uma porta como

entrada, o registrador de Direção de Dados daquele bit deve ser colocado em 1.

Para ser definido com saída, deve ser colocado em 0.

1 = Saída;0 = Entrada;

PORTAS Exemplos

MOV #%00000000,PTADD ; todos os bits de PTA são entradaMOV #$FF,PTBDD ; todos os bits de PTB são saídaMOV #%00001111,PTCDD ; PTC[7..4] = out e PTC[3..0] = in

1 = Saída;0 = Entrada;

PORTAS Valores das portas

Um registrador de dados armazena o valor a ser lido/escrito.

Ex.

MOV #0,PTADD ; todos os bits de PTA são entradaMOV #$FF,PTBDD ; todos os bits de PTB são saídaLDA PTAD ; A = PTASTA PTBD ; PTB = A

Data direction

Dado

Lê os sinais digitais, nos pinos do chip

Escreve os sinais digitais nos pinos do chip

Exercício Fazer um programa que fique lendo

ciclicamente um valor na porta A e armazene-o em uma variável chamada a.

Logo após, escreva na porta B o valor de a+10.

ORG RAMStartA rmb 1 ; define uma var. de 1 byte

ORG ROMStartMAIN: clra ;limpa o acumulador

MOV #$FF, PTBDD ;Porta B é saídaMOV #$00, PTADD ;Porta A é entradaSEI ;desliga interrupções

Loop: LDA PTAD ; Acum. <= Porta ASTA A ; var. A recebe AcumuladorADD #10 ; Acum. <= Acum. + 10STA PTBD ; Porta B <= AcumuladorJMP Loop ; retorna ao Loop

ORG é diretiva de compilador: coloca o código abaixona posição de memória reservada:

às variáveisao programa

Compilador é muito chato.... Cuide os espaçamentos de coluna... Senão não compila:Labels e variáveis na coluna 1.....Código tem q ser recuado....

Exercício 2 Fazer um programa que fique lendo

ciclicamente um valor na porta A e armazene-o em uma variável chamada a.

Logo após, escreva na porta B o valor de a*9-7.

Exercício 3 Ler um valor em um teclado (na porta B) e escrevê-

lo na porta A. O número de entrada fica entre 0 e 9. O esquema do teclado é o seguinte:

Considere que os pull-ups das entradasDevem estar ligados.

1 2 3

4 5 6

7 8 9

* 0 #

B0

B1

B2

B3

B4 B5 B6

Inputs

Out

puts

Exercício 4 Ler um valor em um teclado (na porta B) e escrevê-

lo na porta A. O número de entrada é composto de 2 algarismos. O esquema do teclado é o seguinte:

Considere que os pull-ups das entradasDevem estar ligados.

1 2 3

4 5 6

7 8 9

* 0 #

B0

B1

B2

B3

B4 B5 B6

Inputs

Out

puts

Conversor A/D Grandezas analógicas, do mundo real, como

Temperatura (T), Pressão (P), Corrente (I), Tensão (V), etc Devem ser todas passadas para tensão, para

serem lidas por um microcontrolador. Além disso, deve-se ter cuidado para que a

conversão fique em um intervalo que o conversor A/D trabalhe. Tipicamente, entre 0V e 5V ou 0V e 3.3V... Depende do controlador.

Conversor A/D Por exemplo: Se você quer ler uma tensão

que varia entre 0 e 400V, um divisor resistivo é suficiente, tal como apresentado abaixo. Deve-se calcular R1 e R2, de forma que a tensão

em R2 não ultrapasse 3.3V.

Conversor A/D O HCS08 possui um conversor A/D de

aproximações sucessivas, de 12 bits. O conversor tem a entrada multiplexada, ou

seja, 28 entradas podem ser ligadas no conversor A/D, mas somente 1 pode ser efetuada, cada vez.

Conversor A/D

Conversor A/D

As conversões são feitas entre os valores de referência máximo VREFH e mínimo VREFL .

O valor convertido terá uma representação linear entre 0 e 4096 (12bits) entre as referências.

Conversor A/D

Veja um exemplo, no gráfico abaixo, supondo as referencias em 0V e 3.3V:

4096

0 0V

3.3V

Vin = 1V1241

Uma tensão de 1V seria lida como o número 1241, nas escalas de referência.

Configurando o A/D Registrador de Configuração: ADCCFG

Low Power: Configuração de velocidade/potência0 : alta velocidade1: baixo consumo

Divisor do clockPre-scaler de divisão do clock.

Configurando o A/D Registrador de Configuração: ADCCFG

Long Sample Mode: Configuração de tempo de amostragem do sinal0 : amostra de tempo curta;1: amostra de tempo longa.

Modo de 8, 10 ou 12 bits00: 8 bits01: 12 bits10: 10 bits

Fonte do clock00: Barramento interno01: Barramento interno 210: Clock alternativo (ALTCLK)11: Clock assíncrono (ADACK)

Configurando o A/D Registrador de Configuração: ADCCFG

Por padrão, se não mexer neste registrador, terás: Conver~soa rápida, Clock interno Tempo de amostra curto 8 bits

Se quiser ter conversão de 12bits, faça:

MAIN: MOV #%00000100,ADCCFG

O registrador ADCSC1 controla o conversor da seguinte forma:

Conversão Completa: Bit que indica quando uma conversão terminou0: não terminou;1: Conversão terminou. Este bit é zerado quando o resultado da conversão for lido.... Daí fica pronto para outra conversão.

Configurando o Conversor A/D

Conversão Contínua: 0 : faz somente uma conversão, qdo se escrever em ADCSC1;1: faz conversões sucessivas. Termina uma e começa outra, imediatamente.

Interrupt Enable0: após conversão, não gera interrupção.1: após conversão, gera interrupção.

Configurando o Conversor A/D

Channel Select: Seleciona o canal a ser convertido, conforme tabela abaixo

E o resultado? O resultado da conversão fica em dois

registradores ADCRH, ADCRL. Como o resultado tem 12 bits, deve ser

armazenado em 2 registradores:

ADCRLADCRH

8 bits8 bits

Exemplo Ler um valor analógico no pino AD0, e

armazená-lo.ORG RAMStart

resultado rmb 2 ; define uma var. de 2 bytes

ORG ROMStartMAIN: SEI ; desliga interrupçõesLoop: MOV #%00000100,ADCCFG ; 12 bits

MOV #%00000000,ADCSC1 ; configura e começa a conv.

BRCLR 7,ADCSC1, * ;enquanto ADCSC1[7] = 0;pula pra mesma linha

LDA ADCRH ;acum <= parte altaSTA resultado ;resultado <= acumLDA ADCRL ;acum <= parte baixaSTA resultado+1 ;resultado+1 <= acumLoop ; retorna ao Loop

Canal A0

Só uma conversãoSem interrupções Espera conversão terminar... Quando terminar, bit 7 vai pra ‘1’

Exemplo 2 Ler um valor analógico na porta A0, e

armazená-lo. ORG RAMStart

resultado rmb 2 ; define uma var. de 2 bytes

ORG ROMStartMAIN: SEI ; desliga interrupções MOV #%00000100,ADCCFG ; 12 bits

MOV #%00100000,ADCSC1 ; configura e começa a conv.

Loop: BRCLR 7,ADCSC1, * ;enquanto ADCSC1[7] = 0;pula pra mesma linha

LDA ADCRH ;acum <= parte altaSTA resultado ;resultado <= acumLDA ADCRL ;acum <= parte baixaSTA resultado+1 ;resultado+1 <= acumLoop ; retorna ao Loop

Canal A0

Conversão contínua

Sem interrupçõesEspera conversão terminar...

Quando terminar, bit 7 vai pra ‘1’Com conv. Contínua, o Loop mudou pra cá!

Lê resultado e já começa

outra conversão.

Exemplo 3 Ler um valor analógico na porta A0, e

armazená-lo. Use interrupção.ORG RAMStart

resultado rmb 2 ; define uma var. de 2 bytes

ORG ROMStartMAIN: CLI ; Habilita interrupções

MOV #%00000100,ADCCFG ; 12 bitsMOV #%01100000,ADCSC1 ; configura e começa a conv.

Loop: JMP Loop ; espera gerar uma interrupção

INT_ADC:LDA ADCRH ;acum <= parte altaSTA resultado ;resultado <= acumLDA ADCRL ;acum <= parte baixaSTA resultado+1 ;resultado+1 <= acumRTI

Canal A0

Conversão contínua

Liga interrupções Com int. ligadas, qdo COCO ficar nível alto, irá gerar uma interrupção.

Exercícios: 1.Leia 2 valores analógicos, e escreva o

menor deles em uma saída digital (portas C e D – lembre que são 12bits).

2. Um sinal de tensão entre 0 e 100V foi ajustado para ser lido no A/D do microcontrolador. Leia o valor, e mostre-o em uma saída digital (porta B). O valor lido ficará entre 0 e 4096... Ajuste-o para

representar entre 0V e 100V.

top related