LINGUAGEM C PARA O 8051 Disciplina de Microcontroladores Prof. Rubão
VARIÁVEIS 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 funções e variáveis
ESTRUTURA DE UM PROGRAMA EM C #include <REG52.H> /* special function register declarations */ main (void) { int a; /* for the intended 8051 derivative */
ESCOLHA DA REGIÃO DE ARMAZENAMENTO DE DADOS Regiões Interna e Externa para dados DATA Região de RAM INTERNA DOS REGISTRADORES ESPECIAIS IDATA Região de RAM INTERNA ACESSADA DE FORMA INDIRETA XDATA RAM EXTERNA CODE Memória de programa BIT um único bit reservado do endereço de RAM interna de 20h a 2Fh
ESCOLHA DA REGIÃO DE ARMAZENAMENTO DE DADOS idata unsigned int var; variável 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 região DATA xdata unsigned char var; code unsigned char var; memória de programa Com espaço em memória reservado xdata at 0x8000 unsigned char var; variável de nome var, armazenará um dado char, na região xdata e no endereço 8000h
ESCOLHA DA REGIÃO DE ARMAZENAMENTO DE DADOS TIPOS DE DADOS COMPOSTOS MATRIZES Grupo de um determinado tipo de dado, que por um nome atribuído, se relaciona a um grupo de variáveis. 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 DIMENSÃO 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 variável precisa incluir mais uma dimensão
PRECEDÊNCIA ENTRE OS OPERADORES Mantém-se o padrão em linguagem C ANSI Exemplo: int a=3+7 / 2*10; a= 33 primeiro a divisão e truncado o valor float
CONTROLADORES DE DECISÃO 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 INTERRUPÇÕES as interrupções são vetoradas número das interrupções, segundo o compilador. 0 int0 0x0003 1 timer0 0x000B... 4 serial 0x0023 5 timer2 0x002B
ATENDIMENTO ÀS INTERRUPÇÕES # 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;
EXPERIÊNCIAS PRÁTICAS - 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; ms 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
EXPERIÊNCIAS PRÁTICAS - 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; for(y=0; y<6; y++) 1 // deixo o RS em zero {(pulso (sequencia[y])); P3_4=1; void timer0 (unsigned char vezes) { TMOD=0x01; while(vezes){ TH0=~(1000/256); //1ms TL0=~(1000%256); //1ms TR0=1; while(!tf0); vezes --; // volto apenas pra
USANDO O CONJUNTO KEIL/P51 EM C É muito similar à do assembly, adicionando-se opções para geração do código a partir do C. O endereço inicial de execução 0x2800 foi arbitrado apenas para padronização, 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 depuração ter um endereço 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 interrupções, no tab C51 deverá estar checado Interrupt Vector at addresses: com o campo a seguir preenchido com 0x2000, garantindo que os vetores de interrupção estão 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 depuração inicie automaticamente no endereço 2800h.
USANDO O CONJUNTO KEIL/P51 EM C
USANDO O CONJUNTO KEIL/P51 EM C
USANDO O CONJUNTO KEIL/P51 EM C (Desnecessário) Escolher corretamente o dispositivo utilizado (se for um qualquer, o Keil não acha o include automaticamente). (Desnecessário se não usar variáveis xdata e code) Em Target, setar os limites das memórias. 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 memória usada pelo código 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 possíveis, ambas adicionando o código de startup (crie o projeto como sempre, mas responda SIM à pergunta adicionar código de startup ; o arquivo Startup.a51 será incluído no projeto e copiado para o folder atual): Maneira 1: Altere o endereço dele. Para tanto, localize as linhas abaixo em Startup.a51 e mude o endereço de 0000h para o endereço 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