experiência 6: linguagem de alto nível “c” para 8051 e ... - PCS - USP
experiência 6: linguagem de alto nível “c” para 8051 e ... - PCS - USP
experiência 6: linguagem de alto nível “c” para 8051 e ... - PCS - USP
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
EXPERIÊNCIA 6:<br />
LINGUAGEM DE ALTO NÍVEL “C” PARA <strong>8051</strong> E PROGRAMAÇÃO<br />
ESTRUTURADA<br />
Autores: Prof. Dr. André Riyuiti Hirakawa e Prof. Dr. Carlos Eduardo Cugnasca<br />
Colaborador: Prof. Dr. Jorge Kinoshita<br />
Versão 2.1 - 2007<br />
1. OBJETIVO<br />
Esta <strong>experiência</strong> visa exercitar a implementação <strong>de</strong> programas <strong>para</strong><br />
microprocessadores aplicando uma metodologia <strong>de</strong> <strong>de</strong>senvolvimento <strong>de</strong> programas estruturados. O<br />
ambiente <strong>de</strong> <strong>de</strong>senvolvimento a ser utilizado é o software livre Small Device C Compiler (SDCC)<br />
[01], que permitem mesclar trechos <strong>de</strong> programas escritos em Linguagem Assembly com programas<br />
escritos em Linguagem “C”.<br />
2. INTRODUÇÃO<br />
O <strong>de</strong>senvolvimento <strong>de</strong> programas em linguagens <strong>de</strong> <strong>alto</strong> <strong>nível</strong> permite maior<br />
modularização e organização das ativida<strong>de</strong>s, principalmente quando se utiliza uma <strong>linguagem</strong><br />
estruturada como a <strong>linguagem</strong> “C”. Entretanto, a <strong>linguagem</strong> por si só não inibe o <strong>de</strong>senvolvimento<br />
<strong>de</strong> programas muitas vezes confusos e <strong>de</strong> difícil interpretação. Programas <strong>de</strong>sestruturados, ou seja,<br />
que efetuam <strong>de</strong>svios condicionais ou incondicionais sucessivos, são particularmente susceptíveis a<br />
problemas, sendo <strong>de</strong> <strong>de</strong>puração <strong>de</strong>morada, além da dificulda<strong>de</strong> <strong>de</strong> alteração <strong>para</strong> a<strong>de</strong>quação a<br />
mudanças na especificação original. A utilização <strong>de</strong> metodologias e ferramentas <strong>para</strong> o<br />
<strong>de</strong>senvolvimento se torna essencial e po<strong>de</strong> <strong>de</strong>linear o sucesso ou o insucesso <strong>de</strong> um projeto.<br />
A programação estruturada se baseia em regras e convenções que <strong>de</strong>vem ser<br />
obe<strong>de</strong>cidas durante todas as fases do <strong>de</strong>senvolvimento. Elas permitem que os programas se tornem<br />
mais legíveis, modulares e mais fáceis <strong>de</strong> serem escritos, testados e modificados [4].<br />
O <strong>de</strong>senvolvimento dos algoritmos po<strong>de</strong> obe<strong>de</strong>cer à metodologia top-down, a qual<br />
prescreve um gradual <strong>de</strong>talhamento e refinamento das soluções em etapas sucessivas, partindo da<br />
especificação geral do problema até o <strong>de</strong>talhamento <strong>de</strong> cada módulo. Desta maneira, um programa é<br />
elaborado a partir <strong>de</strong> uma <strong>de</strong>finição abstrata, em termos <strong>de</strong> entida<strong>de</strong>s e operações apropriadas ao<br />
problema a ser solucionado, sendo tal <strong>de</strong>finição refinada nas etapas seguintes, até se obter o<br />
programa escrito na <strong>linguagem</strong> <strong>de</strong>sejada [6].
2 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
Na primeira etapa o programa <strong>de</strong>ve ser escrito como se existisse um computador que<br />
pu<strong>de</strong>sse enten<strong>de</strong>r as instruções utilizadas <strong>para</strong> resolver o problema em questão (esse computador<br />
hipotético é também chamado <strong>de</strong> máquina virtual). As entradas e saídas do programa são<br />
consi<strong>de</strong>radas, mas sem a preocupação com a representação dos dados, e com a construção do<br />
programa em termos <strong>de</strong> comandos <strong>de</strong> <strong>linguagem</strong> <strong>de</strong> programação, <strong>de</strong>vendo inclusive permanecer<br />
in<strong>de</strong>pen<strong>de</strong>nte <strong>de</strong> <strong>de</strong>talhes <strong>de</strong> qualquer <strong>linguagem</strong>.<br />
As etapas seguintes prevêem a divisão do programa num pequeno número <strong>de</strong><br />
módulos, cada um naturalmente <strong>de</strong> menor complexida<strong>de</strong>, mas que no conjunto representam uma<br />
solução válida, e que po<strong>de</strong> por sua vez ser reparticionada até atingir um <strong>nível</strong> <strong>de</strong> <strong>de</strong>talhamento cuja<br />
complexida<strong>de</strong> seja pequena, ou seja, on<strong>de</strong> praticamente o próximo passo natural seria escrever cada<br />
módulo na <strong>linguagem</strong> <strong>de</strong> programação escolhida. Evi<strong>de</strong>ntemente existe algum grau <strong>de</strong> subjetivida<strong>de</strong><br />
no processo que po<strong>de</strong> acarretar em alguns efeitos in<strong>de</strong>sejados. Por exemplo, uma modularização<br />
excessiva não traz tantos benefícios, pelo contrário, gera programas confusos e requer um tempo<br />
maior na sua concepção e <strong>de</strong>puração; já a adoção <strong>de</strong> poucos módulos gran<strong>de</strong>s e complexos também<br />
torna o processo <strong>de</strong> <strong>de</strong>senvolvimento e <strong>de</strong>puração mais difícil. A diminuição <strong>de</strong>ssa subjetivida<strong>de</strong><br />
naturalmente vem com o aumento da <strong>experiência</strong> no projeto e implementação <strong>de</strong> muitos programas.<br />
A representação gráfica dos algoritmos po<strong>de</strong> utilizar diversas formas, sendo as mais<br />
usuais: os Fluxogramas [4][15] e os Diagrama Estruturados, como a Carta <strong>de</strong> Nassi-<br />
Schneirdman ou Diagramas <strong>de</strong> Fluxo <strong>de</strong> Dados (DFDs) [4][7]. Po<strong>de</strong>m ser encontrados diversos<br />
programas <strong>de</strong> computador que auxiliam no <strong>de</strong>senho dos diagramas, e seu uso é recomendado [14]<br />
[15].<br />
O <strong>de</strong>senvolvimento do programa da <strong>experiência</strong> “Interface com Teclado e Display”<br />
[10], apesar <strong>de</strong> aparentemente simples, requer muitos cuidados principalmente porque os eventos<br />
envolvidos possuem limitação <strong>de</strong> tempo <strong>de</strong> execução e sincronismo entre as tarefas. Isto pô<strong>de</strong> ser<br />
confirmado com o surgimento <strong>de</strong> problemas durante a execução do programa e também pela<br />
dificulda<strong>de</strong> encontrada na solução <strong>de</strong>stes.<br />
Assim, nesta <strong>experiência</strong> será exercitado o processo <strong>de</strong> <strong>de</strong>senvolvimento <strong>de</strong><br />
programas utilizando-se as técnicas e recursos mencionados anteriormente. Será consi<strong>de</strong>rada a<br />
mesma especificação do programa <strong>de</strong>senvolvido na <strong>experiência</strong> anterior. Dentre as rotinas<br />
envolvidas no programa, a que retira o “bounce” das teclas, requer especial atenção. Existem várias<br />
formas <strong>de</strong> se elaborar essa rotina, sendo duas <strong>de</strong>las são citadas a seguir:<br />
a) Após ter sido <strong>de</strong>tectada a variação <strong>de</strong> estado em uma tecla (do 0 <strong>para</strong> o 1 ou vice-versa), <strong>de</strong>ve-se<br />
aguardar um tempo t <strong>para</strong> se consi<strong>de</strong>rar o novo estado. O valor <strong>de</strong> t <strong>de</strong>pen<strong>de</strong> do tipo <strong>de</strong> tecla,<br />
sendo da or<strong>de</strong>m <strong>de</strong> milisegundos.<br />
b) A variação <strong>de</strong> uma tecla é consi<strong>de</strong>rada pela rotina somente se o estado da tecla for o mesmo<br />
durante as últimas n leituras. Em função da alta velocida<strong>de</strong> do microcontrolador e da baixa<br />
velocida<strong>de</strong> envolvida no acionamento <strong>de</strong> um teclado, é possível intercalar um outro<br />
processamento entre duas leituras do teclado. Isso é particularmente útil quando existem outras
3 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
tarefas que <strong>de</strong>vem ser realizadas <strong>para</strong>lelamente ao tratamento do teclado. O uso <strong>de</strong> uma<br />
interrupção periódica indicando os instantes <strong>de</strong> leitura do teclado facilitaria a implementação<br />
nesse caso.<br />
3. CARACTERÍSTICAS DO COMPILADOR “C”<br />
O uso <strong>de</strong> uma <strong>linguagem</strong> <strong>de</strong> <strong>alto</strong> <strong>nível</strong> no <strong>de</strong>senvolvimento <strong>de</strong> programas <strong>para</strong><br />
microprocessadores e microcontroladores requer alguns cuidados adicionais. Mesmo se utilizando<br />
linguagens padronizadas, como a Linguagem C, não existe um padrão <strong>de</strong> como o código <strong>de</strong>ve ser<br />
gerado <strong>para</strong> cada processador. Compiladores <strong>de</strong> fabricantes diferentes que geram código <strong>para</strong> um<br />
mesmo processador não necessariamente adotam as mesmas convenções. Assim, cada compilador<br />
apresenta características próprias <strong>para</strong> a geração das instruções em <strong>linguagem</strong> <strong>de</strong> máquina, tais<br />
como passagem <strong>de</strong> parâmetros <strong>para</strong> subrotinas, retirada <strong>de</strong> valores <strong>de</strong> funções, tratamento <strong>de</strong><br />
interrupções, etc.<br />
Além disso, muitos recursos existentes em uma implementação convencional <strong>de</strong> C,<br />
utilizada em computadores, nem sempre são encontrados em implementações especificas <strong>para</strong> a<br />
geração <strong>de</strong> código <strong>para</strong> <strong>de</strong>terminados microprocessadores e microcontroladores (por exemplo, <strong>8051</strong>,<br />
8080/8085, Z80, 8086/8088, 68000, etc).<br />
Com o advento do microcomputador pessoal (por exemplo, o PC, da IBM e<br />
sucessores), surgiram compiladores C específicos <strong>para</strong> essas máquinas, com bibliotecas <strong>de</strong> rotinas<br />
<strong>de</strong> manipulação dos seus periféricos típicos (teclado, ví<strong>de</strong>o, disco, etc), e gerando o programa<br />
executável compatível com elas, e que nem sempre permitem que o mesmo possa ser utilizado <strong>para</strong><br />
a geração <strong>de</strong> programas <strong>para</strong> sistemas diferentes, baseados no mesmo processador (por exemplo,<br />
baseados no 8086/8088). Tais sistemas costumam apresentar áreas <strong>de</strong> memória especificas,<br />
diferente dos computadores pessoais, exigindo compiladores e outras ferramentas <strong>de</strong> geração <strong>de</strong><br />
programa, com capacida<strong>de</strong> <strong>de</strong> alocação <strong>de</strong> programas <strong>para</strong> qualquer região <strong>de</strong> memória escolhida<br />
pelo programador.<br />
Os manuais específicos <strong>de</strong> cada compilador <strong>de</strong>vem ser sempre consultados,<br />
observando-se as restrições existentes, os recursos <strong>de</strong> biblioteca disponíveis, os mecanismos <strong>de</strong><br />
geração <strong>de</strong> código e <strong>de</strong>mais convenções adotadas.<br />
O Apêndice I apresenta as principais características do compilador SDCC [01].<br />
Informações genéricas a respeito da <strong>linguagem</strong> C po<strong>de</strong>m ser obtidas em [4], [5], [6], e [7].
4 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
4. PARTE EXPERIMENTAL<br />
Encontra-se dispo<strong>nível</strong> no laboratório o pacote <strong>de</strong> software envolvendo o compilador<br />
C e recursos <strong>para</strong> a geração <strong>de</strong> código e <strong>de</strong>puração <strong>de</strong> programas:<br />
• o Small Device C Compiler (SDCC) [01] é um software livre (freeware) <strong>para</strong> as famílias Intel<br />
<strong>8051</strong>, Maxim 80DS390 e o Zilog MCUs Z80. Futuramente ele <strong>de</strong>verá aten<strong>de</strong>r às famílias<br />
Motorola 68HC08 Microchip PIC16 e PIC18. Maiores informações, bem como os arquivos e<br />
manuais <strong>para</strong> cópia po<strong>de</strong>m ser obtidos na página http://sdcc.sourceforge.net/.<br />
Para facilitar o aprendizado da geração <strong>de</strong> programas em <strong>linguagem</strong> C <strong>para</strong> a Placa<br />
Experimental do <strong>8051</strong> encontra-se dispo<strong>nível</strong> no Apêndice II uma estrutura-exemplo <strong>de</strong> programa,<br />
visando fornecer material inicial <strong>para</strong> ilustrar o roteiro <strong>de</strong> geração <strong>de</strong> código executável, <strong>de</strong>stacando<br />
as particularida<strong>de</strong>s <strong>de</strong> cada um dos pacotes citados. Ela é baseada no uso das rotinas <strong>de</strong> escrita no<br />
display [12], <strong>de</strong>senvolvidas na <strong>experiência</strong> correspon<strong>de</strong>nte. Tal estrutura <strong>de</strong>ve ser completada com<br />
as soluções específicas adotadas por cada grupo na escrita no display. Esse roteiro <strong>de</strong>verá ser<br />
utilizado também nas <strong>de</strong>mais <strong>experiência</strong>s.<br />
4.1 Compilação <strong>de</strong> programas<br />
a) Editar, compilar, ligar/alocar, carregar e testar um programa em C baseado na estrutura-exemplo<br />
apresentada no Apêndice II, que escreva <strong>PCS</strong>2497 no “display”. Explicar no relatório como os<br />
parâmetros das rotinas são passados e acessados (<strong>para</strong> facilitar, avalie o código gerado pelo<br />
compilador em <strong>linguagem</strong> assembly).<br />
b) Repetir o item a), substituindo a rotina “<strong>de</strong>lay ( )” por instruções em <strong>linguagem</strong> assembly, <strong>de</strong>ntro<br />
da <strong>linguagem</strong> C: consultar o manual do SDCC [01], página 39, comandos “_asm” e “_endasm”.<br />
Verificar a possibilida<strong>de</strong> <strong>de</strong> utilização <strong>de</strong> alguma opção <strong>de</strong> visualização das instruções em<br />
<strong>linguagem</strong> assembly, geradas pelo compilador. Tente substituir a rotina “<strong>de</strong>lay ()” por uma<br />
escrita em <strong>linguagem</strong> assembly em um arquivo *.asm se<strong>para</strong>do.<br />
4.2 Elaboração <strong>de</strong> rotinas básicas e programas<br />
Como forma <strong>de</strong> direcionar a familiarização com o novo ambiente <strong>de</strong><br />
<strong>de</strong>senvolvimento e facilitar futuras tarefas <strong>de</strong> <strong>de</strong>puração, rotinas úteis <strong>para</strong> teste <strong>de</strong> programas são<br />
apresentadas no Apêndice III. Algumas se encontram escritas em <strong>linguagem</strong> assembly. Sugestões<br />
em <strong>linguagem</strong> C po<strong>de</strong>m ser encontradas. Sugere-se que seja feito um bom estudo sobre o uso <strong>de</strong><br />
ponteiros em <strong>linguagem</strong> C, e como eles po<strong>de</strong>m ser implementados no SDCC (por exemplo,<br />
ponteiros po<strong>de</strong>m ser alocados na memória interna, externa, etc). Avaliar, comentar e testar cada<br />
uma <strong>de</strong>las, efetuando eventuais correções ou melhorias:<br />
a) Testar as rotinas CRLF, CO, CHEX e PRINT (duas versões) em <strong>linguagem</strong> C, observando a<br />
passagem <strong>de</strong> parâmetro (o que significa *dado ?). Estudar as formas <strong>de</strong> ponteiro da <strong>linguagem</strong><br />
C previstas no SDCC, resumindo-as no relatório.
5 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
b) Testar as rotinas CI e GETHEX, obtendo o valor lido por parâmetro <strong>de</strong> retorno. Testar o<br />
funcionamento da rotina obtendo do terminal alguma informação, que <strong>de</strong>ve ser <strong>de</strong>volvida ao<br />
terminal através das rotinas testadas no item a).<br />
c) Testar as rotinas COPY e FILL, com os parâmetros correspon<strong>de</strong>ntes.<br />
d) Utilizando as rotinas testadas, elaborar um programa que continuamente faça (loop infinito):<br />
• apresente no terminal os valores das posições <strong>de</strong> memória 0x9000 a 0x900F, solicite a<br />
digitação no terminal <strong>de</strong> um valor 0xnn <strong>para</strong> preencher as mesmas posições, e após essa<br />
operação, apresente novamente no terminal as posições com os novos valores. Exemplo:<br />
supondo que as posições apresentem os valores <strong>de</strong> 0x00 a 0x0f, e que seja digitado 0x55, as<br />
mensagens a serem apresentadas no ví<strong>de</strong>o são:<br />
• Programa <strong>de</strong> preenchimento <strong>de</strong> memoria:<br />
9000 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F<br />
Digite o valor <strong>de</strong> preenchimento (nnh):55<br />
9000 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55<br />
Digite o valor <strong>de</strong> preenchimento (nnh):<br />
...<br />
4.3 Procedimento <strong>de</strong> Projeto e Elaboração do Planejamento<br />
As rotinas e os programas <strong>de</strong>vem obrigatoriamente incorporar os seguintes itens:<br />
1. Descrição do projeto, relacionando suas características principais e as entradas e saídas.<br />
2. Especificação do programa com diagramas estruturados <strong>de</strong> todos os módulos envolvidos,<br />
que po<strong>de</strong>m ser <strong>de</strong>senhados manualmente ou com o auxílio <strong>de</strong> programas <strong>de</strong> computador.<br />
3. Detalhamento <strong>de</strong> módulos e rotinas através <strong>de</strong> diagramas estruturados. Os módulos <strong>de</strong><br />
operações <strong>de</strong>vem ser necessariamente se<strong>para</strong>dos <strong>para</strong> permitir a troca e inclusão <strong>de</strong> novas<br />
operações apenas com a troca do módulo correspon<strong>de</strong>nte.<br />
4. Implementação dos módulos e rotinas, inclusive a <strong>de</strong> testes apresentadas nos Apêndice III e<br />
IV, com a <strong>de</strong>scrição <strong>de</strong>talhada. Se necessário, faça comentário em cada linha do código.<br />
5. Integração dos módulos e rotinas e elaboração do programa principal.<br />
6. Teste do programa e avaliação dos resultados.<br />
O planejamento <strong>de</strong>ve possuir todos os itens acima, ser elaborado segundo mol<strong>de</strong>s <strong>de</strong> um projeto <strong>de</strong><br />
software apresentados em [4] (sugere-se a leitura dos capítulos 13 a 16; alguns exemplares <strong>de</strong>ste<br />
livro estão disponíveis no laboratório <strong>para</strong> consulta) e [7], e <strong>de</strong>ve possuir também um roteiro
6 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
a<strong>de</strong>quado das ativida<strong>de</strong>s a serem <strong>de</strong>senvolvidas em aula, envolvendo a seqüência <strong>de</strong> testes<br />
apropriada.<br />
4.4 Opcional<br />
a) Sugira outras rotinas que po<strong>de</strong>riam ser <strong>de</strong> interesse à <strong>de</strong>puração. Implemente-as e teste-as.<br />
Observação:<br />
As rotinas apresentadas no Apêndice III são úteis <strong>para</strong> a <strong>de</strong>puração <strong>de</strong> programas. Sugere-se<br />
fortemente que elas sejam utilizadas nas <strong>de</strong>mais <strong>experiência</strong>s.<br />
5. BIBLIOGRAFIA<br />
[1] SDCC - Small Device C Compiler, http://sdcc.sourceforge.net/ /cópias do compilador e manual<br />
disponíveis no site e em cada bancada/<br />
[2] ANDRADE, M.T.C.; Cugnasca, C.E.; HIRAKAWA, A.R.; Apostila da Experiência<br />
LINGUAGEM DE ALTO NÍVEL “C” PARA <strong>8051</strong> E GRAVAÇÃO <strong>de</strong> programas em<br />
EPROM, Disciplina <strong>PCS</strong> 597 - Laboratório <strong>de</strong> Microprocessadores I, 2001.<br />
[3] CUGNASCA, C.E.; ZERBINI, R.C.; Apostila da Experiência Desenvolvimento <strong>de</strong> Programas<br />
em Linguagem <strong>de</strong> Alto Nível “C”, Disciplina <strong>PCS</strong> 599 - Laboratório <strong>de</strong><br />
Microprocessadores, 1995.<br />
[4] LEVENTHAL, L.A. 8080A-8085 ASSEMBLY LANGUAGE PROGRAMMING. McGraw-<br />
Hill. 1986. /cópias disponíveis no laboratório/<br />
[5] KERNIGHAN, B.W.; RITCHIE, D.M.C. A Linguagem <strong>de</strong> Programação. Padrão ANSI. Rio <strong>de</strong><br />
Janeiro, Editora Campus, 1990. 289p.<br />
[6] CUGNASCA, C. E. Linguagem PL/M. Apostila FDTE, São Paulo, 1986.<br />
[7] PRESSMAN R.S. Engenharia <strong>de</strong> Software, Makron Books, 1995.<br />
[8] PHILIPS; 80C51-Based 8-Bit Microcontrollers – Data Handbook IC20, Philips Electronics<br />
North America Corporation, USA, 1997.<br />
[9] PHILIPS; Application Notes and Development Tools for 80C51 – Data Handbook, Philips<br />
Electronics North America Corporation, USA, 1997.<br />
[10] CUGNASCA, C.E.; HIRAKAWA, A.R. Apostila da Experiência Interface com Teclado e<br />
Display, Disciplina <strong>PCS</strong> 2497 - Laboratório <strong>de</strong> Processadores I, 2007.<br />
[11] MATSUNAGA, A.M.; TSUGAWA, M.O. Sistema <strong>de</strong> Pesagem Dinâmica. Projeto <strong>de</strong><br />
Formatura (disciplina <strong>PCS</strong>-588). Escola Politécnica da <strong>USP</strong>, 1997.<br />
[12] ALFACOM; Módulos Multi-Matrix – Manual <strong>de</strong> Utilização.<br />
[13] MC<strong>8051</strong> – Diagrama Lógico da Placa Experimental do <strong>8051</strong>.<br />
[14] EasyCODE(SPX). Programa <strong>para</strong> a Edição <strong>de</strong> Diagramas Estruturados da Siemens.<br />
http://www.easyco<strong>de</strong>.<strong>de</strong>/<strong>de</strong>/faq.htm<br />
[15] SFC - A Structured Flow Chart Editor. Programa <strong>para</strong> a Edição <strong>de</strong> Fluxogramas.<br />
http://www.cs.sonoma.edu/~tiawatts/SFC/
7 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
APÊNDICE I – ALGUMAS CARACTERÍSTICAS DO SMALL DEVICE C COMPILER<br />
Recomenda-se a leitura atenta do manual <strong>de</strong>sse compilador. A seguir, serão<br />
apresentadas algumas informações <strong>de</strong> interesse ao programador. Maiores informações, bem como o<br />
manual do compilador po<strong>de</strong>m ser obtidos em http://sdcc.sourceforge.net/.<br />
a) Declarações.<br />
A seguir são apresentadas algumas recomendações <strong>para</strong> seu uso.<br />
Para especificar áreas <strong>de</strong> memória utilizar at. Exemplo: <strong>de</strong>finição da variável var na posição<br />
98H da área SRF do 80C51,<br />
unsigned char far at 0x98 var;<br />
b) Uso <strong>de</strong> Linguagem Assembly <strong>de</strong>ntro da Linguagem C.<br />
Embora possível, não é recomendável, pelos efeitos colaterais que po<strong>de</strong> causar (por exemplo,<br />
alteração <strong>de</strong> valores <strong>de</strong> registradores que o compilador também utiliza).<br />
_asm<br />
<br />
_endasm;<br />
Observação: o ; da última instrução não po<strong>de</strong> ser esquecido, bem como o símbolo _.<br />
c) Chamada do Compilador.<br />
Utilizar o comando SDCC em uma janela DOS, colocando-se as informações <strong>de</strong> alocação na<br />
mesma linha. Exemplo: compilação do programa progr.c, alocando a área <strong>de</strong> código em<br />
A000H e a área <strong>de</strong> dados em 8000H.<br />
c:>sdcc –-co<strong>de</strong>-loc 0xA000 --xram-loc 0x8000 progr.c<br />
d) Passagem <strong>de</strong> Parâmetros em Subrotinas.<br />
seguintes registradores:<br />
O primeiro parâmetro, <strong>de</strong> acordo com o seu tamanho (em bytes) é passado pelos<br />
- 1 o . byte: DPL<br />
- 2 o . byte: DPH<br />
- 3 o . byte: B<br />
- 4 o . byte: A<br />
Do segundo em diante, caso a subrotina seja não reentrante, os parâmetros são<br />
passados pela memória; em caso <strong>de</strong> subrotinas reeentrates, pela pilha (<strong>para</strong> maiores <strong>de</strong>talhes,<br />
consultar documentação do SDCC).
8 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
e) Declaração <strong>de</strong> uma Função Escrita em Linguagem Assembly Presente em um Arquivo<br />
Externo.<br />
Exemplo: rotina no arquivo rot.asm:<br />
extern tipo_retorno nome_função (tipo_<strong>para</strong>metro1, tipo_<strong>para</strong>metro2, ...);<br />
Os nomes dos parâmetros não <strong>de</strong>vem ser passados.<br />
Deve ser <strong>de</strong>clarado que a rotina é <strong>de</strong> uso global e que o código é relocável. Exemplo:<br />
.globl _<strong>de</strong>lay<br />
.área CSEG<br />
_<strong>de</strong>lay: ...<br />
RET<br />
Observação: não se utiliza a pseudo-instrução END.<br />
Deve-se primeiramente chamar o montador <strong>para</strong> gerar o código da função, e <strong>de</strong>pois o compilador<br />
<strong>para</strong> gerar o código do programa que invoca a função e ligá-lo com o código <strong>de</strong>ste. Exemplo:<br />
c:>asx<strong>8051</strong> –losg rot.asm<br />
gera o arquivo rot.rel<br />
c:>sdcc –-co<strong>de</strong>-loc 0xA000 --xram-loc 0x8000 progr.c rot.rel<br />
• a opção –-co<strong>de</strong>-loc 0xA000 aloca o código a partir do en<strong>de</strong>reço A000H.<br />
• a opção --xram-loc 0x8000 aloca a área <strong>de</strong> variáveis externas a partir do en<strong>de</strong>reço<br />
8000H.<br />
• além do rot.rel outros arquivos relocáveis escritos na <strong>linguagem</strong> assembly/C que já<br />
foram montados/compilados po<strong>de</strong>riam ser acrescentados (inclusive bibliotecas prontas ou<br />
criadas pelo usuário); ele será ligado ao programa progr.c que está sendo compilado<br />
através <strong>de</strong>ste comando, e o resultado será alocado, gerando o programa absoluto<br />
progr.ihx no formato hexa<strong>de</strong>cimal Intel (a ser transferido <strong>para</strong> aplaca experimental);<br />
outros arquivos .rel po<strong>de</strong>riam ser colocados neste comando, sendo que o primeiro da<br />
lista (no caso progr.c <strong>de</strong>ve necessariamente conter o main).
9 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
APÊNDICE II - ESTRUTURA-EXEMPLO EM LINGUAGEM C<br />
Editar o programa abaixo no modo texto sem formatação (por exemplo, Bloco <strong>de</strong><br />
Notas do Windows). Após o último símbolo da última linha digitar ENTER.<br />
/************************************************************************<br />
* <strong>PCS</strong>-2497 PROGRAMA EM C SDCC *<br />
************************************************************************<br />
* Este programa <strong>de</strong>ve mostrar a mensagem "<strong>PCS</strong>2497" no display. *<br />
************************************************************************/<br />
#<strong>de</strong>fine WDATA 0x2010 /* Posicao <strong>de</strong> escrita <strong>de</strong> dados no display */<br />
#<strong>de</strong>fine RDATA 0x2030 /* Posicao <strong>de</strong> leitura <strong>de</strong> dados do display */<br />
#<strong>de</strong>fine WCOMMAND 0x2000 /* Posicao <strong>de</strong> escrita <strong>de</strong> comandos no display */<br />
#<strong>de</strong>fine RSTATUS 0x2020 /* Posicao <strong>de</strong> leitura <strong>de</strong> estado do display */<br />
unsigned char far at @WDATA wdata;<br />
unsigned char far at @RDATA rdata;<br />
unsigned char far at @WCOMMAND wcommand;<br />
unsigned char far at @RSTATUS rstatus;<br />
/* Rotina <strong>de</strong> espera <strong>de</strong> tempo */<br />
void <strong>de</strong>lay (int tempo) {<br />
int i,j;<br />
for (i=tempo;i>0;i--) {<br />
for (j=50;j>0;j--) {<br />
};<br />
};<br />
}<br />
/* Rotina que envia comandos ao display */<br />
void displaycommand (int cmd) {<br />
<strong>de</strong>lay (2);<br />
wcommand = cmd;<br />
}<br />
/* Rotina que envia um caractere ao display */<br />
void displaydata (int car){<br />
/* Testa Busy Flag antes <strong>de</strong> escrever */<br />
_asm<br />
BUSY: MOV DPTR,#_rstatus<br />
MOVX A,@DPTR<br />
ANL A,#0x80<br />
JNZ BUSY<br />
_endasm;<br />
}<br />
wdata = car;<br />
/* Rotina que programa o display */<br />
void progrdisplay (void){<br />
displaycommand (0x38); /* 2 linhas 5x7 */<br />
displaycommand (0x0C); /* sem cursor */<br />
displaycommand (0x06); /* escreve <strong>de</strong>slocando <strong>para</strong> a direita */<br />
}
10 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
/* Rotina que limpa o display */<br />
void cleardisplay (void) {<br />
displaycommand (0x01);<br />
}<br />
/* Rotina que seleciona a linha do display que será escrita */<br />
void line (int lin) { /* seleciona a linha do display */<br />
if (lin==1) displaycommand (0x80); /* <strong>de</strong>sloca cursor 1a.lin e 1a.col */<br />
else displaycommand (0xC0); /* <strong>de</strong>sloca cursor 2a.lin e 1a.col */<br />
}<br />
/* Inicio do programa */<br />
main()<br />
{<br />
progrdisplay(); /* programa display */<br />
line(1); /* seleciona linha 1 do display */<br />
cleardisplay(); /* limpa display */<br />
/* envia <strong>PCS</strong>2497 ao display */<br />
displaydata (0x50);<br />
displaydata (0x43);<br />
displaydata (0x53);<br />
displaydata (0x32);<br />
displaydata (0x34);<br />
displaydata (0x39);<br />
displaydata (0x37);<br />
while (1) {}; /* loop infinito */<br />
}
11 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
APÊNDICE III – ROTINAS-EXEMPLO PARA UTILIZAÇÃO EM TESTES<br />
1) Rotina <strong>para</strong> envio <strong>de</strong> um caractere ao terminal <strong>de</strong> vi<strong>de</strong>o:<br />
Sugestão em <strong>linguagem</strong> assembly:<br />
; Rotina <strong>para</strong> envio <strong>de</strong> caractere ao terminal<br />
; Parametros:<br />
; entrada: o valor do Reg. B e' enviado ao terminal através do canal serial<br />
;<br />
CO: JNB TI,$ ; verifica o estado <strong>de</strong> transmissão do canal serial<br />
; caso seja=0 (canal ocupado) pula <strong>para</strong> ele mesmo<br />
CLR TI ; indica que o canal <strong>de</strong> transmissão esta´ ocupado<br />
MOV SBUF,B ; envia caractere<br />
JNB TI,$ ; espera o envio<br />
RET ;<br />
Sugestão em <strong>linguagem</strong> C:<br />
/* Rotina <strong>para</strong> envio <strong>de</strong> caractere ao terminal */<br />
void CO (unsigned char dado){<br />
while (TI==0){}; /* ou while (!TI){} */<br />
TI=0;<br />
SBUF=dado;<br />
while (TI==0){}; /* ou while (!TI){} */<br />
}<br />
2) Rotina <strong>para</strong> voltar <strong>para</strong> a 1a. coluna do terminal <strong>de</strong> ví<strong>de</strong>o, e pular linha:<br />
Sugestão em <strong>linguagem</strong> C:<br />
/* Rotina <strong>para</strong> voltar <strong>para</strong> a 1 a . coluna do terminal <strong>de</strong> vi<strong>de</strong>o e pular uma linha*/<br />
void CRLF(){<br />
CO (0x0D);<br />
CO (0x0A);<br />
}<br />
3) Rotina <strong>para</strong> imprimir um string ASCII no terminal. Fim <strong>de</strong> string 0x00:<br />
Sugestão em <strong>linguagem</strong> assembly:<br />
; Rotina <strong>para</strong> impressao <strong>de</strong> mensagem no terminal <strong>de</strong> vi<strong>de</strong>o<br />
; Parametros:<br />
; entrada: DPTR – aponta <strong>para</strong> o 1o. dado a ser enviado ao terminal <strong>de</strong> vi<strong>de</strong>o<br />
: a sequencia <strong>de</strong>ve ser terminada em 0x00<br />
;<br />
PRINT: MOV A,#00H ;<br />
MOVC A,@A+DPTR ;<br />
JZ PFIM ;<br />
MOV B,A ;<br />
ACALL CO ;<br />
INC DPTR ;<br />
SJMP PRINT ;<br />
PFIM: RET ;<br />
1a. Sugestão em <strong>linguagem</strong> C:<br />
/* Rotina <strong>para</strong> imprimir um string ASCII no terminal. Fim <strong>de</strong> string 0x00 */<br />
/* Parâmetro: en<strong>de</strong>reco inicial do conjunto <strong>de</strong> caracteres */<br />
void PRINT(unsigned char *dado){<br />
while ((*dado)!=0x00{<br />
CO (*dado);<br />
dado=dado++;<br />
}
12 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
2a. Sugestão em <strong>linguagem</strong> C:<br />
/* Rotina <strong>para</strong> imprimir um string ASCII no terminal. Fim <strong>de</strong> string 0x00 */<br />
/* Parâmetro: en<strong>de</strong>reco inicial do conjunto <strong>de</strong> caracteres */<br />
/* xdata unsigned char: o dado e´ armazenado na RAM externa */<br />
/* *xdata pont: o ponteiro <strong>para</strong> os dados e´ armazenado na RAM externa */<br />
void PRINT(xdata unsigned char *xdata pont){<br />
dado=*pont;<br />
unsigned char dado;<br />
while (dado!=0x00){<br />
dado=*pont;<br />
CO (dado);<br />
pont=pont+1);<br />
}<br />
}<br />
4) Rotina que recebe um caractere ASCII do terminal <strong>de</strong> ví<strong>de</strong>o:<br />
Sugestão em <strong>linguagem</strong> assembly:<br />
; Rotina <strong>para</strong> recebe um caractere ASCII do terminal <strong>de</strong> vi<strong>de</strong>o<br />
; Parametros:<br />
; saida: registrador A - valor do caractere<br />
;<br />
CI: JNB RI,$ ; verifica se o canal serial possui um dado<br />
; caso seja=0 (sem dados) pula <strong>para</strong> ele mesmo<br />
CLR RI ; indica que o dado foi lido<br />
MOV A,SBUF ; le dado<br />
RET ;<br />
Sugestão em <strong>linguagem</strong> C:<br />
/* Rotina <strong>para</strong> recebe um caractere ASCII do terminal <strong>de</strong> vi<strong>de</strong>o */<br />
char CI (void){<br />
while (RI==0){}; /* ou while (!RI){} */<br />
RI=0;<br />
return SBUF;<br />
}<br />
5) Rotina que envia um byte hexa<strong>de</strong>cimal ao terminal <strong>de</strong> ví<strong>de</strong>o – [0xAB] ASCII (A) ASCII (B):<br />
Sugestão em <strong>linguagem</strong> C:<br />
/* Rotina que envia um caractere ASCII do terminal <strong>de</strong> vi<strong>de</strong>o */<br />
void CHEX (unsigned char dado){<br />
unsigned char aux;<br />
aux=dado/0x10; /* <strong>de</strong>sloca 4 bits <strong>para</strong> a direita - dado AB: pega 0x0A */<br />
if (aux
13 Laboratório <strong>de</strong> Processadores-I - Experiência 6<br />
6) Rotina que recebe um byte hexa<strong>de</strong>cimal ao terminal <strong>de</strong> ví<strong>de</strong>o – ASCII (A) ASCII (B) [0xAB]:<br />
Sugestão em <strong>linguagem</strong> C:<br />
/* Rotina que recebe um caractere ASCII ao terminal <strong>de</strong> vi<strong>de</strong>o */<br />
unsigned char GETHEX (){<br />
int i;<br />
unsigned char dado;<br />
unsigned char vetordados[2];<br />
for (i=0;i