MIC-2013-1-CST Introdução aos Microcoprocessadores
DADOS GERAIS DA DISCIPLINA
- Professor: Eraldo Silveira e Silva (email: eraldo@ifsc.edu.br)
- Plano de Ensino 2013-1
Cronograma
AULA | DATA | Descriçao |
---|---|---|
1 | 2/4/2013 | |
2 | 9/4/2013 |
AULA 1 - Dia 22/04/2013
OBS: aula improvisada pelo fato de ter sido repassada na última sexta.
Objetivos
- apresentar os objetivos da disciplina
- trabalhar memórias na forma de diagrama em blocos
- apresentar barramentos de endereço/dados/controle
- diferenciar conteúdo de endereço de memória;
- apresentar o procedimento de acesso para escrita e para a leitura;
- apresentar um diagrama de tempo simplificado de acesso a memória;
- apresentar a CPU/microcontrolador como a "entidade" que acessa a memória
Diagrama em blocos da memória e barramentos
No diagrama abaixo está representado um bloco de memória primária de 16x8 (dezesseis endereços por 8 bits).
- Note que uma posição de memória pode ser vista como uma caixa que possue um endereço e um conteúdo.
- O conteúdo associado a posição de memória é uma palavra binária e, neste caso, possui 8 bits.
ou
Para que us dispositivo externo possa "acessar" a memória para leitura ou escrita, ele deve se utilizar de um conjunto de fios que chamamos de barramentos.
Barramento de Endereços
Este barramento permite determinar o endereço de uma posição a ser acessada na memória. Um barramento de 4 linhas de endereço é designado por A3,A2,A1 e A0.
Supondo uma memória com endereços designados da forma hexadecimal de 0h a Fh. Supondo que A3 seja associado ao bit mais significativo e A0 ao bit menos significativo. Então, para acessar a posição Bh de memória, deve-se injetar A3=1, A2=0, A1=1 e A0=1. Note que
O termo "injetar" significa aqui que um dispositivo externo deve forçar tensão nas linhas do barramento. Esta tensão depende da tecnologia utilizada. Poderia ser, por exemplo, 5V para o nível lógico 1 e 0V par ao nível lógico 0.,
Diagrama de Tempo - Acesso para escrita
AULA 2
Objetivos
- apresentar, através de um exercício, um sistema hipotético de microprocessamento;
- desenvolver a noção do que é a linguagem de máquina e do que é linguagem assembly;
Sistema de microprocessamento hipotético
Seja um sistema hipotético de processamento com os seguintes componentes:
Uma CPU contendo:
- Unidade de Controle;
- Unidade Lógica e Aritmética;
- Registradores:
- Registrador de Instrução (IR) de palavra de 6 bits: Armazena a instrução que será executada pela CPU;
- Contador de Programa (PC) de palavra de 4 bits: Armazena o endereço da próxima instrução a ser executada;
- Registrador A e Registrador B, ambos de 6 bits: Registros temporários para transferência de dados da memória e operações de lógica e aritmética.
- Barramentos:
- Barramento de Dados - 6 bits : D5, D4, D3, D2, D1, D0.
- Barramento de Endereço - 4 bits : A3, A2, A1, A0.
- Barramento de Controle:
- WR - Escrever RAM (memória de dados);
- RD - Ler RAM (memória de dados);
- PSEN - Ler ROM (memória de programa)
- Memória externa de Dados: 16 posições de 6 bits;
- Memória externa de Programa: 16 posições de 6 bits;
\section{Conjunto de Intruções do Sistema Hipotético}
\begin{table}[h] \caption{Conjunto de Intruções} \begin{tabular} {|p{1.5cm}|c|p{10cm}|l|} \hline % Código & tam & Descrição & Mnemônico\\ \hline % 00\small{XXXX} & 1 & Ler endereço \small{XXXX} da memória de dados para acumulador A. & MOV A,direto \\ 01\small{XXXX} & 1 & Escrever no endereço \small{XXXX} da memória de dados o valor do acumulador A. & MOV direto,A \\ 100000 & 1 & Somar acumulador A com registrador B e colocar resultado em A. & ADD A,B \\ 100001 & 1 & Decrementar acumulador A. & DEC A \\ 100010 & 1 & Mover o conteúdo do acumulador A para o registrador B. & MOV B,A \\ 100011 & 1 & Subtrair o valor do registrador B do acumulador A e colocar resultado em A & SUBB A,B \\ 100100 & 1 & Parar o microprocessador & HALT \\ 100101 \small{YYYYYY} & 2 & Mover o dado imediato \small{YYYYYY} (armazenado na memória de programa) para o acumulador A & MOV A,\#dado6 \\ 11\small{XXXX} & 1 & Saltar (JUMP) para o endereço \small{XXXX} da memória de programa se acumulador A for diferente de 0. & JNZ direto \\ \hline % \end{tabular} \end{table}
\section{Executando um programa}
Considere a memoria de programa com o seguinte código:
\begin{table}[h] \caption{Conteúdo da Memória de Programa} \begin{tabular} {|c|c|p{8cm}|l|} \hline % Endereço & Conteúdo & Descrição & Mnemônico\\ \hline % 0H & 000001 & Movimenta conteúdo lido da posição 0001 da memória de dados para o registrador A & MOV A,1H \\ 1H & 100010 & Move o conteúdo do registrador A para o registrador B & MOV B,A \\ 2H & 000010 & Movimenta conteúdo lido da posição 0010 da memória de dados para o registrador A & MOV A,2H \\ 3H & 100011 & Subtrair o valor do registrador B do acumulador A e colocar resultado em A. & SUBB A,B \\ 4H &110011 & Saltar (JUMP) para o endereço 0011 da memória de programa se acumulador A for diferente de 0. & JNZ 3H\\ 5H & 010000 & Escrever no endereço 0000 da memória de dados o valor do acumulador A. & MOV 0H,A\\ 6H & 100100 & Parar o microprocessador & HALT \\ \hline % \end{tabular} \end{table}
Preencha a taebela conforme a execução do programa:
\begin{table}[h] \caption{Conteúdo dos principais registros a cada passo do programa exemplo} \begin{tabular} {|c|c|c|c|c|c|c|c|c|} \hline % passo & IR & A & B & PC & RAM 0000 & RAM 0001 & RAM 0010 & RAM 0011\\ \hline % 0 & 000000 & 000000 & 000000 & 0000 & 000111 & 000001 & 000011 & 000010\\ \hline % 1&&&&&&&&\\ \hline % 2&&&&&&&&\\ \hline % 3&&&&&&&&\\ \hline % 4&&&&&&&&\\ \hline % 5&&&&&&&&\\ \hline % 6&&&&&&&&\\ \hline % 7&&&&&&&&\\ \hline % 8&&&&&&&&\\ \hline % 9&&&&&&&&\\ \hline % 10&&&&&&&&\\ \hline % 11&&&&&&&&\\ \hline % 12&&&&&&&&\\ \hline %
As condições de ``reset do sistem são as seguintes: Registros A, B, PC e IR são zerados.
A CPU executará eternamente a sequência:\textbf{ ciclo de busca} e \textbf{ciclo de execução de instrução}. O ciclo de busca consiste basicamente em: \begin{enumerate}
\item Colocar o endereço do PC no Barramento de Endereços; \item Enviar o controle de leitura $\overline{PSEN}$ para Memória de Programa; \item Ler a instrução do Barramento de Dados através da aplicação de um comando de escrita no Registrador de Instrução (IR); \item Incrementar o PC em função do número de palavras da instrução.
\end{enumerate}
O ciclo de execução é basicamente a decoficação da instrução que está no Registrador de Instrução (IR), atualizando os registros ou dados da memória, dependendo da instrução em questão.
AULA 5
Objetivos
Os alunoss deverão ser capazes de:
- enumerar as principais característcias do microcontrolador 8051;
- desenvolver pequenos programas de movimentação de dados entre registradores,memória de código, memória interna e memória externa;
Material de Aula
AULA 6 - Dia 13/05/2013
Simulador MCU8051IDE
Ver detalhes do simulador MCU8051IDE aqui.
Exercícios no simulador
- Implementar um código para copiar o bloco de memória de 40h-4Fh para 60-6Fh usando movimentação indireta. Usar R0 e R1 e também a instrução incrementa Rn (INC R0 e INC R1).
AULA 7 - Dia 14/05/2013
Instruções de Movimentação Externa de Dados
Intsruções úteis:
movx A,@dptr
movx @dptr,A
inc dptr
mov dptr,#imediato
</syntaxhighlight>
Exemplo:
Exercícios
- Colocar a mensagem "ALO" nas posições de memória externa de dados 0670h,0671h e 0672h.
- Copiar o bloco de memória externa de dados das posições 1800h-1804h para as posições de memória externa 0000h-0004h.
AULA 8 - Dia 20/05/2013
Objetivo
- Instruções de Movimentação Dados da Área de Código
- Instruções de Jump Condicional para Controlar Loops
- Exercícios
Material de Apoio
Exercício 1
Considere o código abaixo.
inicio:
loop: jmp loop
msg1:
db 'ALO IFSC'
</syntaxhighlight>
Inserir um código para ler a a cadeia 'ALO' para as posições de memória RAM interna 60h,61h e 62h.
SOLUÇÃO:
inicio:
mov dptr, #msg1
mov a,#00h
movc a,@a+dptr
mov 60h,a
mov a,#01h
movc a,@a+dptr
mov 61h,a
mov a,#02h
movc a,@a+dptr
mov 62h,a
loop: jmp loop
msg1:
db 'ALO IFSC'
</syntaxhighlight>
Exercício 2
Ainda com relação ao código original do exercício anterior. Implementar um código para copiar a cadeia IFSC para as posições de memória RAM externa de dados 1000h,1001h,1002h e 1003h.
.
inicio:
mov dptr,#msg1
mov a,#4
movc a,@a+dptr
mov dptr,#1000h
movx @dptr, a
mov dptr,#msg1
mov a,#5
movc a,@a+dptr
mov dptr,#1001h
movx @dptr, a
mov dptr,#msg1
mov a,#6
movc a,@a+dptr
mov dptr,#1002h
movx @dptr, a
mov dptr,#msg1
mov a,#7
movc a,@a+dptr
mov dptr,#1003h
movx @dptr, a
msg1: db 'ALO IFSC'
loop: jmp loop
</syntaxhighlight>
Exercício 3
Considere o código abaixo.
inicio:
loop: jmp loop
msg1:
db 'ALO IFSC',0
</syntaxhighlight>
Implementar um código para copiar toda a mensagem iniciada em msg1 para uma área de memória interna iniciada em E0h.
OBS: Use o fato de que existe um 0 marcador de final de mensagem.
Exercício 4
Implementar uma função de boot (início de sistema) que zera as posições de memória ram interna de 40 a 7f usando movimentação indireta, e de ram externa de dados 0000h a 00ffh. Use a instrução cjne para elaborar loops que realizam as tarefas repetitivas.
Exercício 5
Seja o código abaixo:
inicio:
loop: jmp loop
msg1:
db 'ALO IFSC',0
</syntaxhighlight>
Observe que a msg 1 é terminada com o byte 0. Sabendo disto, elabore um código para copiar a msg1 para a RAM externa posição inicial 0600h, usando a instrução cjne.
Exercício 6
Considere o programa:
boot:
inicio:
mov A,#55h
mov dptr,#0e00h
movx @dptr,a
fim:
jmp fim
</syntaxhighlight>
Acrescente um código de boot que copia o código a partir do label inicio para a ram externa de dados, a partir da posição 0e000h.
AULA 8 - Dia 20/05/2013
Objetivo
- uso de instrução cjne para elanborar loops
Exercício 1
Iniciar um bloco de memória RAM interna de 50h até 7fh com o valor E5h.
Solução:
.
mov A,#0E5h
mov R0,#50h
inicio:
mov @R0,A
inc R0
cjne R0,#80h,inicio
loop: jmp loop
</syntaxhighlight>
Exercício 2
Copiar um bloco de memória RAM interna de 40h-7f para 20-5F usando move indireto.
Sugestão: usar R0 e R1.
.
mov R0,#40h
mov R1,#20h
loop1:
mov A,@R0
mov @R1,A
inc R0
inc R1
cjne R0,#80h,loop1
loop: jmp loop
</syntaxhighlight>
AULA 9 - Dia 27/05/2013
Objetivo
- Instruções de movimentação de byte para as portas
- instruções de loop condicional cjne
- representação de palavras binárias em binário, hexadecimal e decimal
Exercício 1
Piscar 8 vezes o led da posição P1.0 e depois 8 vezes o LED da posição P1.7. Colocar tudo em um loop infinito.
Use cjne A,imediato, label
.
inicio:
mov A,#8
loop1:
mov P1,#0FEh
mov P1,#0FFH
dec A
cjne A,#00,loop1
mov A,#8
loop2:
mov P1,#01111111b
mov P1,#11111111b
dec A
cjne A,#00,loop2
ljmp inicio
</syntaxhighlight>
Exercício 2
Piscar 8 vezes o led da posição P1.0 e depois 8 vezes o LED da posição P1.7. Colocar tudo em um loop infinito.
Use de cjne A,direto, label
inicio:
mov 50h,#8
loop_main:
mov A,#0
loop1:
mov P1,#0FEh
mov P1,#0FFH
inc A
cjne A,50h,loop1
mov A,#0
loop2:
mov P1,#01111111b
mov P1,#11111111b
inc A
cjne A,50h,loop2
ljmp loop_main
</syntaxhighlight>
Exercício 3
Piscar 8 vezes o led da posição P1.0 e depois 8 vezes o LED da posição P1.7. Colocar tudo em um loop infinito.
Use de cjne @R0,imediato, label
inicio:
mov R0,#50h
loop_main:
mov @R0,#0
loop1:
mov P1,#0FEh
mov P1,#0FFH
inc @R0
cjne @R0,#8,loop1
mov @R0,#0
loop2:
mov P1,#01111111b
mov P1,#11111111b
inc @R0
cjne @R0,#8,loop2
ljmp loop_main
</syntaxhighlight>
AULA 10 - Dia 3/06/2013
Objetivo
- Instruções de jump condicional controladas por bit
- Instruções de set, clear bit
- Operações lógicas com bit.
- Registradores com acesso por bit e byte
Instruções de Salto Condicional a um BIT
Observe o exemplo abaixo. A instrução jb testa o estado de um bit (um pino da porta externa P2)
e salta se estiver 1. Nos códigos de pisca LED são usadas as instruções setb e clr que permitem setar
e resetar bit respectivamente.
.
inicio:
mov P2,#0FFh
loop:
jb P2.0,pisca1
jb P2.1,pisca2
sjmp loop
pisca1:
clr P1.0
setb P1.0
sjmp loop
pisca2:
clr P1.1
setb P1.1
sjmp loop
</syntaxhighlight>
EXERCÍCIOS
- Modificar o programa anterior criando um código para rotacionar bits a direita na porta P1 e para rotacionar bits a esquerda, conforme o estado das chaves.
.
inicio:
mov P2,#0FFh
loop:
jb P2.0,rotaciona_direita
sjmp rotaciona_esquerda
rotaciona_direita:
mov P1,#01111111b
mov P1,#10111111b
mov P1,#11011111b
mov P1,#11101111b
mov P1,#11110111b
mov P1,#11111011b
mov P1,#11111101b
mov P1,#11111110b
sjmp loop
rotaciona_esquerda:
mov P1,#11111110b
mov P1,#11111101b
mov P1,#11111011b
mov P1,#11110111b
mov P1,#11101111b
mov P1,#11011111b
mov P1,#10111111b
mov P1,#01111111b
sjmp loop
</syntaxhighlight>
- Acrescente no loop principal um jb para saltar para um código que pisca os LEDs de forma alternada.
- Modificar o programa exemplo substituindo as instruções de setb e clr por instruções de movimentação de byte para a porta.
O registrador PSW e o flag C
Todo microcontrolador possui um registrador que reflete o estado de alguns pontos do sistema. O 8051 possui o registrador PSW de 8 bits. Neste registrador existe um flag chamado de CARRY (C). Este flag possui várias aplicações, mas especialmente é usado para armazenar o VAI UM de operações aritméticas. Ele também pode ser usado para acumular operações lógicas a nível de bit. Por exemplo, as instruções
anl c,direto e orl c,direto (e os complementos do direto). Também existem as instruções jnc e jc que permite saltar se o CARRY estiver setado ou resetado.
Exemplo 1: uma implementação da porta E:
inicio:
mov C, P2.0
anl C, P2.1
cpl c
mov P1.0,c
sjmp inicio
</syntaxhighlight>
Exemplo 2: uma implementação da porta OU:
inicio:
mov C, P2.0
orl C, P2.1
cpl c
mov P1.0,c
sjmp inicio
</syntaxhighlight>
inicio:
mov P2,#0FFh
mov P1,#7fh
loop:
jb P2.0,pisca1
jb P2.1,pisca2
sjmp loop
pisca1:
mov A,P1
rr A
mov P1,A
sjmp loop
pisca2:
mov A,P1
rl A
mov P1,A
sjmp loop
</syntaxhighlight>
EXERCÍCIO 3
Implementar no microcontrolador uma porta lógica E com 3 entradas. Usar como entrada P2.0, P2.1 e P2.2. Usar como saída P1.0.
EXERCÍCIO 4
Implementar no microcontrolador a seguinte função lógica:
AULA 11 - Dia 4/06/2013
Objetivo
- Memória RAM com acesso por bit e por byte;
- Exercícios de operações com bits.
Memória RAM com acesso por bit
Na aula anterior vimos que alguns registradores são acessíveis por bit e por byte.
Esta facilidade permite que possamos modificar o valor de um bit de um registrador sem alterar os demais. Podemos por exemplo, armazenar bits individualmente em um registrador.
Adicionalmente, o 8051 possui uma parte da memória RAM que é acessível por bit e por byte. Ver detalhes na nota de aula abaixo.
EXERCÍCIO 1: alarme simples
PROBLEMA: Construir um alarme com 4 sensores de entrada. Se pelo menos um sensor (chave) for ativado o sistema deve disparar um alarme. Assim que os sensores forem desabilitados o alarme desliga.
ETAPA 1: Definição de quem é entrada e que é saída.
ENTRADAS: P2.0 a P2.3
SAÌDAS: P1.7 (alarme ativado = LED piscando)
ETAPA 2: Fazer um projeto simples (um fluxograma simples do sistema)
ETAPA 3: Implementação do Código e Testes
EXERCÍCIO 2: alarme simples com memorização de sensores violados
- Acrescentar saídas para representar o estado dos sensores. Se um sensor for violado um LED deve acender (de P1.0 a P1.3).
SOLUÇÃO ERALDO:
.
inicio:
mov P2,#0FFh
clr 00h
loop:
jmp trata_sensor0
pta:
jmp trata_sensor1
ptb:
jmp trata_sensor2
ptc:
jmp trata_sensor3
ptd:
jb 00h,alarme
pte:
sjmp loop
alarme:
clr P1.7
setb P1.7
clr 00h
sjmp pte
trata_sensor0:
jnb P2.0,liga_sensor0
sjmp desliga_sensor0
liga_sensor0:
clr P1.0
setb 00h
sjmp fim_sensor0
desliga_sensor0:
setb P1.0
fim_sensor0:
sjmp pta
trata_sensor1:
jnb P2.1,liga_sensor1
sjmp desliga_sensor1
liga_sensor1:
clr P1.1
setb 00h
sjmp fim_sensor1
desliga_sensor1:
setb P1.1
fim_sensor1:
sjmp ptb
trata_sensor2:
sjmp ptc
trata_sensor3:
sjmp ptd
</syntaxhighlight>
EXERCÍCIO 3
- Acrescentar saídas para representar estado de sensores. Se um sensor for violado, mesmo que volte ao normal deve registrar em uma saída (de P1.0 a P1.3).
- Acrescentar uma chave para resetar registros de violação (P3.0)
- Acrescentar uma chave para desligar alarme (P3.1)
EXERCÍCIO 4: alarme simples com inibidor de entradas
- As vezes é necessário desabilitar algum sensor. Acrescentar uma chave para desligar sensores.
Aula 12 - Dia 10/06/2013
- Uso de Pilha e Subrotina
- Exercíios
Material da Referência
Exemplo do Funcionamento da Pilha
O programa abaixo demonstra o funcionamento da pilha. Execute-o passo a passo, verificando o estado do registrador sp e da memória interna. Note que a pilha poderá ser usada como uma área de rascunho, onde se pode salvar valores que se deseja recuperar futuramtente.
.
mov A,#65H
mov B,#87H
push ACC
push B
mov A,#00H
mov B,#00H
pop B
pop ACC
loop: sjmp loop
END
</syntaxhighlight>
Exemplo de chamada de subrotina
.
inicio:
mov A,#5
lcall rotacionar_direita
mov A,#6
lcall piscar
mov A,#3
lcall rotacionar_esquerda
sjmp inicio
rotacionar_direita:
ret
piscar:
ret
rotacionar_esquerda:
ret
</syntaxhighlight>
Exercícios