Apostila Linguagem C Para PIC

download Apostila Linguagem C Para PIC

of 122

Transcript of Apostila Linguagem C Para PIC

Curso de Linguagem C

Rinaldo Cmara Gonalves Labtools Mosaico Didactic Division Reviso 2

SumrioSUMRIO .....................................................................................................................................................................3 RECURSOS BSICOS: EXEMPLO 1 BOTO E LED ............................................................................................5 RECURSOS DO LIVRO ..................................................................................................................................................5 LGICA DO EXEMPLO ...................................................................................................................................................5 ESQUEMA ELTRICO....................................................................................................................................................6 FLUXOGRAMA ..............................................................................................................................................................7 CDIGO ......................................................................................................................................................................8 EXERCCIOS PROPOSTOS ..........................................................................................................................................10 ANOTAES ..............................................................................................................................................................11 RECURSOS BSICOS: EXEMPLO 2 PISCA PISCA VARIVEL .....................................................................13 RECURSOS DO LIVRO ................................................................................................................................................13 LGICA DO EXEMPLO .................................................................................................................................................13 ESQUEMA ELTRICO..................................................................................................................................................14 FLUXOGRAMA ............................................................................................................................................................15 CDIGO ....................................................................................................................................................................16 EXERCCIOS PROPOSTOS ..........................................................................................................................................18 ANOTAES ..............................................................................................................................................................19 RECURSOS BSICOS: EXEMPLO 3 CONTADOR HEXADECIMAL ..................................................................20 RECURSOS DO LIVRO ................................................................................................................................................20 LGICA DO EXEMPLO .................................................................................................................................................20 ESQUEMA ELTRICO..................................................................................................................................................21 FLUXOGRAMA ............................................................................................................................................................22 CDIGO ....................................................................................................................................................................25 EXERCCIOS PROPOSTOS ..........................................................................................................................................28 ANOTAES ..............................................................................................................................................................29 RECURSOS AVANADOS: EXEMPLO 4 MAXIMIZAO DE PINOS DE I/O...................................................30 RECURSOS DO LIVRO ................................................................................................................................................30 LGICA DO EXEMPLO .................................................................................................................................................30 ESQUEMA ELTRICO..................................................................................................................................................31 FLUXOGRAMA ............................................................................................................................................................32 CDIGO ....................................................................................................................................................................36 EXERCCIOS PROPOSTOS ..........................................................................................................................................40 ANOTAES ..............................................................................................................................................................41 RECURSOS AVANADOS: EXEMPLO 5 VARREDURA DE DISPLAY .............................................................42 RECURSOS DO LIVRO ................................................................................................................................................42 LGICA DO EXEMPLO .................................................................................................................................................42 ESQUEMA ELTRICO..................................................................................................................................................44 FLUXOGRAMA ............................................................................................................................................................45 CDIGO ....................................................................................................................................................................50 EXERCCIOS PROPOSTOS ..........................................................................................................................................57 ANOTAES ..............................................................................................................................................................58 RECURSOS AVANADOS: EXEMPLO 6 CONTROLE DO LCD ............................................................................59 RECURSOS DO LIVRO ................................................................................................................................................59 LGICA DO EXEMPLO .................................................................................................................................................59 ESQUEMA ELTRICO..................................................................................................................................................60 FLUXOGRAMA ............................................................................................................................................................61 CDIGO ....................................................................................................................................................................68 EXERCCIOS PROPOSTOS ..........................................................................................................................................76 ANOTAES ..............................................................................................................................................................77 RECURSOS AVANADOS: EXEMPLO 7 CONVERSOR ANALGICO DIGITAL..............................................78 RECURSOS DO LIVRO ................................................................................................................................................78 LGICA DO EXEMPLO .................................................................................................................................................78 Linguagem C para PIC 3

ESQUEMA ELTRICO..................................................................................................................................................79 FLUXOGRAMA ............................................................................................................................................................80 CDIGO ....................................................................................................................................................................82 EXERCCIOS PROPOSTOS ..........................................................................................................................................86 ANOTAES ..............................................................................................................................................................87 RECURSOS AVANADOS: EXEMPLO 8 CONTROLE DO PWM E EEPROM INTERNA ..................................88 RECURSOS DO LIVRO ................................................................................................................................................88 LGICA DO EXEMPLO .................................................................................................................................................88 ESQUEMA ELTRICO..................................................................................................................................................89 FLUXOGRAMA ............................................................................................................................................................90 CDIGO ....................................................................................................................................................................93 EXERCCIOS PROPOSTOS ..........................................................................................................................................99 ANOTAES ............................................................................................................................................................100 RECURSOS AVANADOS: EXEMPLO 9 COLETOR DE DADOS ....................................................................101 RECURSOS DO LIVRO ..............................................................................................................................................101 LGICA DO EXEMPLO ...............................................................................................................................................101 ESQUEMA ELTRICO................................................................................................................................................102 FLUXOGRAMA ..........................................................................................................................................................103 CDIGO ..................................................................................................................................................................109 EXERCCIOS PROPOSTOS ........................................................................................................................................114 ANOTAES ............................................................................................................................................................115 RECURSOS AVANADOS: EXEMPLO 10 FUNES MATEMTICAS..............................................................116 RECURSOS DO LIVRO ..............................................................................................................................................116 LGICA DO EXEMPLO ...............................................................................................................................................116 ESQUEMA ELTRICO................................................................................................................................................117 FLUXOGRAMA ..........................................................................................................................................................118 CDIGO .................................................................................................................................................................119 EXERCCIOS PROPOSTOS ........................................................................................................................................121 ANOTAES ............................................................................................................................................................122

4

Linguagem C para PIC

Recursos Bsicos: Exemplo 11.1 - Recursos do Livro

Boto e Led

Para o bom entendimento deste nosso primeiro exemplo so necessrios os conhecimentos de programao em linguagem C, comandos de controle de Fluxo (cap.7 do livro Programao em C), declarao de variveis, constantes e tipos de dados (cap.5 do livro Programao em C), diretivas de configurao dos pinos de I/O (cap.10-pg.170, cap.11.5; 11.6-pg.202; 11.7 e cap.12.2-pg. 250 do livro Programao em C).

1.2 - Lgica do exemploNosso exemplo ser composto de um programa capaz de ler um boto e controlar um led. Com o boto S1 pressionado o led L2 acende, com o boto S1 liberado o led L2 apaga. Veremos os primeiros comandos para controle de fluxo de um programa e como ler uma entrada e acionar uma sada, fundamental j que estamos trabalhando com um microcontrolador. Neste exemplo voc ver o comando WHILE, (Faa enquanto for verdadeiro) sendo utilizado para o controle de fluxo de nossa rotina principal, forando um loop infinito. O comando IF ELSE, (Se verdadeiro {comando}, Se falso {comando}), realiza o teste do boto e determina o caminho a ser seguido, se acende ou apaga o led. Caso o boto esteja pressionado o teste determina que o led deve acender, caso contrrio o led ser apagado. Para o teste do boto est sendo utilizado o operando ! (NOT), para boto pressionado temos nvel lgico zero no pino de I/O, neste caso o teste com o comando IF ser verdadeiro para boto pressionado e falso para boto liberado.

Linguagem C para PIC

5

1.3 - Esquema Eltrico

+5V

RESET 10K1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 23 24

MC1MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC632 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25

+5V

+5V

RB010K

RB1

330R

+5V

S1

L2

4MHz

16F877A

6

Linguagem C para PIC

1.4 - Fluxograma

MAIN

CONFIGURAES INICIAIS TRIS, PORTAS, WATCHDOG, PRESCALER.

A LIMPA WATCHDOG

NO

BOTO S1 PRESS.?

SIM

APAGA LED L2

ACENDE LED L2

A

Linguagem C para PIC

7

1.5 - Cdigo/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * * Exemplo 1 * * * * CENTRO DE CAPACITAO - LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: [email protected] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * Este software est preparado para demonstrar o controle este primeiro programa demonstrar o estado de um boto * * * * * * * * * * * * * * * * */ dos pinos de I/O por meio de um led.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio das variveis internas do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include // microcontrolador utilizado

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt fusveis // configurao dos

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. //Este programa no utiliza nenhuma varivel de usurio /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. //Este programa no utiliza nenhuma constante de usurio /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. //Este programa no utiliza nenhum flag de usurio /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use #use #use #use #use #byte #byte #byte #byte #byte fast_io(a) fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09

8

Linguagem C para PIC

/* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit

* * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. // Estado do boto // 1 -> Liberado // 0 -> Pressionado

* * */ e

botao = portb.0

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // As sadas devem ser associadas a nomes para facilitar a programao //futuras alteraes do Hardware. #bit led = portb.1 // Led correspondente ao boto // 1 -> Led ligado // 0 -> Led desligado

* * */ e

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { setup_counters(RTCC_INTERNAL, WDT_2304MS); set_tris_a(0b11111111); set_tris_b(0b11111101); set_tris_c(0b11111111); set_tris_d(0b11111111); set_tris_e(0b00000111); porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00; // // // // // // configurao dos pinos de I/O

limpa limpa limpa limpa limpa

porta portb portc portd porte

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { RESTART_WDT(); if(!botao) { led = 1; } else led=0; } }

// testa boto // Se boto = 0, ento led = 1 // caso contrrio, led = 0 // FIM DO PROGRAMA

1.6 -

Linguagem C para PIC

9

1.7 - Exerccios PropostosAgora que o exemplo j foi estudado e esclarecido, aproveite para gerar novos problemas e solues, seguindo os exerccios propostos: 1. Utilize as funes do Compilador para controlar o Led, OUTPUT_HIGH e OUTPUT_LOW. 2. Altere a lgica do programa para que o led acenda com o boto liberado e apague com o boto pressionado. 3. Troque o pino de I/O que controla o boto, por exemplo, utilize o pino RB3. 4. Com o boto pressionado acenda o led 2 e apague o led 3, para o boto liberado apague o led 2 e acenda o led 3.

10 Linguagem C para PIC

1.8 - Anotaes

Linguagem C para PIC

11

Recursos Bsicos: Exemplo 21.9 - Recursos do Livro

Pisca Pisca Varivel

Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos no exemplo 1 e mais, funes do compilador para controle de atraso (cap.11.4 pg. 195 do livro Programao em C), Operadores para criao de expresses lgicas e aritmticas (cap.6 do livro Programao em C), diretivas de configurao para uso de funo de atraso (cap.10, pg.169 do livro Programao em C).

1.10 - Lgica do exemploA finalidade de nosso exemplo demonstrar a inverso de portas e a utilizao da funo de delay da Linguagem C. Atravs dos botes S1 e S2, Up e Down possvel ajustar a freqncia de oscilao dos Leds 3 e 4 da placa McLab2. As constantes min e max determinam os limites, mximos e mnimos de ajuste da freqncia de oscilao. Para a inverso das portas est sendo utilizado o operador lgico ~, (NOT, complemento de 1), com este operando estaremos invertendo bit a bit o contedo do registrador portb. A funo delay_ms gera um atraso de milisegundos usando o ciclo de mquina, ou seja, o programa fica travado nesta funo at o tempo desejado. O camando For (inicializao, teste condicional, incremento) utilizado para controle do lao da rotina de delay, definindo a quantidades de vezes que o lao ser executado, nesta rotina no utilizaremos a opo de inicializao do comando For, sendo a mesma executada fora do lao.

Linguagem C para PIC

13

1.11 - Esquema Eltrico

+5V

RESET 10K1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 23 24

MC1MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC632 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25

+5V

+5V

4MHz

16F877A

+5V

+5V

10K

10K

RB0 S1

RB1 S2

RB2330R

RB3330R

L3

L4

14 Linguagem C para PIC

1.12 - FluxogramaA MAIN

CONFIGURAES INICIAIS TRIS, PORTAS, WATCHDOG, PRESCALER.

NO

BOTO S1 PRESS.?

SIM

INICIALIZA PORTB COM 0X0F B LIMPA WATCHDOG

SIM

TEMPO = MAX?

NO

INCREMENTA TEMPO COMPLEMENTA PORTB

A NO BOTO S2 PRESS.? SIM

SIM

TEMPO = MIN?

NO

DECREMENTA TEMPO

CARREGA A VARIVEL CONTADOR COM O VALOR DA VARIVEL TEMPO

ROTINA DE DELAY LAO FOR

B

NO

CONTADOR 0

SIM DELAY (10MS)

Linguagem C para PIC

15

1.13 - Cdigo/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * * Exemplo 2 * * * * CENTRO DE CAPACITAO - LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: [email protected] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Este software demonstrar a utilizao da funo de delay e //a frequncia de oscilao dos leds controlada pelos botes * * * * * * * * * * * * */ a inverso de portas S1 (UP) e S2 (DOWN).

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio das variveis internas do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt // configurao dos fusveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT) // diretiva para o uso da funo delay /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int contador = 0 ; int tempo = 9; /* * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * //A definio de constantes facilita a programao //Este programa no utiliza constantes #define max 255 // Limite de ajuste do #define min 10 * * * * * * * * * * * * * * * * * * * * * * * * */ e a manuteno. tempo

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. //Este programa no utiliza nenhum flag de usurio. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte porta portb portc portd = = = = 0x05 0x06 0x07 0x08

16 Linguagem C para PIC

#byte porte = 0x09 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit botao_0 #bit botao_1

* * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. = portb.0 // Estado do boto_0 // 1 -> Liberado // 0 -> Pressionado = portb.1 // Estado do boto_1 // 1 -> Liberado // 0 -> Pressionado

* * */ e

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // As sadas devem ser associadas a nomes para facilitar a programao //futuras alteraes do hardware.

* * */ e

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { setup_counters(rtcc_internal,wdt_2304ms); set_tris_a(0b11111111); set_tris_b(0b11110011); set_tris_c(0b11111111); set_tris_d(0b11111111); set_tris_e(0b00000111); porta portb portc portd porte = = = = = 0x00; 0x0f; 0x00; 0x00; 0x00; // carrega portb com valor inicial

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { RESTART_WDT(); portb = ~portb; if (!botao_0) // { if (tempo != max) // { tempo = tempo + 1; // } } // // complemanta o portb O boto_0 foi pressionado? sim, tempo diferente de max? no, incrementa tempo boto_0 liberado, testa boto 1

if (!botao_1) // O boto 1 foi pressionado ? { if (tempo != min) // sim, tempo diferente de min? { tempo = tempo - 1; // no, decrementa tempo } } // boto_1 liberado contador = tempo; // carrega contador for (;contador!=0; contador--) // contador diferente de 0? se sim // decrementa contador e executa o comando delay_ms(10); // comando: delay de 10 milisegundos. } } // FIM DO PROGRAMA

Linguagem C para PIC

17

1.14 - Exerccios PropostosAgora que o exemplo j foi estudado e esclarecido, aproveite para gerar novos problemas e solues, seguindo os exerccios propostos: 1. Implemente a inverso de portas para que o led 3 e o led 4 pisquem alternadamente. 2. Utilize a forma reduzida para incrementar e decrementar a varivel tempo. 3. Troque a funo delay_ms por delay_us e ajuste as constantes para obter o mesmo ajuste de freqncia. 4. Substitua o comando For pelo comando While.

18 Linguagem C para PIC

1.15 - Anotaes

Linguagem C para PIC

19

Recursos Bsicos: Exemplo 31.16 - Recursos do Livro

Contador Hexadecimal

Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos nos exemplos anteriores e tabela de constante (cap.12.21 pg. 309 do livro Programao em C).

1.17 - Lgica do exemploAtravs dos botes S1 e S2 o contador ser incrementado ou decrementado, e o seu valor mostrado no display de sete segmentos ds4. A finalidade de nosso exemplo demonstrar a implementao de tabelas utilizando a memria de programa, sendo est tabela uma matriz unidimensional, nossa tabela far a converso de BCD para sete segmentos, realizando a funo de um circuito decodificador. Para o devido tratamento dos botes, neste exemplo foi implementada uma rotina de filtro para cada boto evitando o problema de debouncing, alm do filtro foi criado um flag, para cada boto, que tem a funo de indicar se a tecla est pressionada ou liberada. Desta forma para que o contador seja incrementado ou decrementado o boto deve ser pressionado e depois liberado. A varivel contador ser utilizada como indexador da tabela de constante, assim sendo para o contador igual zero, ser retornado o cdigo de sete segmentos para o nmero zero e assim por diante.

20 Linguagem C para PIC

1.18 - Esquema Eltrico

220R +5V +5V RESET 10K1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

MC1MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC632 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25

a b c d e f g Dp

DS4a f e d g b c Dp

220R 4,7K

BC337

+5V

4MHz

16 17 18 23 24

16F877A

+5V

+5V

10K

10K

RB0 S1

RB1 S2

PIC16F877

Linguagem C para PIC

21

1.19 - Fluxograma

MAIN

CONFIGURAES INICIAIS TRIS, PORTAS, WATCHDOG, PRESCALER.

INICIALIZA PORTB COM 0X10 B LIMPA WATCHDOG

A

22 Linguagem C para PIC

A

NO

BOTO S1 PRESS.?

SIM

Re-carrrega o Filtro do Boto Marca boto liberado

O boto j estava pressionado ?

SIM

C

NO

NO

Filtro 0 ?

Marca Boto pressionado

SIM

Decrementa o Filtro NO

Contador Max ?

SIM Incrementa o contador Consulta tabela de converso e atualiza o display

C

Linguagem C para PIC

23

C

NO

BOTO S2 PRESS.?

SIM

Re-carrrega o Filtro do Boto Marca boto liberado

O Boto j estava pressionado ?

SIM

B

NO

NO

Filtro 0 ?

Marca Boto pressionado

SIM

Decrementa o Filtro NO

Contador Min ?

SIM Decrementa o contador Consulta tabela de converso e atualiza o display

B

24 Linguagem C para PIC

1.20 - Cdigo/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 3 * * CENTRO DE CAPACITAO - LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: [email protected] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * // // * * * * * * * * */

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Contador hexadecimal que utiliza dois botes para incrementar e decrementar o valor da varivel "contador". O contador est limitado pelas constantes min e max.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt // configurao dos fusveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 400 #define min 0 #define max 15 // tamanho do filtro // valor mnimo para o contador // valor mximo para o contador

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int contador=min; // long int filtro0=t_filtro; // long int filtro1=t_filtro; // int flags=0; // inicia contador com mnimo inicia filtro do bot1 inicia filtro do bot2 limpa os flags

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. #bit bt_UP_press = flags.0 #bit bt_DOWN_press = flags.1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e)

Linguagem C para PIC

25

#byte #byte #byte #byte #byte

porta portb portc portd porte

= = = = =

0x05 0x06 0x07 0x08 0x09 * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. // Estado do boto UP // 1 -> Liberado // 0 -> Pressionado * * */ e

/* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit

botao_UP = portb.0

#bit

botao_DOWN = portb.1 // Estado do boto DOWN // 1 -> Liberado // 0 -> Pressionado * * */ e

/* * * // //

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * As sadas devem ser associadas a nomes para facilitar a programao futuras alteraes do hardware.

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ byte const tabela[16] = { //PGFEDCBA ; POSIO RELATIVA AOS SEGMENTOS 0b00111111, // 0H - 0 0b00000110, // 1H - 1 0b01011011, // 2H - 2 0b01001111, // 3H - 3 0b01100110, // 4H - 4 0b01101101, // 5H - 5 0b01111101, // 6H - 6 0b00000111, // 7H - 7 0b01111111, // 8H - 8 0b01101111, // 9H - 9 0b01110111, // AH - A 0b01111100, // BH - B 0b00111001, // CH - C 0b01011110, // DH - D 0b01111001, // EH - E 0b01110001}; // FH - F /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_counters(rtcc_internal, wdt_2304ms); set_tris_a(0b11111111); set_tris_b(0b11101111); set_tris_c(0b11111111); set_tris_d(0b00000000); set_tris_e(0b00000111); porta = 0x00; portb=(0b00010000); // seleciona display ds4 portc = 0x00; portd = (tabela[contador]); // mostra no display valor inicial do contador porte = 0x00;

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

26 Linguagem C para PIC

* Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog timer /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao_UP) // O boto UP est pressionado ? { // sim, if (!(bt_UP_press)) // O boto UP j foi tratato ? { // no. if (filtro0 !=0) // Fim do filtro do boto UP ? { filtro0--; // No, ento decrementa o filtro } else // Sim, Faz a ao do boto { bt_UP_press = 1; // Marca que o boto est pressionado if (contador != max) { contador++; // incrementa o contador portd = (tabela[contador]); // consulta tabela, atualiza // display } } } } else { // boto 0 liberado filtro0 = t_filtro; // inicia o filtro do boto 0 bt_UP_press = 0; // marca que o boto foi liberado } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao_DOWN) // testa boto DOWN { // boto DOWN pressionado if (!(bt_DOWN_press)) // o boto DOWN j foi tratato ? { // no if (filtro1 !=0) // Fim do filtro do boto DOWN ? { filtro1--; // no, ento decrementa o filtro } else // SIM. Faz a ao do boto { bt_DOWN_press = 1; // marca que o boto est pressionado if (contador != min) { contador--; // decrementa o contador portd = (tabela[contador]);// consulta tabela, atualiza // display } } } } else { // boto 1 liberado filtro1 = t_filtro; // inicia o filtro do boto 1 bt_DOWN_press = 0; // marca que o boto foi liberado } } }

Linguagem C para PIC

27

1.21 - Exerccios PropostosAgora que o exemplo j foi estudado e esclarecido, aproveite para gerar novos problemas e solues, seguindo os exerccios propostos: 1. 2. 3. 4. Modifique o programa para que o contador conte de 1 a 5. Implemente um boto para reset do contador. Altere a tabela para que as posies de A a F da tabela apaguem o display. Mude a contagem do dsp4 para o display dsp3.

28 Linguagem C para PIC

1.22 - Anotaes

Linguagem C para PIC

29

Recursos Avanados: Exemplo 41.23 - Recursos do Livro

Maximizao de Pinos de I/O

Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos nos exemplos anteriores e mais, funes do compilador para controle de interrupo, tratamento automtico (cap.12 pg.254 do livro Programao em C), controle do processador (cap.11 pg.223 do livro Programao em C), manipulao de Timers (cap.11.8 pg.211 do livro Programao em C), diretivas de configurao para uso de interrupes, #int_xxx e #priority (cap.10, pg.161 e pg.166 do livro Programao em C).

1.24 - Lgica do exemploNosso exemplo ser composto de um programa capaz de ler quatro botes e tocar o buzzer com uma freqncia diferente para cada combinao de botes. Para cada boto existe um led ligado no mesmo pino, que ser utilizado para indicar os botes pressionados no momento. Utilizaremos os timers e duas interrupes para controlarmos a freqncia de leitura dos botes e a freqncia do buzzer: Timer 0: controlar a freqncia de varredura dos botes; Timer 2: controlar a freqncia do som. O som ser feito excitando o buzzer com uma onda quadrada de freqncia varivel. Variaremos esta freqncia alterando o valor de PR2, que controla o estouro deste timer. Desta forma, nosso programa principal ser um loop infinito sem efeito algum. Somente ficaremos esperando o acontecimento das interrupes. Para a varredura dos botes ajustaremos a interrupo de TMR0 para aproximadamente 500Hz: Ciclo de Mq. 1 s Prescale 8 Conta TMR0 256 Auxiliar Perodo 2048 s Freqncia 488 Hz

Alm disso, o sistema possui um filtro, regulado pela constante FILTRO_BOTAO, para evitar o debounce da tecla. Este filtro garante que a tecla fique pressionada pelo tempo de FILTRO_BOTAO x 2048s. Quanto freqncia do buzzer, esta ser controlada por TMR2. Calibramos os valores de pre e postscale para que a freqncia da interrupo do TMR2 varie entre 100Hz e 2kHz, com a variao de PR2 entre 16 e 240: Ciclo de Mq. 1 s 1 s Prescale 16 16 Postscale 1 1 PR2 16 240 Perodo 256 s 3840 s Freqncia 3906 Hz 260 Hz

Para facilitar a implementao, a cada interrupo inverteremos o estado do pino de acionamento do buzzer. Desta forma, a freqncia deste ser equivalente metade da freqncia da interrupo do TMR2. O Livro Conectando o PIC, possui um cpitulo dedicado a este assunto.

30 Linguagem C para PIC

1.25 - Esquema Eltrico

+5V

RESET 10K1 2 3 4 5 6 7

MC1MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC632 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25

+5V

BUZZER

+5V

8 9 10 11 12 13 14 15 16 17 18 23 24

4MHz

16F877A

+5V

+5V

+5V

+5V

10K

10K

10K

10K

RB0

10K

RB1 S1

10K

RB2 S2

10K

RB3 S3

10K

330R

330R

330R

330R

S4

L1

L2

L3

L4

Linguagem C para PIC

31

1.26 - Fluxograma

MAIN

CONFIGURAES INICIAIS TRIS, PORTAS, WATCHDOG, PRESCALER.

LIGA AS INTERRUPES

LIMPA WATCHDOG

32 Linguagem C para PIC

INTERRUPES

NO

INT DE TMR0?

SIM

Trata TMR2

Trata TMR0

TRATA TMR2

NO

SADA DO BUZZER EST LIGADA?

SIM

LIGA A SADA DO BUZZER

DESLIGA A SADA DO BUZZER

FIM DA INTERRUPO

Linguagem C para PIC

33

TRATA TMR0

Convetre pinos dos botes em entradas

Delay de 4 ciclos de mquina para estabilizao do port

L todos os botes e guarda em varivel temporria (STATUS_BOTES)

Converte pinos dos botes em sada

CHECA BOTO S1 NO

Reinicia Filtro

Boto S1 PRESS ?

Limpa Flag de boto pressionado (Status Leds)

SIM

Fim do Filtro ?

NO

SIM Marca flag de boto pressionado

CHECA BOTO S2

CHECA BOTO S3

CHECA BOTO S4

A

34 Linguagem C para PIC

AO DOS BOTES

A

Atualiza leds conforme botes pressionados

NO

Algum boto pressionado ?

SIM

Inicializa PER com 255

Consulta tabela conforme conbinao de botes pressionados

Deliga interrupo de TMR2

Inicializa TMR2

Desliga a sada do Buzzer

Liga Interrupo de TMR2

FIM DA INTERRUPO

Linguagem C para PIC

35

1.27 - Cdigo/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 4 * * CENTRO DE CAPACITAO - LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: [email protected] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Este software est preparado para ler quatro botes e //durao variavel conforme a tecla pressionada, alm de //indicando a ltima tecla pressionada. * * * * * * * * */

* * * * * * * * * * * * * * * * * * */ tocar o buzzer com acender o led

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include // microcontrolador utilizado

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt fusveis // configurao dos

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 20 // tamanho do filtro

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int status_botoes = 0; int status_leds = 0; int per = 0; int int int int filtro1 filtro2 filtro3 filtro4 = = = = t_filtro; t_filtro; t_filtro; t_filtro; // armazena o estado lgico dos botes // atualiza leds conforme o boto pressionado // limitador de contagem do Timer2 // // // // inicia inicia inicia inicia filtro filtro filtro filtro do do do do botao1 botao2 botao3 botao4

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use #use #use #use #use #byte #byte #byte #byte #byte fast_io(a) fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09

36 Linguagem C para PIC

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. * * */ e

botao1 = status_botoes.0 // Estado do boto 1 // 1 -> Liberado // 0 -> Pressionado botao2 = status_botoes.1 // Estado do boto 2 // 1 -> Liberado // 0 -> Pressionado botao3 = status_botoes.2// Estado do boto 3 // 1 -> Liberado // 0 -> Pressionado botao4 = status_botoes.3 // Estado do boto 4 // 1 -> Liberado // 0 -> Pressionado * * */ E

#bit

#bit

#bit

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO //FUTURAS ALTERAES DO HARDWARE. #bit #bit #bit #bit #bit botao1_press botao2_press botao3_press botao4_press = = = = status_leds.0 status_leds.1 status_leds.2 status_leds.3

buzzer = porta.5

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ byte const tabela[16] = {255,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurao do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // A rotina principal simplesmente limpa o WDT, pois toda a lgica do // programa tratada dentro das interrupes. void main() { setup_adc_ports (no_analogs); setup_counters(rtcc_internal , rtcc_div_8); setup_timer_2 (t2_div_by_16,per,1); set_tris_a(0b11011111); set_tris_b(0b11110000); set_tris_c(0b11111111); set_tris_d(0b11111111); set_tris_e(0b00000111); porta=(0b00000000); portb=(0b00000000); portc=(0b00000000); portd=(0b00000000); porte=(0b00000000); enable_interrupts(GLOBAL); enable_interrupts(INT_RTCC); #priority timer0,timer2

// prioridade para a int de trm0

Linguagem C para PIC

37

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog timer } } /* * * // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Esta interrupo ocorrer a cada 2048us. O filtro dos botes tem durao de 40ms (2048us x 20) e so decrementados a cada interrupo. Esta interrupo responsvel por converter os pinos dos botes em entrada, salvar a condio dos botes em varivel temporria e converter os pinos em sada novamente.

#int_rtcc void trata_int_tmr0() { set_tris_b(0b00001111); delay_cycles(4); status_botoes = portb; set_tris_b(0b00000000);

// configura os pinos como entrada para // testar os botes // aguarda 4 ciclos de mquina para a // estabilizao do portb // l o status dos botoes, salva em varivel // temporria // configura os pinos como sada para // controle dos leds

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao1) { filtro1--; if (filtro1 == 0) { botao1_press = 1; } } else { filtro1 = t_filtro; botao1_press = 0; } // // // // testa boto 1 boto 1 est pressionado ? Sim, ento decrementa o filtro acabou o filtro do boto 1 ?

// marca que o boto est pressionado

// boto 1 liberado // inicia o filtro do boto 1 // marca que o boto foi liberado

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao2) { filtro2--; if (filtro2 == 0) { botao2_press = 1; } } else { filtro2 = t_filtro; botao2_press = 0; } /* * * * * * * * * * * * * * * * * * * * * Tratamento do * * * * * * * * * * * * * * * * * * * * if (!botao3) { // // // // testa boto 2 boto 2 est pressionado ? Sim, ento decrementa o filtro fim do filtro do boto 2 ?

// marca que o boto est pressionado

// boto 2 liberado // inicia o filtro do boto 2 // marca que o boto foi liberado * * * * * * * * * * * * * * * * Boto 3 * * * * * * * * * * * * * * * * */ // testa boto 3 // boto 3 est pressionado ?

38 Linguagem C para PIC

filtro3--; if (filtro3 == 0) { botao3_press = 1; } } else { filtro3 = t_filtro; botao3_press = 0; } /* * * * * * * * * * * * * * * * * * * * * Tratamento do * * * * * * * * * * * * * * * * * * * * if (!botao4) { filtro4--; if (filtro4 == 0) { botao4_press = 1; } } else { filtro4 = t_filtro; botao4_press = 0; }

// Sim, ento decrementa o filtro // fim do filtro do boto 3 ? // marca que o boto est pressionado

// boto 3 liberado // inicia o filtro do boto 3 // marca que o boto foi liberado * * * * * * * * * * * * * * * * Boto 4 * * * * * * * * * * * * * * * * */ // testa boto 4 // boto 4 est pressionado ? // Sim, ento decrementa o filtro // fim do filtro do boto 4 ? // marca que o boto est pressionado

// boto 4 liberado // inicia o filtro do boto 4 // marca que o boto foi liberado

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Atualiza Leds conforme botes pressionados * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ portb = status_leds; // atualiza os leds if (status_leds == 0) { per = 0xff; setup_timer_2 (t2_div_by_16,per,1); disable_interrupts (INT_TIMER2); buzzer = 0; } else { per = (tabela[status_leds]);// consulta tabela e inicializa timer2. setup_timer_2 (t2_div_by_16,per,1); enable_interrupts (INT_TIMER2); // habilita interrupo de timer2. } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Est interrupo s ir ocorrer quando alguma tecla estiver pressionada, // o periodo de ocorrncia depende do boto ou da conbinao de botes pressionados, // ela ir inverter o pino de I/O do buzzer a cada interrupo. #int_timer2 void trata_int_tmr2() { if (buzzer != 0) // o buzzer est ligado ? { buzzer = 0; // sim, ento desliga } else { buzzer = 1; // no, ento liga } }

Linguagem C para PIC

39

1.28 - Exerccios PropostosAgora que o exemplo j foi estudado e esclarecido, aproveite para gerar novos problemas e solues, seguindo os exerccios propostos: 1. Utilize as funes disponveis do Compilador para inverter o estado do buzzer. 2. Modifique o controle dos leds, os botes pares controlam os leds impares e os botes impares controlam os leds pares, conforme a tabela abaixo. Boto 1 Boto 2 Boto 3 Boto 4 Led 2 Led 1 Led 4 Led3

40 Linguagem C para PIC

1.29 - Anotaes

Linguagem C para PIC

41

Recursos Avanados: Exemplo 51.30 - Recursos do Livro

Varredura de Display

Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos nos exemplos anteriores e mais, funes do compilador para controle de interrupo, tratamento manual (cap.12 pg.254 do livro Programao em C), controle do processador (cap.11 pg.223 do livro Programao em C), manipulao de Timers (cap.11.8 pg.211 do livro Programao em C), introduo de cdigo em assembly no programa em C (cap.10, pg.151 do livro Programao em C),retorno de valores em funes assembly (cap.9, pg.147 do livro Programao em C), diretivas de configurao para uso de interrupes, #int_global e #priority (cap.10, pg.162 e pg.166 do livro Programao em C).

1.31 - Lgica do exemploO exemplo desenvolvido para esta aula faz muito mais que simplesmente implementar a varredura dos displays. Trata-se de um contador regressivo de segundos, ou seja, um temporizador capaz de contar at 9.999 segundos. Para isso, utilizaremos os displays para indicar o valor atual do temporizador. A primeira tecla (S1) no possui nenhuma funo. Por outro lado, o led relacionado a ela (L1) ser utilizado para indicar o estado do temporizador: L1 Aceso Apagado Descrio Temporizador em contagem regressiva Temporizador paralisado

Os demais botes apresentam as funes de controle do temporizador: Boto S2 S3 S4 Descrio Incrementa o valor inicial em 1 segundo Decrementa o valor inicial em 1 segundo Inicia e paralisa o temporizador

Os botes de incremento e decremento operam de forma rotativa, isto , comutam automaticamente entre 0000 e 9999. Outra caracterstica destes botes que eles executam suas funes repetidamente quando mantidos pressionados e s funcionam quando o temporizador est paralisado. Ao atingir o valor zero (0000) o temporizador automaticamente paralisado, desligandose o led indicativo (L1). Para o sistema de varredura foram criadas 4 variveis para armazenamento dos dgitos mostrados nos respectivos displays: UNIDADE, DEZENA, CENTENA e MILHAR. Estas variveis representam o valor atual do temporizador e so incrementadas e decrementadas atravs dos botes. Na verdade, os botes alteram diretamente o valor da unidade. A lgica do sistema compara este valor com os limites (0 e 9) para alterar ou no os demais dgitos. A freqncia de varredura controlada pela interrupo de Timer0. Ajustamos seus parmetros para que a comutao entre displays (tempo da interrupo) seja de aproximadamente 4kHz: Ciclo de Mq. 1 s42 Linguagem C para PIC

Prescale 1

Conta TMR0 256

Auxiliar -

Perodo 256 s

Freqncia 3900 Hz

A freqncia de varredura ser a freqncia de comutao dividida pelo nmero de displays, que no nosso caso ser de aproximadamente 1kHz. Dentro do tratamento da interrupo de TMR0 desligado o display atual, carregado o valor do dgito correspondente ao display e ligado o display seguinte. Quanto contagem dos segundos, utilizamos a interrupo de Timer1 para esta finalidade. Veja os ajustes dos parmetros para esta interrupo: Ciclo de Mq. 1 s Prescale 8 Conta TMR1 62500 Auxiliar 2 Perodo 1.000.000 s Freqncia 1 Hz

Para isso, configuramos o prescale de TMR1 em 1:8 e iniciamos o contador com o valor total menos o desejado para a contagem (65.536 62.500). Desta maneira a interrupo acontecer a cada 0,5 segundo. Para podermos contar 1 segundo foi criado uma varivel auxiliar denominada DIVISOR_TMR1. Cada vez que o sistema entrar na interrupo de TMR1 e o contador auxiliar (DIVISOR_TMR1) terminar, o tempo decrementado, comeando pela unidade e chegando at a milhar, se for necessrio. Quando o tempo termina (0000) tanto o led quanto o TMR1 so desligado. Neste exemplo est sendo utilizado o tratamento Manual de interrupes, neste modo ns devemos providenciar todo o cdigo necessrio para o tratamento da interrupo, tais como: salvar contexto, restaurar contexto, limpar os flags de indicao de interrupo e criar os registradores para as rotinas de salvar e restaurar contexto. A prioridade de tratamento da interrupo depende da seqncia de teste dos flags de int, que tambm de responsabilidade do programador. Para este tipo de tratamento estamos utilizando a diretiva #int global.

Linguagem C para PIC

43

1.32 - Esquema Eltrico220R a b c d e f g Dp DS1a f e d g b c Dp f e d

DS2a g b c Dp f e

DS3a g b c d Dp f e

DS4a g b c d Dp

220R

Comum 1 BC337

Comum 2 BC337

Comum 3 BC337

Comum 4 BC337

+5V +5V RESET 10K1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

4,7K

4,7K

4,7K

4,7K

MC1MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC632 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25

+5V

4MHz

16 17 18 23 24

16F877A

+5V

+5V

+5V

RB0330R 10K 10K 10K

RB1 S2L1

RB2 S3

RB3 S4

44 Linguagem C para PIC

1.33 - Fluxograma

MAIN

CONFIGURAES INICIAIS TRIS, PORTAS, WATCHDOG, PRESCALER.

Configura Timer1

Liga as interrupes A Limpa WATCHDOG

BOTO UP PRESS.?

SIM

Trata Boto UP

NO

BOTO DOWN PRESS.?

SIM

Trata Boto Down

NO

BOTO Start/Stop PRESS.?

SIM

Trata Boto Start/Stop

NO

Recarrega Filtro e turbo das teclas

Linguagem C para PIC

45

INTERRUPES

NO

INT DE TMR0?

SIM

SWITCH CASE Recarrega Timer1 Incrementa ponteiro de seleo de Display, desliga display do milhar, consulta tabela de converso para sete segmentos, liga display da unidade

Atualiza Display da Unidade? decrementa contador de int. NO

SIM

Passou 1 segundo ?

NO

Atualiza Display da Dezena?

SIM

Incrementa ponteiro de seleo de Display, desliga display da unidade, consulta tabela de converso para sete segmentos, liga display da dezena

SIM

NO

Recarrega contador de int. Atualiza Display da Centena? SIM

Incrementa ponteiro de seleo de Display, desliga display da dezena, consulta tabela de converso para sete segmentos, liga display da centena

Decrementa Timer

NO

Timer Chegou a zero?

NO

Atualiza Display do milhar?

SIM

Zera ponteiro de seleo de Display, desliga display da centena, consulta tabela de converso para sete segmentos, liga display do milhar

NO SIM

Desliga led de indicao de timer operando FIM DA INTERRUPO

Desabilita interrupo de Timer1

FIM DA INTERRUPO

46 Linguagem C para PIC

Trata Boto UP

Trata Boto DOWN

Timer Ligado ?

SIM

Timer Ligado ?

SIM

NO

NO

Decrementa Filtro

Decrementa Filtro

NO Fim do Filtro ? Fim do Filtro ?

NO

SIM

SIM

Decrementa Turbo

Decrementa Turbo

Fim do Temporizador para Turbo do Boto?

NO

Fim do Temporizador para Turbo do Boto?

NO

SIM

SIM

Recarrega temporizador para Turbo

Recarrega temporizador para Turbo

Incrementa Timer

Decrementa Timer

A

A

Linguagem C para PIC

47

Trata boto Start/Stop

SIM Ao j foi executada ?

NO

NO Filtro terminou ?

SIM

NO Timer ligado ?

SIM SIM Timer igual a zero ? Apaga led de indicao de Timer ligado

NO Desabilita interrupo de Timer1

Acende Led de indicao de Timer ligado

Carrega Timer1

A

Carrega contador de interrupes

Habilita interrupo de Timer 1

A

48 Linguagem C para PIC

Incrementa Timer

Decrementa Timer

Incrementa unidade

Decrementa unidade

NO Unidade = 10 ? Unidade = 0XFF ?

NO

SIM

SIM

Zera unidade Incrementa dezena

Unidade = 9 Decrementa dezena

NO Dezena = 10 ? Dezena = 0XFF ?

NO

SIM

SIM

Zera dezena Incrementa centena

Dezena = 9 Decrementa centena

NO centena = 10 ? centena = 0XFF ?

NO

SIM

SIM

Zera centena Incrementa milhar

Centena = 9 Decrementa milhar

NO Milhar = 10 ? Milhar = 0XFF ?

NO

SIM Zera milhar

SIM Milhar = 9

Return

Return

Linguagem C para PIC

49

1.34 - Cdigo/* * * * * * * * * * * * /* * * // // // // // // // // /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 5 * * CENTRO DE CAPACITAO - LABTOOLS * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * E-MAIL: [email protected] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi preparado para demonstrar o funcionamento do TIMER de 16 bits do PIC (TMR1), da varredura de displays e do tratamento manual de int. Consiste num temporizador de segundos. dois botes foram utilizados para programar o tempo da contagem. Um outro boto foi utilizado para disparar o contador. O temporizador consegue contar at 9999 segundos, de forma que os 4 displays de 7 segmentos foram necessrios. A contagem regressiva. um led indica que o temporizador est operando. Quando o sistema chega a 0000 (ZERO) o led desligado automaticamente. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // microcontrolador utilizado

#include

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt fusveis // configurao dos

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT)

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 250 // tamanho do filtro #define turbo_tecla 60 #define delta_timer1 (65536 - 62500) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int int int int int int int int display = 0 ; contador = 2; filtro = t_filtro; turbo = 1; unidade = 9; dezena = 9; centena = 9; milhar = 9; int int int INT W_TEMP; STATUS_TEMP; FSR_TEMP; PCLATH_TEMP; // atualiza os displays // contador de interrupes de timer1 // inicia filtro dos botes // inicia turbo das teclas // varivel unidade do timer de 1 seg // varivel dezena do timer de 1 seg // varivel centena do timer de 1 seg // varivel milhar do timer de 1 seg // variveis para salvar contexto

static static static static

50 Linguagem C para PIC

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte #byte porta=0x05 portb=0x06 portc=0x07 portd=0x08 porte=0x09 * * * * * * * * * * * * * * * * * * * * * * */ o bit 0 do sfr pir1 bit 2 do sfr intcon o bit 0 do fsr pie1 do reg de status do reg de fsr do reg de pclath

/* * * * * * * * * * * * * * * * * * * * * * * * * * * Definio de SFR's * * * * * * * * * * * * * * * * * * * * * * * * * * #bit tmr1if = 0x0c.0 // tmr1if #bit t0if = 0x0b.2 // t0if o #bit tmr1ie = 0x8c.0 // tmr1ie #byte status = 0x03 // define endereo #byte fsr = 0x04 // define endereo #byte pclath = 0x0a // define endereo

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. // Estado do boto up // 1 -> Liberado // 0 -> Pressionado // Estado do boto down // 1 -> Liberado // 0 -> Pressionado * * */ e

bt_up = portb.1

#bit

bt_down

= portb.2

#bit

bt_start_stop = portb.3 // Estado do boto start_stop // 1 -> Liberado // 0 -> Pressionado * * */ E

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO //FUTURAS ALTERAES DO HARDWARE. #bit estado_timer = portb.0 // led de estado do timer // 1 -> timer contando // 0 -> timer parado // seleo do display unidade (0) // seleo do display dezena // seleo do display centena (2) // seleo do display milhar (3)

#bit #bit #bit #bit

disp0 disp1 disp2 disp3

= portb.4 = portb.5 = portb.6 = portb.7

(1)

Linguagem C para PIC

51

/* * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * byte const converte[11] = { //PGFEDCBA 0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111, 0b00000000}; /* * * * * * * * * * * * * * Funo * * * * * * * * * * * * * decrementa_timer() { unidade --; if (unidade == 0xff) { unidade = 9; dezena --; } if (dezena == 0xff) { dezena = 9; centena --; } if (centena == 0xff) { centena = 9; milhar --; } if (milhar == 0xff) { milhar = 9; } } /* * * * * * * * * * * * * * Funo * * * * * * * * * * * * * incrementa_timer() { unidade ++; if (unidade == 10) { unidade = 0; dezena ++; } if (dezena == 10) { dezena = 0; centena ++; } if (centena == 10) { centena = 0; milhar ++; } if (milhar == 10) { milhar = 0; } }

* * * * * * * * * * * * * * * * * * * * * * * * * * */ POSIO RELATIVA AOS SEGMENTOS // 0H - 0 // 1H - 1 // 2H - 2 // 3H - 3 // 4H - 4 // 5H - 5 // 6H - 6 // 7H - 7 // 8H - 8 // 9H - 9 // blank

* * * * * * * * * * * * * * * * * * * * * * * de decremento do Timer * * * * * * * * * * * * * * * * * * * * * * * */

* * * * * * * * * * * * * * * * * * * * * * * de incremento do Timer * * * * * * * * * * * * * * * * * * * * * * * */

52 Linguagem C para PIC

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de tratamento de interrupo de Timer1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupo ocorrer a cada 0,5 segundos, a rotina de tratamento executada a // cada 2 interrupes (contador). #inline trata_tmr1() { set_timer1(delta_timer1); // carraga timer1 tmr1if = 0; // limpa flag de interrupo contador --; // decrementa contador de interrupes if (contador == 0) { set_timer1(delta_timer1); // carraga timer1 contador = 2; // carrega contador de int decrementa_timer(); if((unidade==0)&&(dezena==0)&&(centena==0)&&(milhar==0))// timer est zerado? { estado_timer = 0; // sim, apaga o led e tmr1ie = 0; // desliga tratamento de interrupo de timer1 } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupo ocorrer a cada 256us. #inline trata_tmr0() { t0if = 0; switch(display) // incio da varredura dos displays { case 0: display++; // incrementa a varivel de varredura disp3 = 0; // desliga o display 3 portd = (converte[unidade]); // atualiza o portd disp0 = 1; // liga o display 0 break; // sai case 1: display++; // disp0 = 0; // portd = (converte[dezena]); disp1 = 1; // break; // case 2: display++; // disp1 = 0; // portd = (converte[centena]); disp2 = 1; // break; // case 3: display disp2 = portd = disp3 = break; } } = 0; // 0; // (converte[milhar]); 1; // // incrementa a varivel de varredura desliga o display 0 // atualiza o portd liga o display 1 sai incrementa a varivel de varredura desliga o display 1 // atualiza o portd liga o display 2 sai inicia a varivel de varredura desliga o display 2 // atualiza o portd liga o display 3 sai

Linguagem C para PIC

53

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para salvar contexto * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ salva_contexto() { #asm MOVWF W_TEMP // SALVA REGISTRADOR DE TRABALHO E SWAPF STATUS,W // DE STATUS DURANTE O TRATAMENTO MOVWF STATUS_TEMP // DA INTERRUPO. MOVF FSR,W MOVWF FSR_TEMP // SALVA REGISTRADOR FSR MOVF PCLATH,W MOVWF PCLATH_TEMP // SALVA REGISTRADOR PCLATH CLRF PCLATH // LIMPA REGISTRADOR PCLATH, SELECIONA PAGINA 0 CLRF STATUS // LIMPA REGISTRADOR STATUS #endasm } /* * * * * * * * * * * * * * * * * * * * * * * * * * Funo para restaurar contexto * * * * * * * * * * * * * * * * * * * * * * * * * restaura_contexto() { #asm MOVF PCLATH_TEMP,W MOVWF PCLATH // RECUPERA REG. MOVF FSR_TEMP,W MOVWF FSR // RECUPERA REG. SWAPF STATUS_TEMP,W MOVWF STATUS // RECUPERA REG. SWAPF W_TEMP,F SWAPF W_TEMP,W // RECUPERA REG. #endasm } * * * * * * * * * * * * * * * * * * * * * * */

PCLATH (PAGINAO) FSR (END. INDIRETO) STATUS WORK

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurao do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs); setup_counters(rtcc_internal, wdt_2304ms); setup_timer_1 (t1_internal | t1_div_by_8); set_tris_a(0b11111111); set_tris_b(0b00001110); set_tris_c(0b11111111); set_tris_d(0b00000000); set_tris_e(0b00000111); porta=(0b00000000); portb=(0b00000000); portc=(0b00000000); portd=(0b00000000); porte=(0b00000000); enable_interrupts(INT_RTCC ); enable_interrupts(GLOBAL); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(TRUE) { RESTART_WDT(); // rotina principal // incia o watch-dog timer

54 Linguagem C para PIC

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de incremento (UP) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!bt_up) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de decremento (down) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!bt_down) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de Start / Stop * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!bt_start_stop) // testa boto start_stop { goto trata_start_stop; // desvia para a rotina para ligar ou // desligar o timer } filtro = t_filtro; turbo = 1; } //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_up: if (estado_timer == 0) // o timer est parado? { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? { turbo --; // decrementa o turbo da tecla if (turbo == 0) // sim, fim do turbo do boto ? { turbo = turbo_tecla; // carrega o turbo incrementa_timer(); // incrementa o timer } } } goto loop; //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_dowm: if (estado_timer == 0) // o timer est parado? { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? { turbo --; // decrementa o turbo da tecla if (turbo == 0) // sim, fim do turbo do boto ? { turbo = turbo_tecla; // carrega o turbo decrementa_timer(); // decrementa o timer } } } goto loop; // testa boto down trata_dowm;// desvia para a rotina de decremento do timer // testa boto up trata_up;// desvia para a rotina de incremento do timer

Linguagem C para PIC

55

//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_start_stop: if (filtro != 0) // o timer est parado? { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? { if (estado_timer != 0) // sim, o timer est ligado ? { estado_timer = 0; // indica timer parado tmr1ie = 0; // desliga o tratamento de interrupo de timer1 } else { if((unidade!=0)||(dezena!=0)||(centena!=0)||(milhar != 0)) // timer est zerado? { estado_timer = 1;// no, indica que o timer est contando contador = 2; // carrega contador auxiliar set_timer1(delta_timer1); // carrega timer 1 tmr1if = 0; // limpa flag de int tmr1 tmr1ie = 1; // liga o tratamento de interrupo de timer1 } } } } goto loop; } /* * * // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de Tratamento de interrupes * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Todo o tratamento de interrupo feito manualmente. As funes salva contexto e restaura contexto foram feitas em assembler Observe que a prioridade das interrupes realizada atravs do comando IF e a ordem do teste determina a prioridade no tratamento da interrupo.

#int_global Void trata_int() { salva_contexto();// salva os registradores antes do tratamento da int if (t0if) { trata_tmr0(); } else // int de tmr0 ? // sim, trata tmr0

// no, { if (tmr1if) // int de tmr1 ? { trata_tmr1(); // sim, trata tmr1 } } // no. // restaura contexto e sai da int.

restaura_contexto(); }

56 Linguagem C para PIC

1.35 - Exerccios PropostosAgora que o exemplo j foi estudado e esclarecido, aproveite para gerar novos problemas e solues, seguindo os exerccios propostos: 1. Mude a rotina para que o temporizador conte de forma crescente e desligue quando chegar a zero. 2. Altere a rotina de temporizao para que o timer seja decrementado a cada 1 minuto. 3. Mude a rotina do timer para que ele funcione como um cronmetro com um boto de start e um de reset.

Linguagem C para PIC

57

1.36 - Anotaes

58 Linguagem C para PIC

Recursos Avanados: Exemplo 6 Controle do LCD1.37 - Recursos do LivroPara o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos no exemplo 1 e mais, controle do LCD (cap.12.7.2 pg. 310 do livro Programao em C).

1.38 - Lgica do exemploEste exemplo foi criado para demonstrar a inicializao de LCD de 2 linhas por 16 caracteres utilizando 8 vias de dados, e como enviar dados e comandos para o LCD. O exemplo controla o acionamento de leds e do ventilador atravs de um MENU, tecla S1, de escolha de opes, onde ser possvel escolher as opes de ligar ou desligar atravs da tecla ENTER, tecla S2. A escolha das telas ser controlada pelo comando SWITCH do compilador C. Aps o programa ser carregado a seguinte tela ser visualizada no display: T a r e f a S e l e c i o n e P r e s s M e n u Quando a tecla S1 pressionada a mensagem trocada indicando as opes de controle, pressionando a tecla menu possvel escolher entre controle de leds e controle do ventilador. O controle selecionado indicado por uma seta . c t r c t r d o s d o l e d s v e n t

Uma vez que a tela de controle foi escolhida, pressione a tecla enter para entrar na tela de controle, de acordo com a tela selecionada poderemos visualizar as seguintes telas: c t r d o s l e d s O N > O F F

V e n t i l a d o r O N > O F F Na tela de controle, deve se pressionar enter para escolher a opo desejada, ON ou OFF, quando a tecla for pressionada o smbolo > ser deslocado para a condio desejada.

Linguagem C para PIC

59

1.39 - Esquema Eltrico+5V

7 8 9 1 0 1 1 1 2 1 3 1 4

DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7

VDD 2 VO 3 VSS 1 RS 6 EN 5 R/W4

10K

RS EN

LCD +5V

RESET

10K MC1MCLR RA0 RA1 4 RA2 5 RA3 6 RA4 7 RA5 8 RE0 9 RE1 10 1 RE2 1 VDD 1 2 VSS 1 3 OSC1 1 4 OSC2 1 5 RC0 1 6 RC1 1 7 RC2 1 8 RC3 2 3 RC4 2 4 RC52 3 1 3 2 3 1 4 0 3 9 3 8 3 7 3 6 3 5 3 4 33 3 0 2 9 2 8 2 7 2 2 2 1 2 0 1 9 2 6 2 5

+5VVDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC6

+5V

RS EN

4MHz

16F877 A RB2+5V +5V 330R 330R

RB3

10K +Vcc

10K

RB0 S1

RB1 S2

L3

L4

1N4148

4,7K

60 Linguagem C para PIC

MINI VENTILADOR BC337

1.40 - FluxogramaMAIN

CONFIGURAES INICIAIS TRIS, PORTAS, W ATCHDOG, PRESCALER.

Configura Timer0

Inicializa LCD

Tela principal

Habilita as interrupes A Limpa W ATCHDOG

Escreve tela principal ?

SIM

Tela principal

NO

BOTO MENUPRESS.?

SIM

Trata Boto Menu

NO

BOTO ENTER PRESS.?

SIM

Trata Boto ENTER

NO

Recarrega Filtro dos Botes

Linguagem C para PIC

61

INT ERRUP ES

Declara Variveis locais

Incrementa contador de interrupes

Temp1 = 40

SIM

NO

Zera contador de interrupes SW IT CH CASE

Controle do Led2

SIM

Verifica se o led 1 est aceso Se sim: Pisca o Led 2 a cada 1 segundo. Se no: Apaga o led 2.

NO

Controle do T ime - out da tela principal

SIM

Incrementa contador de time out, aps 5 segundos, limpa o flag "f_tela_principal", para liberar atualizao da tela principal.

NO

FIM DA INT ERRUPO

62 Linguagem C para PIC

Trata Boto MENU

Ao j foi executada ?

SIM

NO

Decrementa Filtro

SIM

Fim do Filtro ?

NO

SIM Contador de Tela < 2

NO

Posiciona a seta na linha 0, coluna 0 do LCD

Posiciona a seta na linha 1, coluna 0 do LCD

A

Linguagem C para PIC

63

Trata Boto ENTER

Ao j foi executada ?

SIM

NO

Decrementa Filtro

SIM

Fim do Filtro ?

NO

Carrega a tela de seleo de tarefa: Controle dos Leds ou Controle do Ventilador

Re-inicia time-out

A

64 Linguagem C para PIC

Linguagem C para PIC

65

Seleo da Tela de Menu Switch Case

SIM Tela 1 do Menu ?

NO

Posiciona a seta na linha 0 coluna 0

SIM Tela 2 do Menu

NO

Posiciona a seta na linha 1 coluna 0

Return

Beep

Fim do loop do Beep ? (conta beep)

SIM

NO

Return

Liga Beep Delay

Desliga Beep Delay

Decrementa conta beep

66 Linguagem C para PIC

Seleo da Tela de Enter Switch Case

SIM Tela 1 do Enter ? Carrega a tela de controle de leds. Carrega contador para tela 3

NO

SIM Tela 2 do Enter Carrega a tela de controle do Ventilador Carrega contador para tela 4

NO

SIM Tela 3 do Enter Indica estado dos leds On ou Off emite beep.

NO

SIM Tela 4 do Enter

NO

Indica estado do ventilador On ou Off emite beep

Return

A

Linguagem C para PIC

67

1.41 - Cdigo/* * * * * * * * * * * * /* * * // // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 6 * * CENTRO DE CAPACITAO - LABTOOLS * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * E-MAIL: [email protected] * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi elaborado para explicar o funcionamento do mdulo de LCD. Foi criada uma rotina para escrever comandos e uma para escrever caracteres, existe tambm uma rotina de inicializao necessria para a correta configurao do LCD. Os botes S1 e S2 so respectivamente boto Menu e Enter, o boto Menu seleciona a tarefa que desejamos executar (controle de Leds ou do Ventilador), o boto Enter seleciona a tarefa e funciona como controle de liga/desliga para a tarefa selecionada. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ arquivo de definies do pic utilizado deve ser referenciado para que nomes definidos pela Microchip possam ser utilizados, sem a necessidade redigitao. // microcontrolador utilizado

/* * * * * // O //os //de

#include

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt fusveis // configurao dos

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT)

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 500 // tamanho do filtro

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. long int filtro = t_filtro; // inicia filtro dos botes int flags1 = 0; // registrador de flags int contador_tela = 0; // contador para seleo de tela int time_out = 0; // registrador para contagem de tempo de time-out int contador,temp1,temp2; // variaveis para a rotina de int de Timer0 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a)

68 Linguagem C para PIC

#use #use #use #use #byte #byte #byte #byte #byte

fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. #bit f_tela_principal = /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit menu flags1.0

* * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programao e do hardware. // Estado do boto menu // 1 -> Liberado // 0 -> Pressionado // Estado do boto enter // 1 -> Liberado // 0 -> Pressionado

= portb.0

#bit

enter = portb.1

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO E //FUTURAS ALTERAES DO HARDWARE. #bit #bit #bit #bit #bit #bit rs = porte.0 enable = porte.1 led1 = portb.2 // led led2 = portb.3 // led ventilador = portc.1 buzzer = porta.5 // // s3 s4 // // via do lcd que sinaliza recepo de dados ou comando enable do lcd controle do ventilador controle do buzzer *

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0; portd = caracter; enable = 1 ; delay_us(1); enable = 0; delay_us(40); }

// // // // //

// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable espera mnimo 40 microsegundos

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1; portd = caracter; enable = 1; delay_us(1); enable = 0; delay_us(40); }

*

// // // // //

// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable espera mnimo 40 microsegundos

Linguagem C para PIC

69

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01); delay_ms (2); }

*

// limpa lcd

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30); delay_ms(4); comando_lcd(0x30); delay_us(100); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de Bips * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void bip(long int tempo, long int periodo) { long int conta_bip; conta_bip = tempo / periodo; while (conta_bip) { buzzer = 1; delay_ms(periodo/2); buzzer = 0; delay_ms(periodo/2); conta_bip--; } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { comando_lcd(0x80); // posiciona o cursor na linha 0, coluna 0 printf (escreve_lcd, "Seleciona Tarefa"); // imprime mensagem no lcd comando_lcd(0xC0); // posiciona o cursor na linha 1, coluna 2 printf (escreve_lcd, " Press Menu "); // imprime mensagem no lcd f_tela_principal = 1; // indica que a tecla foi atualizada time_out = 0; // re-inicia contagem do tempo de time-out } // define varivel local // contabiliza quantas vezes ter // que fazer o loop de bips // faa o loop at acabar o conta_bip

*

// envia comando para inicializar display // espera 4 milisengundos // envia comando para inicializar display // espera 100 microsengundos // envia comando para inicializar display // configura LCD, 8 bits, matriz de 7x5, 2 linhas // limpa lcd // display sem cursor // desloca cursor para a direita

// liga o buzzer // conta tempo para o perodo escolhido // desliga o buzzer // conta tempo para o perodo excolhido // decrementa o conta_bip

*

70 Linguagem C para PIC

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Menu * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_menu() { limpa_lcd(); comando_lcd(0x82); // posiciona o cursor na linha 0, coluna 2 printf (escreve_lcd, "ctr dos leds"); // imprime mensagem no lcd comando_lcd(0xc2); // posiciona o cursor na linha 1, coluna 2 printf (escreve_lcd, "ctr do vent"); // imprime mensagem no lcd } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Seleo de tela aps pressionar a tecla enter * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_ctr_led() { limpa_lcd(); comando_lcd(0x82); // posiciona o cursor na linha 0, coluna 2 printf (escreve_lcd, "ctr dos leds"); // imprime mensagem no lcd comando_lcd(0xc4); printf (escreve_lcd, "ON // posiciona o cursor na linha 1, coluna 4 OFF"); // imprime mensagem no lcd *

if (!led1) { comando_lcd(0xc7); escreve_lcd(0x3e); comando_lcd(0xc3); escreve_lcd(' '); } else { comando_lcd(0xc3); escreve_lcd(0x3e); comando_lcd(0xc7); escreve_lcd(' '); } }

// // // //

posiciona o cursor na linha 1, coluna 7 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 3 envia simbolo "espao" para o lcd

// // // //

posiciona o cursor na linha 1, coluna 3 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 7 envia simbolo "espao" para o lcd

void tela_ctr_ventilador() { limpa_lcd(); comando_lcd(0x83); // posiciona o cursor na linha 0, coluna 3 printf (escreve_lcd, "Ventilador"); // imprime mensagem no lcd comando_lcd(0xc4); printf (escreve_lcd, "ON // posiciona o cursor na linha 1, coluna 4 OFF"); // imprime mensagem no lcd

if (!ventilador) { comando_lcd(0xc7); escreve_lcd(0x3e); comando_lcd(0xc3); escreve_lcd(' '); } else { comando_lcd(0xc3); escreve_lcd(0x3e); comando_lcd(0xc7); escreve_lcd(' '); } }