Você está na página 1de 23

LINGUAGEM C PARA O 8051

Disciplina de Microcontroladores
Prof. Rubo

VARIVEIS E TIPOS DE DADOS SIMPLES


Char 8 bits
Short e int 16 bits
Long 32 bits
Float 32 bits
Unsigned int 16 bits
Unsigned long 32 bits
Obs. cuidado com as palavras reservadas ao definir funes e
variveis

ESTRUTURA DE UM PROGRAMA EM C

#include <REG52.H>

/* special function register declarations */

/* for the intended 8051 derivative

main (void)
{
int a;
}

*/

ESCOLHA DA REGIO DE
ARMAZENAMENTO DE DADOS

Regies Interna e Externa para dados


DATA Regio de RAM INTERNA DOS REGISTRADORES ESPECIAIS
IDATA Regio de RAM INTERNA ACESSADA DE FORMA INDIRETA
XDATA RAM EXTERNA
CODE Memria de programa
BIT um nico bit reservado do endereo de RAM interna de 20h a 2Fh

ESCOLHA DA REGIO DE
ARMAZENAMENTO DE DADOS

idata unsigned int var; varivel de nome var que armazenar um


dado do tipo int (2 bytes), que ter alcance de 0 a 65535.

data unsigned char var; armazenado na regio DATA


xdata unsigned char var;
code unsigned char var; memria de programa
Com espao em memria reservado
xdata at 0x8000 unsigned char var; varivel de nome var,
armazenar um dado char, na regio xdata e no endereo 8000h

ESCOLHA DA REGIO DE
ARMAZENAMENTO DE DADOS
TIPOS DE DADOS COMPOSTOS MATRIZES

Grupo de um determinado tipo de dado, que por um nome atribudo, se relaciona a


um grupo de variveis.
Exemplo: #include <REG52.H>

#include <stdio.h>
void main (void)
{
char nome_da_variavel [2];
nome_da_variavel[0] = 12;
nome_da_variavel[1] = 13;
}

OU MAIS DE UMA DIMENSO


char nome_da_variavel [5] = {12,
13, 14, 15, 16};
char display [2] = { a, B};
char display [2] [3] = { ab,
AB}; quando tiver mais de uma
varivel precisa incluir mais uma
dimenso

PRECEDNCIA ENTRE OS OPERADORES


Mantm-se o padro em linguagem C ANSI

Exemplo: int a=3+7 / 2*10;


a= 33 primeiro a diviso e truncado o valor float

CONTROLADORES DE DECISO
void main( )
{
int a=3;
if (a= =10) {a=1}
else
{a=2};
}

int a,b;
a=3;
Switch (a)
{
case 0: b=10; break;
case 1: b=20; break;
case 3: b=40; break;
default: b=0; break;
}

CONTROLADORES DE LOOPING
void main()
{
int b, a;
for (a=0; a<0xff;
a++)
P1=a;
}

ATENDIMENTO S INTERRUPES

as interrupes so vetoradas
nmero das interrupes, segundo o compilador.
0 int0 0x0003
1 timer0 0x000B
.
.
.
4 serial 0x0023
5 timer2 0x002B

ATENDIMENTO S INTERRUPES
# include <reg52.h>
# include <stdio.h>
sbit P1_0=0x90;
sbit P1_1=0x91;
void int_0( ) interrupt 0
{
P1_1= ~P1_1;
}
void main()
{
EA=1;
EX0=1;
while(1)
{
P1_0= ~P1_0;
}
}

EXPERINCIAS PRTICAS - TIMER


#include <reg52.h>
void timer (char vezes)
{ while (vezes)
{ TMOD=0x01;
TH0= ~(60000/256); //15h
TL0=~(60000%256); //9fh
TR0=1;
while(!TF0);
vezes --;
}
}

void main()
{ char vetor;
code char dados [4] = {0x01, 0x04,
0x07, 0x08};
P1=0;
while (1)
{for (vetor=0; vetor<4; vetor ++)
{P1=dados[vetor];
timer (2);//delay de 120
ms
}
}
}

EXPERINCIAS PRTICAS - LCD


#include <reg52.h>
sbit P3_5=0xB5; // Enable
sbit P3_4=0xB4; // RS
int sequencia[5]={0x38, 0x38,
0x06, 0x0E, 0x01};
void pulso (int x);
void timer0 (unsigned char
vezes);
void pulso (int x)
{
P3_5=0;
timer0(5);
P1=x;
P3_5=1;
}

void inicia_LCD()
{
int y;
P3_4=0;
// deixo o RS em zero
for(y=0; y<6; y++)
{(pulso (sequencia[y]));
P3_4=1;
// volto apenas pra
1
}}
void timer0 (unsigned char vezes)
{
TMOD=0x01;
while(vezes){
TH0=~(1000/256); //1ms
TL0=~(1000%256); //1ms
TR0=1;
while(!TF0);
vezes --; }}

USANDO O CONJUNTO KEIL/P51 EM C

muito similar do assembly, adicionando-se opes para


gerao do cdigo a partir do C. O endereo inicial de
execuo 0x2800 foi arbitrado apenas para padronizao,
podendo-se escolher outro, eventualmente.
(Essencial) No tab BL51Locate, o campo Code deve ser
preenchido com 0x2000-0x3FFF, ?PR?MAIN?*(0x2800)
garantindo que o programa seja alocado em RAM e que a
main comece em 0x2800 (facilita depurao ter um
endereo fixo pra ela).

USANDO O CONJUNTO KEIL/P51 EM C

USANDO O CONJUNTO KEIL/P51 EM C

USANDO O CONJUNTO KEIL/P51 EM C

(Essencial) Se forem usadas interrupes, no tab C51 dever estar


checado Interrupt Vector at addresses: com o campo a seguir
preenchido com 0x2000, garantindo que os vetores de interrupo
esto deslocados de 0x2000.
(Opcional) No tab Debug, Initialization File, insira um arquivo
texto debug.ini que tenha apenas uma linha: $ = 0x2800 fazendo com
que a depurao inicie automaticamente no endereo 2800h.

USANDO O CONJUNTO KEIL/P51 EM C

USANDO O CONJUNTO KEIL/P51 EM C

USANDO O CONJUNTO KEIL/P51 EM C

(Desnecessrio) Escolher corretamente o dispositivo


utilizado (se for um qualquer, o Keil no acha o include
automaticamente).
(Desnecessrio se no usar variveis xdata e code)
Em Target, setar os limites das memrias. Se for como no
circuito da placa (EPROM (Start 0 Size 0x2000) e RAM
(Start 0x2000 Size 0x2000)) d problema; deve-se
considerar toda a memria usada pelo cdigo do
programa como EPROM (ex.: Start 0 Size 0x3000) e o
restante como RAM (ex.: Start 0x3000 Size 0x1000).

USANDO O CONJUNTO KEIL/P51 EM C


Para retirar o LJMP inicial do programa em C, h duas
abordagens possveis, ambas adicionando o cdigo de startup
(crie o projeto como sempre, mas responda SIM pergunta
adicionar cdigo de startup; o arquivo Startup.a51 ser
includo no projeto e copiado para o folder atual):
Maneira 1: Altere o endereo dele. Para tanto, localize as linhas
abaixo em Startup.a51 e mude o endereo de 0000h para o
endereo inicial desejado (por exemplo, 2000h se estiver usando o
monitor com a P51).

PUBLIC ?C_STARTUP
CSEG AT
0000h ; alterar aqui!
?C_STARTUP: LJMP STARTUP1

USANDO O CONJUNTO KEIL/P51 EM C

Maneira 2: Simplesmente o retire. Localize as linhas acima,

comente as ltimas e copie o label logo a seguir:


PUBLIC ?C_STARTUP
;
CSEG AT 0000h ; alterar aqui!
;?C_STARTUP: LJMP STARTUP1
RSEG ?C_C51STARTUP
?C_STARTUP: ; adicionado!
STARTUP1:

BIBLIOGRAFIA

NICOLOSI, linguagem C para o 8051