Curso de Linguagem C

Rinaldo Câmara Gonçalves Labtools – Mosaico Didactic Division Revisão 2

Sumário
SUMÁRIO .....................................................................................................................................................................3 RECURSOS BÁSICOS: EXEMPLO 1 BOTÃO E LED ............................................................................................5 RECURSOS DO LIVRO ..................................................................................................................................................5 LÓGICA DO EXEMPLO ...................................................................................................................................................5 ESQUEMA ELÉTRICO....................................................................................................................................................6 FLUXOGRAMA ..............................................................................................................................................................7 CÓDIGO ......................................................................................................................................................................8 EXERCÍCIOS PROPOSTOS ..........................................................................................................................................10 ANOTAÇÕES ..............................................................................................................................................................11 RECURSOS BÁSICOS: EXEMPLO 2 PISCA – PISCA VARIÁVEL .....................................................................13 RECURSOS DO LIVRO ................................................................................................................................................13 LÓGICA DO EXEMPLO .................................................................................................................................................13 ESQUEMA ELÉTRICO..................................................................................................................................................14 FLUXOGRAMA ............................................................................................................................................................15 CÓDIGO ....................................................................................................................................................................16 EXERCÍCIOS PROPOSTOS ..........................................................................................................................................18 ANOTAÇÕES ..............................................................................................................................................................19 RECURSOS BÁSICOS: EXEMPLO 3 CONTADOR HEXADECIMAL ..................................................................20 RECURSOS DO LIVRO ................................................................................................................................................20 LÓGICA DO EXEMPLO .................................................................................................................................................20 ESQUEMA ELÉTRICO..................................................................................................................................................21 FLUXOGRAMA ............................................................................................................................................................22 CÓDIGO ....................................................................................................................................................................25 EXERCÍCIOS PROPOSTOS ..........................................................................................................................................28 ANOTAÇÕES ..............................................................................................................................................................29 RECURSOS AVANÇADOS: EXEMPLO 4 MAXIMIZAÇÃO DE PINOS DE I/O...................................................30 RECURSOS DO LIVRO ................................................................................................................................................30 LÓGICA DO EXEMPLO .................................................................................................................................................30 ESQUEMA ELÉTRICO..................................................................................................................................................31 FLUXOGRAMA ............................................................................................................................................................32 CÓDIGO ....................................................................................................................................................................36 EXERCÍCIOS PROPOSTOS ..........................................................................................................................................40 ANOTAÇÕES ..............................................................................................................................................................41 RECURSOS AVANÇADOS: EXEMPLO 5 VARREDURA DE DISPLAY .............................................................42 RECURSOS DO LIVRO ................................................................................................................................................42 LÓGICA DO EXEMPLO .................................................................................................................................................42 ESQUEMA ELÉTRICO..................................................................................................................................................44 FLUXOGRAMA ............................................................................................................................................................45 CÓDIGO ....................................................................................................................................................................50 EXERCÍCIOS PROPOSTOS ..........................................................................................................................................57 ANOTAÇÕES ..............................................................................................................................................................58 RECURSOS AVANÇADOS: EXEMPLO 6 CONTROLE DO LCD ............................................................................59 RECURSOS DO LIVRO ................................................................................................................................................59 LÓGICA DO EXEMPLO .................................................................................................................................................59 ESQUEMA ELÉTRICO..................................................................................................................................................60 FLUXOGRAMA ............................................................................................................................................................61 CÓDIGO ....................................................................................................................................................................68 EXERCÍCIOS PROPOSTOS ..........................................................................................................................................76 ANOTAÇÕES ..............................................................................................................................................................77 RECURSOS AVANÇADOS: EXEMPLO 7 CONVERSOR ANALÓGICO DIGITAL..............................................78 RECURSOS DO LIVRO ................................................................................................................................................78 LÓGICA DO EXEMPLO .................................................................................................................................................78 Linguagem C para PIC 3

..........................................................101 RECURSOS DO LIVRO ..............................................................89 FLUXOGRAMA .................................................................................................................................................................................................................................................................................................119 EXERCÍCIOS PROPOSTOS .....................................101 LÓGICA DO EXEMPLO ..............................................114 ANOTAÇÕES ................................................................................................................................................88 ESQUEMA ELÉTRICO...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................ESQUEMA ELÉTRICO....................................................................82 EXERCÍCIOS PROPOSTOS ..........102 FLUXOGRAMA .............80 CÓDIGO ..............................................................................................................................................................................................................................................................................................................................................................................................................116 ESQUEMA ELÉTRICO...................................................................109 EXERCÍCIOS PROPOSTOS ............................................................................................................................................................................................................................................................................................................103 CÓDIGO ................................................................93 EXERCÍCIOS PROPOSTOS .................................................................................................................................................99 ANOTAÇÕES .................116 RECURSOS DO LIVRO ....................................................................................................................................90 CÓDIGO ...................................................................................................................................................................88 RECURSOS DO LIVRO .................................................................................................................................................................121 ANOTAÇÕES .......................................................................87 RECURSOS AVANÇADOS: EXEMPLO 8 CONTROLE DO PWM E EEPROM INTERNA ..................................................116 LÓGICA DO EXEMPLO .....................................101 ESQUEMA ELÉTRICO.........................................................................................................................................................................................................................122 4 Linguagem C para PIC ................118 CÓDIGO .............................................................79 FLUXOGRAMA .........100 RECURSOS AVANÇADOS: EXEMPLO 9 COLETOR DE DADOS .............................................................................................................86 ANOTAÇÕES .........................................................................................................................................................................................................................................88 LÓGICA DO EXEMPLO ...................................................................115 RECURSOS AVANÇADOS: EXEMPLO 10 FUNÇÕES MATEMÁTICAS..........................................117 FLUXOGRAMA ....................................................................................................................................................................................................................................................................................

11.7 do livro Programação em C).5 do livro Programação em C). realiza o teste do botão e determina o caminho a ser seguido.10-pág. comandos de controle de Fluxo (cap. (Se verdadeiro {comando}.Lógica do exemplo Nosso exemplo será composto de um programa capaz de ler um botão e controlar um led.5. 1.170. diretivas de configuração dos pinos de I/O (cap. fundamental já que estamos trabalhando com um microcontrolador. Se falso {comando}).202. cap. 250 do livro Programação em C).7 e cap. se acende ou apaga o led.1 . com o botão S1 liberado o led L2 apaga. Caso o botão esteja pressionado o teste determina que o led deve acender. declaração de variáveis.12. caso contrário o led será apagado. Linguagem C para PIC 5 .2 .6-pág. para botão pressionado temos nível lógico zero no pino de I/O. constantes e tipos de dados (cap. neste caso o teste com o comando IF será verdadeiro para botão pressionado e falso para botão liberado.2-pág. Para o teste do botão está sendo utilizado o operando “!” (NOT). forçando um loop infinito. O comando IF ELSE. 11. (Faça enquanto for verdadeiro) sendo utilizado para o controle de fluxo de nossa rotina principal. 11. Neste exemplo você verá o comando WHILE.Recursos Básicos: Exemplo 1 1. Veremos os primeiros comandos para controle de fluxo de um programa e como ler uma entrada e acionar uma saída. Com o botão S1 pressionado o led L2 acende.Recursos do Livro Botão e Led Para o bom entendimento deste nosso primeiro exemplo são necessários os conhecimentos de programação em linguagem C.

3 .Esquema Elétrico +5V RESET 10K 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 23 24 MC1 MCLR 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 RC6 32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25 +5V +5V RB0 10K RB1 330R +5V S1 L2 4MHz 16F877A 6 Linguagem C para PIC .1.

PRESCALER.1. A LIMPA WATCHDOG NÃO BOTÃO S1 PRESS.Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS. PORTAS.4 . WATCHDOG.? SIM APAGA LED L2 ACENDE LED L2 A Linguagem C para PIC 7 .

//Este programa não utiliza nenhuma constante de usuário /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM.com.nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa.com.LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.wdt.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C .0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * Este software está preparado para demonstrar o controle este primeiro programa demonstrará o estado de um botão * * * * * * * * * * * * * * * * */ dos pinos de I/O por meio de um led.put.brownout.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt. //Este programa não utiliza nenhum flag de usuário /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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 .nocpd.Recursos Básicos de programação * * Exemplo 1 * * * * CENTRO DE CAPACITAÇÃO .nolvp.br * * E-MAIL: cursos@labtools.1. //Este programa não utiliza nenhuma variável de usuário /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção.noprotect.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.5 . /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição das variáveis internas do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.labtools.

portd=0x00. // Estado do botão // 1 -> Liberado // 0 -> Pressionado * * */ e botao = portb. set_tris_c(0b11111111). set_tris_a(0b11111111)./* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware. portc=0x00. portb=0x00. WDT_2304MS). #bit led = portb. // // // // // // configuração dos pinos de I/O limpa limpa limpa limpa limpa porta portb portc portd porte /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { RESTART_WDT(). porte=0x00. porta=0x00. } } // testa botão // Se botão = 0. if(!botao) { led = 1. set_tris_b(0b11111101). set_tris_e(0b00000111).1 // Led correspondente ao botão // 1 -> Led ligado // 0 -> Led desligado * * */ e /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { setup_counters(RTCC_INTERNAL. então led = 1 // caso contrário. led = 0 // FIM DO PROGRAMA 1.6 - Linguagem C para PIC 9 . } else led=0. set_tris_d(0b11111111).0 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // As saídas devem ser associadas a nomes para facilitar a programação //futuras alterações do Hardware.

Com o botão pressionado acenda o led 2 e apague o led 3. Utilize as funções do Compilador para controlar o Led. 10 Linguagem C para PIC . 3.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. 2. seguindo os exercícios propostos: 1. para o botão liberado apague o led 2 e acenda o led 3. Troque o pino de I/O que controla o botão.1. utilize o pino RB3.7 . aproveite para gerar novos problemas e soluções. 4. OUTPUT_HIGH e OUTPUT_LOW. por exemplo. Altere a lógica do programa para que o led acenda com o botão liberado e apague com o botão pressionado.

Anotações Linguagem C para PIC 11 .8 .1.

.

Linguagem C para PIC 13 .Recursos Básicos: Exemplo 2 1. O camando For (inicialização. incremento) é utilizado para controle do laço da rotina de delay. funções do compilador para controle de atraso (cap. sendo a mesma executada fora do laço. pág. Up e Down é possível ajustar a freqüência de oscilação dos Leds 3 e 4 da placa McLab2. máximos e mínimos de ajuste da freqüência de oscilação. 1. Operadores para criação de expressões lógicas e aritméticas (cap.11. complemento de 1). ou seja.4 pág.Recursos do Livro Pisca – Pisca Variável Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos no exemplo 1 e mais. A função delay_ms gera um atraso de milisegundos usando o ciclo de máquina. Para a inversão das portas está sendo utilizado o operador lógico “~”.10.169 do livro Programação em C). 195 do livro Programação em C). com este operando estaremos invertendo bit a bit o conteúdo do registrador portb. diretivas de configuração para uso de função de atraso (cap.6 do livro Programação em C). As constantes min e max determinam os limites. teste condicional.9 . (NOT. o programa fica travado nesta função até o tempo desejado. definindo a quantidades de vezes que o laço será executado. nesta rotina não utilizaremos a opção de inicialização do comando For.10 .Lógica do exemplo A finalidade de nosso exemplo é demonstrar a inversão de portas e a utilização da função de delay da Linguagem C. Através dos botões S1 e S2.

1.11 - Esquema Elétrico

+5V

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

MC1
MCLR 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 RC6
32 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

RB2
330R

RB3
330R

L3

L4

14 Linguagem C para PIC

1.12 - Fluxograma
A MAIN

CONFIGURAÇÕES INICIAIS TRIS, PORTAS, WATCHDOG, PRESCALER.

NÃO

BOTÃO S1 PRESS.?

SIM

INICIALIZA PORTB COM 0X0F B LIMPA WATCHDOG

SIM

TEMPO = MAX?

NÃO

INCREMENTA TEMPO COMPLEMENTA PORTB

A NÃO BOTÃO S2 PRESS.? SIM

SIM

TEMPO = MIN?

NÃO

DECREMENTA TEMPO

CARREGA A VARIÁVEL CONTADOR COM O VALOR DA VARIÁVEL TEMPO

ROTINA DE DELAY LAÇO FOR

B

NÃO

CONTADOR ≠ 0

SIM DELAY (10MS)

Linguagem C para PIC

15

1.13 - Código
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C - Recursos Básicos de programação * * Exemplo 2 * * * * CENTRO DE CAPACITAÇÃO - LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Este software demonstrará a utilização da função de delay e //a frequência de oscilação dos leds é controlada pelos botões * * * * * * * * * * * * */ a inversão de portas S1 (UP) e S2 (DOWN).

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição das variáveis internas do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt // configuração dos fusíveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT) // diretiva para o uso da função delay /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa. int contador = 0 ; int tempo = 9; /* * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * //A definição de constantes facilita a programação //Este programa não utiliza constantes #define max 255 // Limite de ajuste do #define min 10 * * * * * * * * * * * * * * * * * * * * * * * * */ e a manutenção. tempo

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM. //Este programa não utiliza nenhum flag de usuário. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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

// carrega portb com valor inicial /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { RESTART_WDT().contador!=0. set_tris_c(0b11111111).1. portb = ~portb. incrementa tempo botão_0 liberado. tempo é diferente de min? { tempo = tempo . 0x00. // não.1 // Estado do botão_1 // 1 -> Liberado // 0 -> Pressionado * * */ e /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // As saídas devem ser associadas a nomes para facilitar a programação //futuras alterações do hardware. } } // FIM DO PROGRAMA Linguagem C para PIC 17 . * * */ e /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { setup_counters(rtcc_internal.#byte porte = 0x09 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit botao_0 #bit botao_1 * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware. tempo é diferente de max? não. set_tris_e(0b00000111). // carrega contador for (.0 // Estado do botão_0 // 1 -> Liberado // 0 -> Pressionado = portb. testa botão 1 if (!botao_1) // O botão 1 foi pressionado ? { if (tempo != min) // sim. set_tris_d(0b11111111). porta portb portc portd porte = = = = = 0x00. 0x00. set_tris_b(0b11110011). 0x0f. decrementa tempo } } // botão_1 liberado contador = tempo. 0x00. set_tris_a(0b11111111). = portb. // comando: delay de 10 milisegundos.wdt_2304ms). if (!botao_0) // { if (tempo != max) // { tempo = tempo + 1. contador--) // contador é diferente de 0? se sim // decrementa contador e executa o comando delay_ms(10). // } } // // complemanta o portb O botão_0 foi pressionado? sim.

Implemente a inversão de portas para que o led 3 e o led 4 pisquem alternadamente. 18 Linguagem C para PIC . Substitua o comando For pelo comando While. 3. Utilize a forma reduzida para incrementar e decrementar a variável tempo.1. aproveite para gerar novos problemas e soluções. Troque a função delay_ms por delay_us e ajuste as constantes para obter o mesmo ajuste de freqüência. 4. seguindo os exercícios propostos: 1. 2.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido.14 .

Anotações Linguagem C para PIC 19 .1.15 .

309 do livro Programação em C). nossa tabela fará a conversão de BCD para sete segmentos. Desta forma para que o contador seja incrementado ou decrementado o botão deve ser pressionado e depois liberado. para cada botão. Para o devido tratamento dos botões. além do filtro foi criado um flag. que tem a função de indicar se a tecla está pressionada ou liberada. realizando a função de um circuito decodificador.21 pág.Recursos do Livro Contador Hexadecimal Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos nos exemplos anteriores e tabela de constante (cap.Recursos Básicos: Exemplo 3 1. e o seu valor mostrado no display de sete segmentos ds4. será retornado o código de sete segmentos para o número zero e assim por diante.17 . neste exemplo foi implementada uma rotina de filtro para cada botão evitando o problema de debouncing. 20 Linguagem C para PIC . 1. A finalidade de nosso exemplo é demonstrar a implementação de tabelas utilizando a memória de programa. A variável contador será utilizada como indexador da tabela de constante.12. assim sendo para o contador igual à zero.Lógica do exemplo Através dos botões S1 e S2 o contador será incrementado ou decrementado. sendo está tabela uma matriz unidimensional.16 .

18 .1.Esquema Elétrico 220R +5V +5V RESET 10K 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 MC1 MCLR 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 RC6 32 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 DS4 a 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 .

19 .1. INICIALIZA PORTB COM 0X10 B LIMPA WATCHDOG A 22 Linguagem C para PIC .Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS. PRESCALER. PORTAS. WATCHDOG.

A NÃO BOTÃO S1 PRESS.? SIM Re-carrrega o Filtro do Botão Marca botão liberado O botão já estava pressionado ? SIM C NÃO NÃO Filtro ≠ 0 ? Marca Botão pressionado SIM Decrementa o Filtro NÃO Contador ≠ Max ? SIM Incrementa o contador Consulta tabela de conversão e atualiza o display C Linguagem C para PIC 23 .

C NÃO BOTÃO S2 PRESS.? SIM Re-carrrega o Filtro do Botão Marca botão liberado O Botão já estava pressionado ? SIM B NÃO NÃO Filtro ≠ 0 ? Marca Botão pressionado SIM Decrementa o Filtro NÃO Contador ≠ Min ? SIM Decrementa o contador Consulta tabela de conversão e atualiza o display B 24 Linguagem C para PIC .

// inicia contador com mínimo inicia filtro do bot1 inicia filtro do bot2 limpa os flags /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM.1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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 .nocpd. #define t_filtro 400 #define min 0 #define max 15 // tamanho do filtro // valor mínimo para o contador // valor máximo para o contador /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção. // long int filtro1=t_filtro.noprotect.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.1.Recursos Básicos de programação * Exemplo 3 * * CENTRO DE CAPACITAÇÃO . int contador=min. // long int filtro0=t_filtro.com.labtools.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C .wdt.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.br * * E-MAIL: cursos@labtools.nowrt // configuração dos fusíveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000.LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * // // * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Contador hexadecimal que utiliza dois botões para incrementar e decrementar o valor da variável "contador". #bit bt_UP_press = flags. // int flags=0.put.brownout.com. O contador está limitado pelas constantes min e max.0 #bit bt_DOWN_press = flags.20 .nolvp.

5 0b01111101. set_tris_b(0b11101111). // 2H . // 3H . // 4H . // 0H . portd = (tabela[contador]).9 0b01110111.1 0b01011011.3 0b01100110. // seleciona display ds4 portc = 0x00. set_tris_d(0b00000000). set_tris_e(0b00000111). // 8H .C 0b01011110.B 0b00111001.8 0b01101111. // BH .7 0b01111111.F /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_counters(rtcc_internal. // FH .0 #bit botao_DOWN = portb. // DH . // Estado do botão UP // 1 -> Liberado // 0 -> Pressionado * * */ e /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit botao_UP = portb.4 0b01101101.2 0b01001111. // 5H . // EH . /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ byte const tabela[16] = { //PGFEDCBA . POSIÇÃO RELATIVA AOS SEGMENTOS 0b00111111. // 1H . // mostra no display valor inicial do contador porte = 0x00.1 // Estado do botão DOWN // 1 -> Liberado // 0 -> Pressionado * * */ e /* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * As saídas devem ser associadas a nomes para facilitar a programação futuras alterações do hardware. // 7H . // 9H .A 0b01111100. wdt_2304ms). /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 26 Linguagem C para PIC .0 0b00000110. // AH .#byte #byte #byte #byte #byte porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09 * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware. portb=(0b00010000). // CH . // 6H .6 0b00000111. set_tris_a(0b11111111).D 0b01111001. porta = 0x00.E 0b01110001}. set_tris_c(0b11111111).

// Não. if (!(bt_UP_press)) // O botão UP já foi tratato ? { // não. // inicia o filtro do botão 0 bt_UP_press = 0.// consulta tabela. // incia o watch-dog timer /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão 0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao_UP) // O botão UP está pressionado ? { // sim. // não. atualiza // display } } } } else { // botão 1 liberado filtro1 = t_filtro. // marca que o botão está pressionado if (contador != min) { contador--. então decrementa o filtro } else // SIM. // decrementa o contador portd = (tabela[contador]).* Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) // rotina principal { RESTART_WDT(). // inicia o filtro do botão 1 bt_DOWN_press = 0. // incrementa o contador portd = (tabela[contador]). // Marca que o botão está pressionado if (contador != max) { contador++. // marca que o botão foi liberado } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao_DOWN) // testa botão DOWN { // botão DOWN pressionado if (!(bt_DOWN_press)) // o botão DOWN já foi tratato ? { // não if (filtro1 !=0) // Fim do filtro do botão DOWN ? { filtro1--. // consulta tabela. Faz a ação do botão { bt_UP_press = 1. if (filtro0 !=0) // Fim do filtro do botão UP ? { filtro0--. // marca que o botão foi liberado } } } Linguagem C para PIC 27 . Faz a ação do botão { bt_DOWN_press = 1. então decrementa o filtro } else // Sim. atualiza // display } } } } else { // botão 0 liberado filtro0 = t_filtro.

Altere a tabela para que as posições de A a F da tabela apaguem o display. seguindo os exercícios propostos: 1.21 . 28 Linguagem C para PIC . 2. Mude a contagem do dsp4 para o display dsp3. 3.1. 4. Implemente um botão para reset do contador.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. aproveite para gerar novos problemas e soluções. Modifique o programa para que o contador conte de 1 a 5.

1.Anotações Linguagem C para PIC 29 .22 .

Recursos Avançados: Exemplo 4
1.23 - Recursos do Livro

Maximização de Pinos de I/O

Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos nos exemplos anteriores e mais, funções do compilador para controle de interrupção, tratamento automático (cap.12 pág.254 do livro Programação em C), controle do processador (cap.11 pág.223 do livro Programação em C), manipulação de Timers (cap.11.8 pág.211 do livro Programação em C), diretivas de configuração para uso de interrupções, #int_xxx e #priority (cap.10, pág.161 e pág.166 do livro Programação em C).

1.24 - Lógica do exemplo
Nosso exemplo será composto de um programa capaz de ler quatro botões e tocar o buzzer com uma freqüência diferente para cada combinação de botões. Para cada botão existe um led ligado no mesmo pino, que será utilizado para indicar os botões pressionados no momento. Utilizaremos os timers e duas interrupções para controlarmos a freqüência de leitura dos botões e a freqüência do buzzer: • Timer 0: controlará a freqüência de varredura dos botões; • Timer 2: controlará a freqüência do som. O som será feito excitando o buzzer com uma onda quadrada de freqüência variável. Variaremos esta freqüência 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 interrupções. Para a varredura dos botões ajustaremos a interrupção de TMR0 para aproximadamente 500Hz: Ciclo de Máq. 1 µs Prescale 8 Conta TMR0 256 Auxiliar Período 2048 µs Freqüência 488 Hz

Além 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 2048µs. Quanto à freqüência do buzzer, esta será controlada por TMR2. Calibramos os valores de pre e postscale para que a freqüência da interrupção do TMR2 varie entre 100Hz e 2kHz, com a variação de PR2 entre 16 e 240: Ciclo de Máq. 1 µs 1 µs Prescale 16 16 Postscale 1 1 PR2 16 240 Período 256 µs 3840 µs Freqüência 3906 Hz 260 Hz

Para facilitar a implementação, a cada interrupção inverteremos o estado do pino de acionamento do buzzer. Desta forma, a freqüência deste será equivalente à metade da freqüência da interrupção do TMR2. O Livro Conectando o PIC, possui um cápitulo dedicado a este assunto.

30 Linguagem C para PIC

1.25 - Esquema Elétrico

+5V

RESET 10K
1 2 3 4 5 6 7

MC1
MCLR 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 RC6
32 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

CONFIGURAÇÕES INICIAIS TRIS, PORTAS, WATCHDOG, PRESCALER.

LIGA AS INTERRUPÇÕES

LIMPA WATCHDOG

32 Linguagem C para PIC

INTERRUPÇÕES NÃO INT DE TMR0? SIM Trata TMR2 Trata TMR0 TRATA TMR2 NÃO SAÍDA DO BUZZER ESTÁ LIGADA? SIM LIGA A SAÍDA DO BUZZER DESLIGA A SAÍDA DO BUZZER FIM DA INTERRUPÇÃO Linguagem C para PIC 33 .

TRATA TMR0 Convetre pinos dos botões em entradas Delay de 4 ciclos de máquina para estabilização do port Lê todos os botões e guarda em variável temporária (STATUS_BOTÕES) Converte pinos dos botões em saída CHECA BOTÃO S1 NÃO Reinicia Filtro Botão S1 PRESS ? Limpa Flag de botão pressionado (Status Leds) SIM Fim do Filtro ? NÃO SIM Marca flag de botão pressionado CHECA BOTÃO S2 CHECA BOTÃO S3 CHECA BOTÃO S4 A 34 Linguagem C para PIC .

AÇÃO DOS BOTÕES A Atualiza leds conforme botões pressionados NÃO Algum botão pressionado ? SIM Inicializa PER com 255 Consulta tabela conforme conbinação de botões pressionados Deliga interrupção de TMR2 Inicializa TMR2 Desliga a saída do Buzzer Liga Interrupção de TMR2 FIM DA INTERRUPÇÃO Linguagem C para PIC 35 .

int status_leds = 0.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . #define t_filtro 20 // tamanho do filtro /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt. t_filtro.noprotect. int per = 0.labtools.com.brownout.Recursos Básicos de programação * Exemplo 4 * * CENTRO DE CAPACITAÇÃO . além de //indicando a última tecla pressionada. int status_botoes = 0.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.1.put.wdt.nolvp.27 . * * * * * * * * */ * * * * * * * * * * * * * * * * * * */ tocar o buzzer com acender o led /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.nocpd. // armazena o estado lógico dos botões // atualiza leds conforme o botão pressionado // limitador de contagem do Timer2 // // // // inicia inicia inicia inicia filtro filtro filtro filtro do do do do botao1 botao2 botao3 botao4 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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 .br * * E-MAIL: cursos@labtools.LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Este software está preparado para ler quatro botões e //duração variavel conforme a tecla pressionada. int int int int filtro1 filtro2 filtro3 filtro4 = = = = t_filtro. t_filtro. t_filtro.nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção.

192.1 // Estado do botão 2 // 1 -> Liberado // 0 -> Pressionado botao3 = status_botoes.2// Estado do botão 3 // 1 -> Liberado // 0 -> Pressionado botao4 = status_botoes. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuração do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // A rotina principal simplesmente limpa o WDT.64. set_tris_d(0b11111111). enable_interrupts(GLOBAL). porte=(0b00000000).112.96. set_tris_a(0b11011111). set_tris_c(0b11111111).160.176. set_tris_e(0b00000111).1 status_leds.1). portd=(0b00000000).0 // Estado do botão 1 // 1 -> Liberado // 0 -> Pressionado botao2 = status_botoes.2 status_leds. portc=(0b00000000).timer2 // prioridade para a int de trm0 Linguagem C para PIC 37 .0 status_leds.3 // Estado do botão 4 // 1 -> Liberado // 0 -> Pressionado * * */ E #bit #bit #bit /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SAÍDAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAÇÃO //FUTURAS ALTERAÇÕES DO HARDWARE.240}.80.128.224.3 buzzer = porta.144. #bit #bit #bit #bit #bit botao1_press botao2_press botao3_press botao4_press = = = = status_leds. setup_timer_2 (t2_div_by_16. pois toda a lógica do // programa é tratada dentro das interrupções.5 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ byte const tabela[16] = {255. set_tris_b(0b11110000). rtcc_div_8). portb=(0b00000000). void main() { setup_adc_ports (no_analogs). porta=(0b00000000). #priority timer0.48. * * */ e botao1 = status_botoes.16.32. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware.208./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM. enable_interrupts(INT_RTCC). setup_counters(rtcc_internal .per.

} /* * * * * * * * * * * * * * * * * * * * * Tratamento do * * * * * * * * * * * * * * * * * * * * if (!botao3) { // // // // testa botão 2 botão 2 está pressionado ? Sim. salvar a condição dos botões em variável temporária e converter os pinos em saída novamente. então decrementa o filtro acabou o filtro do botão 1 ? // marca que o botão está pressionado // botão 1 liberado // inicia o filtro do botão 1 // marca que o botão foi liberado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão 2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao2) { filtro2--. salva em variável // temporária // configura os pinos como saída para // controle dos leds /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao1) { filtro1--. if (filtro2 == 0) { botao2_press = 1. O filtro dos botões tem duração de 40ms (2048us x 20) e são decrementados a cada interrupção. botao2_press = 0. // incia o watch-dog timer } } /* * * // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupção de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Esta interrupção ocorrerá a cada 2048us. #int_rtcc void trata_int_tmr0() { set_tris_b(0b00001111). status_botoes = portb. } // // // // testa botão 1 botão 1 está pressionado ? Sim. } } else { filtro1 = t_filtro. set_tris_b(0b00000000). delay_cycles(4). if (filtro1 == 0) { botao1_press = 1./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) // rotina principal { RESTART_WDT(). botao1_press = 0. // configura os pinos como entrada para // testar os botões // aguarda 4 ciclos de máquina para a // estabilização do portb // lê o status dos botoes. } } else { filtro2 = t_filtro. então decrementa o filtro fim do filtro do botão 2 ? // marca que o botão está pressionado // botão 2 liberado // inicia o filtro do botão 2 // marca que o botão foi liberado * * * * * * * * * * * * * * * * Botão 3 * * * * * * * * * * * * * * * * */ // testa botão 3 // botão 3 está pressionado ? 38 Linguagem C para PIC . Esta interrupção é responsável por converter os pinos dos botões em entrada.

// atualiza os leds if (status_leds == 0) { per = 0xff. #int_timer2 void trata_int_tmr2() { if (buzzer != 0) // o buzzer está ligado ? { buzzer = 0. setup_timer_2 (t2_div_by_16. então liga } } Linguagem C para PIC 39 . } } else { filtro3 = t_filtro. } } else { filtro4 = t_filtro. // sim. então decrementa o filtro // fim do filtro do botão 4 ? // marca que o botão está pressionado // botão 4 liberado // inicia o filtro do botão 4 // marca que o botão foi liberado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Atualiza Leds conforme botões pressionados * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ portb = status_leds. então decrementa o filtro // fim do filtro do botão 3 ? // marca que o botão está pressionado // botão 3 liberado // inicia o filtro do botão 3 // marca que o botão foi liberado * * * * * * * * * * * * * * * * Botão 4 * * * * * * * * * * * * * * * * */ // testa botão 4 // botão 4 está pressionado ? // Sim.1).per.1). if (filtro4 == 0) { botao4_press = 1. botao3_press = 0. // habilita interrupção de timer2. // não. então desliga } else { buzzer = 1. } /* * * * * * * * * * * * * * * * * * * * * Tratamento do * * * * * * * * * * * * * * * * * * * * if (!botao4) { filtro4--.// consulta tabela e inicializa timer2. enable_interrupts (INT_TIMER2). setup_timer_2 (t2_div_by_16.per. botao4_press = 0. // o periodo de ocorrência depende do botão ou da conbinação de botões pressionados. // ela irá inverter o pino de I/O do buzzer a cada interrupção.filtro3--. } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupção de TMR2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Está interrupção só irá ocorrer quando alguma tecla estiver pressionada. buzzer = 0. } // Sim. if (filtro3 == 0) { botao3_press = 1. } else { per = (tabela[status_leds]). disable_interrupts (INT_TIMER2).

Utilize as funções disponíveis do Compilador para inverter o estado do buzzer. 2.28 .Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. aproveite para gerar novos problemas e soluções. conforme a tabela abaixo.1. os botões pares controlam os leds impares e os botões impares controlam os leds pares. seguindo os exercícios propostos: 1. Botão 1 Botão 2 Botão 3 Botão 4 Led 2 Led 1 Led 4 Led3 40 Linguagem C para PIC . Modifique o controle dos leds.

29 .1.Anotações Linguagem C para PIC 41 .

um temporizador capaz de contar até 9.11. introdução de código em assembly no programa em C (cap. Na verdade. A primeira tecla (S1) não possui nenhuma função. os botões alteram diretamente o valor da unidade.254 do livro Programação em C). manipulação de Timers (cap. diretivas de configuração para uso de interrupções.10.31 . Outra característica destes botões é que eles executam suas funções repetidamente quando mantidos pressionados e só funcionam quando o temporizador está paralisado. tratamento manual (cap. 1.12 pág.11 pág.retorno de valores em funções assembly (cap. utilizaremos os displays para indicar o valor atual do temporizador. 1 µs 42 Linguagem C para PIC Prescale 1 Conta TMR0 256 Auxiliar - Período 256 µs Freqüência 3900 Hz .211 do livro Programação em C).147 do livro Programação em C). comutam automaticamente entre 0000 e 9999. #int_global e #priority (cap.223 do livro Programação em C). controle do processador (cap. funções do compilador para controle de interrupção.9. Ajustamos seus parâmetros para que a comutação entre displays (tempo da interrupção) seja de aproximadamente 4kHz: Ciclo de Máq.151 do livro Programação em C). o led relacionado a ela (L1) será utilizado para indicar o estado do temporizador: L1 Aceso Apagado Descrição Temporizador em contagem regressiva Temporizador paralisado Os demais botões apresentam as funções de controle do temporizador: Botão S2 S3 S4 Descrição Incrementa o valor inicial em 1 segundo Decrementa o valor inicial em 1 segundo Inicia e paralisa o temporizador Os botões de incremento e decremento operam de forma rotativa.10. Trata-se de um contador regressivo de segundos. A lógica do sistema compara este valor com os limites (0 e 9) para alterar ou não os demais dígitos.Recursos Avançados: Exemplo 5 1. Estas variáveis representam o valor atual do temporizador e são incrementadas e decrementadas através dos botões.162 e pág. CENTENA e MILHAR.166 do livro Programação em C). DEZENA. ou seja. A freqüência de varredura é controlada pela interrupção de Timer0. isto é.8 pág.Recursos do Livro Varredura de Display Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos nos exemplos anteriores e mais.999 segundos.Lógica do exemplo O exemplo desenvolvido para esta aula faz muito mais que simplesmente implementar a varredura dos displays. Ao atingir o valor zero (0000) o temporizador é automaticamente paralisado.30 . Por outro lado. pág. Para isso. Para o sistema de varredura foram criadas 4 variáveis para armazenamento dos dígitos mostrados nos respectivos displays: UNIDADE. desligandose o led indicativo (L1). pág. pág.

A prioridade de tratamento da interrupção depende da seqüência de teste dos flags de int. limpar os flags de indicação de interrupção e criar os registradores para as rotinas de salvar e restaurar contexto. Para este tipo de tratamento estamos utilizando a diretiva #int global. Cada vez que o sistema entrar na interrupção de TMR1 e o contador auxiliar (DIVISOR_TMR1) terminar. utilizamos a interrupção de Timer1 para esta finalidade. Linguagem C para PIC 43 . que também é de responsabilidade do programador.5 segundo. configuramos o prescale de TMR1 em 1:8 e iniciamos o contador com o valor total menos o desejado para a contagem (65. Dentro do tratamento da interrupção de TMR0 é desligado o display atual. Quando o tempo termina (0000) tanto o led quanto o TMR1 são desligado.000 µs Freqüência 1 Hz Para isso. Veja os ajustes dos parâmetros para esta interrupção: Ciclo de Máq. Desta maneira a interrupção acontecerá a cada 0.536 – 62. tais como: salvar contexto. Quanto à contagem dos segundos. Neste exemplo está sendo utilizado o tratamento Manual de interrupções.000. começando pela unidade e chegando até a milhar. restaurar contexto.500). carregado o valor do dígito correspondente ao display e ligado o display seguinte. neste modo nós devemos providenciar todo o código necessário para o tratamento da interrupção.A freqüência de varredura será a freqüência de comutação dividida pelo número de displays. que no nosso caso será de aproximadamente 1kHz. 1 µs Prescale 8 Conta TMR1 62500 Auxiliar 2 Período 1. se for necessário. o tempo é decrementado. Para podermos contar 1 segundo foi criado uma variável auxiliar denominada DIVISOR_TMR1.

1.7K MC1 MCLR 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 RC6 32 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 RB0 330R 10K 10K 10K RB1 S2 L1 RB2 S3 RB3 S4 44 Linguagem C para PIC .7K 4.7K 4.32 .7K 4.Esquema Elétrico 220R a b c d e f g Dp DS1 a f e d g b c Dp f e d DS2 a g b c Dp f e DS3 a g b c d Dp f e DS4 a g b c d Dp 220R Comum 1 BC337 Comum 2 BC337 Comum 3 BC337 Comum 4 BC337 +5V +5V RESET 10K 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 4.

PRESCALER.? SIM Trata Botão Down NÃO BOTÃO Start/Stop PRESS. PORTAS.1. Configura Timer1 Liga as interrupções A Limpa WATCHDOG BOTÃO UP PRESS.? SIM Trata Botão UP NÃO BOTÃO DOWN PRESS.33 .Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS. WATCHDOG.? SIM Trata Botão Start/Stop NÃO Recarrega Filtro e turbo das teclas Linguagem C para PIC 45 .

consulta tabela de conversão para sete segmentos. consulta tabela de conversão para sete segmentos. NÃO SIM Passou 1 segundo ? NÃO Atualiza Display da Dezena? SIM Incrementa ponteiro de seleção de Display. liga display da centena Decrementa Timer NÃO Timer Chegou a zero? NÃO Atualiza Display do milhar? SIM Zera ponteiro de seleção de Display. liga display da unidade Atualiza Display da Unidade? decrementa contador de int.INTERRUPÇÕES NÃO INT DE TMR0? SIM SWITCH CASE Recarrega Timer1 Incrementa ponteiro de seleção de Display. desliga display da centena. desliga display da dezena. consulta tabela de conversão para sete segmentos. consulta tabela de conversão para sete segmentos. liga display do milhar NÃO SIM Desliga led de indicação de timer operando FIM DA INTERRUPÇÃO Desabilita interrupção de Timer1 FIM DA INTERRUPÇÃO 46 Linguagem C para PIC . desliga display do milhar. liga display da dezena SIM NÃO Recarrega contador de int. Atualiza Display da Centena? SIM Incrementa ponteiro de seleção de Display. desliga display da unidade.

Trata Botão UP Trata Botão DOWN Timer Ligado ? SIM Timer Ligado ? SIM NÃO NÃO Decrementa Filtro Decrementa Filtro NÃO Fim do Filtro ? Fim do Filtro ? NÃO SIM SIM Decrementa Turbo Decrementa Turbo Fim do Temporizador para Turbo do Botão? NÃO Fim do Temporizador para Turbo do Botão? NÃO SIM SIM Recarrega temporizador para Turbo Recarrega temporizador para Turbo Incrementa Timer Decrementa Timer A A Linguagem C para PIC 47 .

Trata botão Start/Stop SIM Ação já foi executada ? NÃO NÃO Filtro terminou ? SIM NÃO Timer ligado ? SIM SIM Timer é igual a zero ? Apaga led de indicação de Timer ligado NÃO Desabilita interrupção de Timer1 Acende Led de indicação de Timer ligado Carrega Timer1 A Carrega contador de interrupções Habilita interrupção de Timer 1 A 48 Linguagem C para PIC .

Incrementa Timer Decrementa Timer Incrementa unidade Decrementa unidade NÃO Unidade = 10 ? Unidade = 0XFF ? NÃO SIM SIM Zera unidade Incrementa dezena Unidade = 9 Decrementa dezena NÃO Dezena = 10 ? Dezena = 0XFF ? NÃO SIM SIM Zera dezena Incrementa centena Dezena = 9 Decrementa centena NÃO centena = 10 ? centena = 0XFF ? NÃO SIM SIM Zera centena Incrementa milhar Centena = 9 Decrementa milhar NÃO Milhar = 10 ? Milhar = 0XFF ? NÃO SIM Zera milhar SIM Milhar = 9 Return Return Linguagem C para PIC 49 .

turbo = 1. int int int INT W_TEMP. #define t_filtro 250 // tamanho do filtro #define turbo_tecla 60 #define delta_timer1 (65536 . Consiste num temporizador de segundos. filtro = t_filtro. PCLATH_TEMP.nocpd.com. contador = 2. dezena = 9.h> // microcontrolador utilizado #include /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.put.br * E-MAIL: cursos@labtools. Quando o sistema chega a 0000 (ZERO) o led é desligado automaticamente. milhar = 9. centena = 9. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ <16f877A.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi preparado para demonstrar o funcionamento do TIMER de 16 bits do PIC (TMR1).1.62500) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa.noprotect. O temporizador consegue contar até 9999 segundos. da varredura de displays e do tratamento manual de int. de forma que os 4 displays de 7 segmentos foram necessários. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção.34 .nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000.LABTOOLS * * TEL: (0XX11) 4992-8775 SITE: www.Código /* * * * * * * * * * * * /* * * // // // // // // // // /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . um led indica que o temporizador está operando. // atualiza os displays // contador de interrupções de timer1 // inicia filtro dos botões // inicia turbo das teclas // variável unidade do timer de 1 seg // variável dezena do timer de 1 seg // variável centena do timer de 1 seg // variável milhar do timer de 1 seg // variáveis para salvar contexto static static static static 50 Linguagem C para PIC .Recursos Básicos de programação * Exemplo 5 * * CENTRO DE CAPACITAÇÃO .wdt. dois botões foram utilizados para programar o tempo da contagem. Um outro botão foi utilizado para disparar o contador.labtools. A contagem é regressiva. STATUS_TEMP. FSR_TEMP.com.nolvp. int int int int int int int int display = 0 . unidade = 9.brownout.

3 // Estado do botão start_stop // 1 -> Liberado // 0 -> Pressionado * * */ E /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SAÍDAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAÇÃO //FUTURAS ALTERAÇÕES DO HARDWARE.0 // led de estado do timer // 1 -> timer contando // 0 -> timer parado // seleção do display unidade (0) // seleção do display dezena // seleção do display centena (2) // seleção do display milhar (3) #bit #bit #bit #bit disp0 disp1 disp2 disp3 = portb.4 = portb.1 #bit bt_down = portb.0 // tmr1ie é #byte status = 0x03 // define endereço #byte fsr = 0x04 // define endereço #byte pclath = 0x0a // define endereço /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM. // Estado do botão up // 1 -> Liberado // 0 -> Pressionado // Estado do botão down // 1 -> Liberado // 0 -> Pressionado * * */ e bt_up = portb.7 (1) Linguagem C para PIC 51 .6 = portb./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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 /* * * * * * * * * * * * * * * * * * * * * * * * * * * Definição de SFR's * * * * * * * * * * * * * * * * * * * * * * * * * * #bit tmr1if = 0x0c. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware.0 // tmr1if é #bit t0if = 0x0b. #bit estado_timer = portb.5 = portb.2 // t0if é o #bit tmr1ie = 0x8c.2 #bit bt_start_stop = portb.

} } /* * * * * * * * * * * * * * Função * * * * * * * * * * * * * incrementa_timer() { unidade ++. dezena ++. centena --.9 // blank * * * * * * * * * * * * * * * * * * * * * * * de decremento do Timer * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * de incremento do Timer * * * * * * * * * * * * * * * * * * * * * * * */ 52 Linguagem C para PIC .7 // 8H .8 // 9H .4 // 5H .0 // 1H . milhar --. dezena --. } if (milhar == 10) { milhar = 0. 0b00000000}. } if (centena == 0xff) { centena = 9. } if (milhar == 0xff) { milhar = 9.2 // 3H . 0b01101111. 0b01111101./* * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * byte const converte[11] = { //PGFEDCBA 0b00111111. milhar ++. if (unidade == 10) { unidade = 0. 0b01101101. 0b01100110. } if (dezena == 0xff) { dezena = 9. } } * * * * * * * * * * * * * * * * * * * * * * * * * * */ POSIÇÃO RELATIVA AOS SEGMENTOS // 0H .3 // 4H . 0b01011011. } if (dezena == 10) { dezena = 0.5 // 6H . 0b00000111. /* * * * * * * * * * * * * * Função * * * * * * * * * * * * * decrementa_timer() { unidade --.6 // 7H . 0b00000110. if (unidade == 0xff) { unidade = 9. 0b01111111. centena ++. } if (centena == 10) { centena = 0. 0b01001111.1 // 2H .

// liga o display 0 break. // // incrementa a variável de varredura desliga o display 0 // atualiza o portd liga o display 1 sai incrementa a variável de varredura desliga o display 1 // atualiza o portd liga o display 2 sai inicia a variável de varredura desliga o display 2 // atualiza o portd liga o display 3 sai Linguagem C para PIC 53 . // desliga o display 3 portd = (converte[unidade]). // decrementa contador de interrupções if (contador == 0) { set_timer1(delta_timer1). // portd = (converte[dezena]). // break. disp1 = 1. // desliga tratamento de interrupção de timer1 } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupção de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupção ocorrerá a cada 256us.5 segundos. // sai case 1: display++. // carrega contador de int decrementa_timer(). // carraga timer1 contador = 2. // case 3: display disp2 = portd = disp3 = break. // disp0 = 0. // 0. disp2 = 1. // case 2: display++. 1. #inline trata_tmr0() { t0if = 0. if((unidade==0)&&(dezena==0)&&(centena==0)&&(milhar==0))// timer está zerado? { estado_timer = 0. // incrementa a variável de varredura disp3 = 0. #inline trata_tmr1() { set_timer1(delta_timer1). switch(display) // início da varredura dos display´s { case 0: display++. // portd = (converte[centena]). // (converte[milhar]). apaga o led e tmr1ie = 0. // carraga timer1 tmr1if = 0. // break. // atualiza o portd disp0 = 1./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função de tratamento de interrupção de Timer1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupção ocorrerá a cada 0. // limpa flag de interrupção contador --. // sim. a rotina de tratamento é executada a // cada 2 interrupções (contador). } } = 0. // disp1 = 0.

set_tris_e(0b00000111). SWAPF STATUS_TEMP. // rotina principal // incia o watch-dog timer 54 Linguagem C para PIC . setup_counters(rtcc_internal. enable_interrupts(INT_RTCC ). /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(TRUE) { RESTART_WDT(). set_tris_b(0b00001110). setup_timer_1 (t1_internal | t1_div_by_8).W MOVWF FSR_TEMP // SALVA REGISTRADOR FSR MOVF PCLATH. SELECIONA PAGINA 0 CLRF STATUS // LIMPA REGISTRADOR STATUS #endasm } /* * * * * * * * * * * * * * * * * * * * * * * * * * Função para restaurar contexto * * * * * * * * * * * * * * * * * * * * * * * * * restaura_contexto() { #asm MOVF PCLATH_TEMP. set_tris_c(0b11111111). portb=(0b00000000).W MOVWF PCLATH_TEMP // SALVA REGISTRADOR PCLATH CLRF PCLATH // LIMPA REGISTRADOR PCLATH.F SWAPF W_TEMP./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para salvar contexto * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ salva_contexto() { #asm MOVWF W_TEMP // SALVA REGISTRADOR DE TRABALHO E SWAPF STATUS.W MOVWF FSR // RECUPERA REG. portd=(0b00000000). INDIRETO) STATUS WORK /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuração do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs).W MOVWF STATUS // RECUPERA REG. porte=(0b00000000).W // DE STATUS DURANTE O TRATAMENTO MOVWF STATUS_TEMP // DA INTERRUPÇÃO.W // RECUPERA REG. MOVF FSR. portc=(0b00000000). set_tris_d(0b00000000). MOVF FSR_TEMP.W MOVWF PCLATH // RECUPERA REG. wdt_2304ms). enable_interrupts(GLOBAL). set_tris_a(0b11111111). #endasm } * * * * * * * * * * * * * * * * * * * * * * */ PCLATH (PAGINAÇÃO) FSR (END. SWAPF W_TEMP. porta=(0b00000000).

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

trata tmr0 // não. } /* * * // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função de Tratamento de interrupções * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Todo o tratamento de interrupção é feito manualmente. trata tmr1 } } // não. // carrega timer 1 tmr1if = 0. // liga o tratamento de interrupção de timer1 } } } } goto loop. { if (tmr1if) // É int de tmr1 ? { trata_tmr1(). As funções salva contexto e restaura contexto foram feitas em assembler Observe que a prioridade das interrupções é realizada através do comando IF e a ordem do teste determina a prioridade no tratamento da interrupção. } 56 Linguagem C para PIC . o timer está ligado ? { estado_timer = 0. indica que o timer está contando contador = 2. // desliga o tratamento de interrupção de timer1 } else { if((unidade!=0)||(dezena!=0)||(centena!=0)||(milhar != 0)) // timer está zerado? { estado_timer = 1. // indica timer parado tmr1ie = 0.// salva os registradores antes do tratamento da int if (t0if) { trata_tmr0(). // restaura contexto e sai da int. // carrega contador auxiliar set_timer1(delta_timer1). // limpa flag de int tmr1 tmr1ie = 1.// não. restaura_contexto(). // decrementa o filtro if (filtro == 0) // fim do filtro do botão? { if (estado_timer != 0) // sim. #int_global Void trata_int() { salva_contexto().//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_start_stop: if (filtro != 0) // o timer está parado? { filtro --. } else // É int de tmr0 ? // sim. // sim.

2. Altere a rotina de temporização para que o timer seja decrementado a cada 1 minuto. 3. seguindo os exercícios propostos: 1. aproveite para gerar novos problemas e soluções.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. Mude a rotina do timer para que ele funcione como um cronômetro com um botão de start e um de reset. Mude a rotina para que o temporizador conte de forma crescente e desligue quando chegar a zero.1. Linguagem C para PIC 57 .35 .

Anotações 58 Linguagem C para PIC .1.36 .

pressione a tecla enter para entrar na tela de controle. pressionando a tecla menu é possível escolher entre controle de leds e controle do ventilador. tecla S1. de escolha de opções. Após 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 opções de controle.Recursos do Livro Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos no exemplo 1 e mais.2 pág. quando a tecla for pressionada o símbolo “>” será deslocado para a condição desejada.Lógica do exemplo Este exemplo foi criado para demonstrar a inicialização de LCD de 2 linhas por 16 caracteres utilizando 8 vias de dados. Linguagem C para PIC 59 . A escolha das telas será controlada pelo comando SWITCH do compilador C. onde será possível escolher as opções de ligar ou desligar através da tecla ENTER. deve se pressionar enter para escolher a opção desejada. 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. 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. e como enviar dados e comandos para o LCD. controle do LCD (cap. ON ou OFF. tecla S2.38 .37 . O controle selecionado é indicado por uma seta . O exemplo controla o acionamento de leds e do ventilador através de um MENU. 1.Recursos Avançados: Exemplo 6 Controle do LCD 1.12. 310 do livro Programação em C).7.

1.7K 60 Linguagem C para PIC MINI VENTILADOR BC337 .Esquema Elétrico +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/W 4 10K RS EN LCD +5V RESET 10K MC1 MCLR 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 RC5 2 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 +5V VDD 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.39 .

PRESCALER. W ATCHDOG.? SIM Trata Botão ENTER NÃO Recarrega Filtro dos Botões Linguagem C para PIC 61 .? SIM Trata Botão Menu NÃO BOTÃO ENTER PRESS. Configura Timer0 Inicializa LCD Tela principal Habilita as interrupções A Limpa W ATCHDOG Escreve tela principal ? SIM Tela principal NÃO BOTÃO MENUPRESS.Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS.1. PORTAS.40 .

NÃO Controle do T ime .INT ERRUPÇÕ ES Declara Variáveis locais Incrementa contador de interrupções Temp1 = 40 SIM NÃO Zera contador de interrupções 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. NÃO FIM DA INT ERRUPÇÃO 62 Linguagem C para PIC . limpa o flag "f_tela_principal". Se não: Apaga o led 2. após 5 segundos. para liberar atualização da tela principal.out da tela principal SIM Incrementa contador de time out.

Trata Botão MENU Ação já foi executada ? SIM NÃO Decrementa Filtro SIM Fim do Filtro ? NÃO SIM Contador de Tela < 2 NÃO Posiciona a seta na linha 0. coluna 0 do LCD A Linguagem C para PIC 63 . coluna 0 do LCD Posiciona a seta na linha 1.

Trata Botão ENTER Ação já foi executada ? SIM NÃO Decrementa Filtro SIM Fim do Filtro ? NÃO Carrega a tela de seleção de tarefa: Controle dos Leds ou Controle do Ventilador Re-inicia time-out A 64 Linguagem C para PIC .

Linguagem C para PIC 65 .

Seleção da Tela de Menu Switch Case SIM Tela 1 do Menu ? NÃO Posiciona a seta na linha 0 coluna 0 SIM Tela 2 do Menu NÃO Posiciona a seta na linha 1 coluna 0 Return Beep Fim do loop do Beep ? (conta beep) SIM NÃO Return Liga Beep Delay Desliga Beep Delay Decrementa conta beep 66 Linguagem C para PIC .

Seleção da Tela de Enter Switch Case SIM Tela 1 do Enter ? Carrega a tela de controle de leds. Carrega contador para tela 3 NÃO SIM Tela 2 do Enter Carrega a tela de controle do Ventilador Carrega contador para tela 4 NÃO SIM Tela 3 do Enter Indica estado dos leds On ou Off emite beep. NÃO SIM Tela 4 do Enter NÃO Indica estado do ventilador On ou Off emite beep Return A Linguagem C para PIC 67 .

LABTOOLS * * TEL: (0XX11) 4992-8775 SITE: www.41 . o botão Enter seleciona a tarefa e funciona como controle de liga/desliga para a tarefa selecionada.h> // microcontrolador utilizado /* * * * * // O //os //de #include /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.nocpd. o botão Menu seleciona a tarefa que desejamos executar (controle de Leds ou do Ventilador).brownout. // variaveis para a rotina de int de Timer0 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) 68 Linguagem C para PIC . Foi criada uma rotina para escrever comandos e uma para escrever caracteres. sem a necessidade redigitação.1. #define t_filtro 500 // tamanho do filtro /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi elaborado para explicar o funcionamento do módulo de LCD.wdt.com.Recursos Básicos de programação * Exemplo 6 * * CENTRO DE CAPACITAÇÃO .Código /* * * * * * * * * * * * /* * * // // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . // contador para seleção de tela int time_out = 0. // registrador de flags int contador_tela = 0.nolvp.noprotect.labtools.nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000.put.temp2. // registrador para contagem de tempo de time-out int contador. existe também uma rotina de inicialização necessária para a correta configuração do LCD. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção. // inicia filtro dos botões int flags1 = 0.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ arquivo de definições do pic utilizado deve ser referenciado para que nomes definidos pela Microchip possam ser utilizados.br * E-MAIL: cursos@labtools.temp1. long int filtro = t_filtro. <16f877A. Os botões S1 e S2 são respectivamente botão Menu e Enter.

} * // // // // // // 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 mínimo 40 microsegundos Linguagem C para PIC 69 . enable = 0. delay_us(1).1 buzzer = porta. portd = caracter. } // // // // // // 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 mínimo 40 microsegundos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1.1 led1 = portb. delay_us(40). enable = 1 . enable = 1.2 // led led2 = portb.#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 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM.0 #bit enter = portb.3 // led ventilador = portc. #bit #bit #bit #bit #bit #bit rs = porte.0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware. delay_us(1).5 // // s3 s4 // // via do lcd que sinaliza recepção 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. delay_us(40).1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // AS SAÍDAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAÇÃO E //FUTURAS ALTERAÇÕES DO HARDWARE. portd = caracter. enable = 0. #bit f_tela_principal = /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit menu flags1. // Estado do botão menu // 1 -> Liberado // 0 -> Pressionado // Estado do botão enter // 1 -> Liberado // 0 -> Pressionado = portb.0 enable = porte.

// imprime mensagem no lcd f_tela_principal = 1. delay_ms (2). // posiciona o cursor na linha 0. } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função de Bip´s * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void bip(long int tempo. 8 bits. delay_us(100). conta_bip--. comando_lcd(0x30). // posiciona o cursor na linha 1. // indica que a tecla foi atualizada time_out = 0. comando_lcd(0x06). matriz de 7x5. 2 linhas // limpa lcd // display sem cursor // desloca cursor para a direita // liga o buzzer // conta tempo para o período escolhido // desliga o buzzer // conta tempo para o período excolhido // decrementa o conta_bip * 70 Linguagem C para PIC . // imprime mensagem no lcd comando_lcd(0xC0). delay_ms(4). comando_lcd(0x30). long int periodo) { long int conta_bip. } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { comando_lcd(0x80). buzzer = 0. // re-inicia contagem do tempo de time-out } // define variável local // contabiliza quantas vezes terá // que fazer o loop de bip´s // faça 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. coluna 0 printf (escreve_lcd. coluna 2 printf (escreve_lcd. delay_ms(periodo/2). comando_lcd(0x0c). } * // limpa lcd /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicialização do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30). conta_bip = tempo / periodo. limpa_lcd()./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01). "Seleciona Tarefa"). delay_ms(periodo/2). " Press Menu "). comando_lcd(0x38). while (conta_bip) { buzzer = 1.

// imprime mensagem no lcd comando_lcd(0xc2). comando_lcd(0xc3). escreve_lcd(' '). printf (escreve_lcd. "ctr dos leds"). } } // // // // posiciona o cursor na linha 1. escreve_lcd(' '). coluna 2 printf (escreve_lcd. coluna 4 OFF"). // imprime mensagem no lcd if (!ventilador) { comando_lcd(0xc7). "ctr do vent"). printf (escreve_lcd. comando_lcd(0xc7). coluna 2 printf (escreve_lcd. escreve_lcd(0x3e). comando_lcd(0xc3). } else { comando_lcd(0xc3). coluna 7 envia simbolo " " para o lcd Linguagem C para PIC 71 . // imprime mensagem no lcd comando_lcd(0xc4). coluna 3 printf (escreve_lcd. "ctr dos leds"). coluna 3 envia simbolo "espaço" para o lcd // // // // posiciona o cursor na linha 1. coluna 3 envia simbolo "espaço" para o lcd // // // // posiciona o cursor na linha 1. escreve_lcd(' '). comando_lcd(0x83). coluna 4 OFF"). escreve_lcd(0x3e). coluna 2 printf (escreve_lcd. // posiciona o cursor na linha 1. coluna 7 envia simbolo "maior" para o lcd posiciona o cursor na linha 1. escreve_lcd(0x3e). coluna 3 envia simbolo "maior" para o lcd posiciona o cursor na linha 1./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Menu * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_menu() { limpa_lcd(). coluna 7 envia simbolo "maior" para o lcd posiciona o cursor na linha 1. // posiciona o cursor na linha 0. comando_lcd(0x82). comando_lcd(0x82). "ON // posiciona o cursor na linha 1. } } // // // // posiciona o cursor na linha 1. "Ventilador"). escreve_lcd(' '). coluna 7 envia simbolo "espaço" para o lcd void tela_ctr_ventilador() { limpa_lcd(). coluna 3 envia simbolo "maior" para o lcd posiciona o cursor na linha 1. } else { comando_lcd(0xc3). // imprime mensagem no lcd * if (!led1) { comando_lcd(0xc7). // posiciona o cursor na linha 0. // imprime mensagem no lcd } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Seleção de tela após pressionar a tecla enter * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_ctr_led() { limpa_lcd(). escreve_lcd(0x3e). // posiciona o cursor na linha 0. // imprime mensagem no lcd comando_lcd(0xc4). comando_lcd(0xc7). "ON // posiciona o cursor na linha 1.

// posiciona o cursor na escreve_lcd(0x3e). // acende o led bip(50.// envia simbolo "maior" comando_lcd(0xc3). comando_lcd(0x80). bip(50. // posiciona o cursor na linha 1.// envia simbolo "maior" comando_lcd(0xc7). // envia simbolo "seta" para o lcd break. // envia simbolo "seta" para o lcd break.2). coluna 0 escreve_lcd(0x7e). // retorna case 2: tela_menu(). // retorna da função } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Seleção das telas após pressionar Enter * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void sel_tela_enter() { switch(contador_tela) { case 1: tela_ctr_led().// envia simbolo "espaço" } else { led1 = 0.2). coluna 7 para o lcd linha 1. coluna 3 para o lcd linha 1. delay_ms(250)./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Seleção das telas de Menu * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void sel_tela_menu() { switch(contador_tela) { case 1: tela_menu(). comando_lcd(0xc0). // apaga o led comando_lcd(0xc7). * // retorna da função // retorna da função case 3: if (!led1) { led1 = 1. contador_tela = 4. break.// posiciona o cursor na escreve_lcd(' '). coluna 3 para o lcd 72 Linguagem C para PIC . break. } break.// envia simbolo "espaço" bip(50. coluna 7 para o lcd linha 1. // posiciona o cursor na linha 0. // retorna da função linha 1. contador_tela = 3. case 2: tela_ctr_ventilador().// posiciona o cursor na escreve_lcd(' '). comando_lcd(0xc3).2).// posiciona o cursor na escreve_lcd(0x3e). coluna 0 escreve_lcd(0x7e).

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(TRUE) // rotina principal { RESTART_WDT(). portc=0x00. comando_lcd(0xc3). porte=0x00. comando_lcd(0xc7). } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs). coluna 7 envia simbolo "espaço" para o lcd // // // // limpa limpa limpa limpa limpa porta portb portc portd porte // configura o lcd // imprime a tela principal no LCD enable_interrupts(INT_RTCC). setup_counters (rtcc_internal. enable_interrupts(GLOBAL). } Linguagem C para PIC 73 . set_tris_c(0b11111101). coluna 7 envia simbolo "maior" para o lcd posiciona o cursor na linha 1. // // // // // // configuração da direção dos pinos de I/O // desliga o ventilador posiciona o cursor na linha 1. coluna 3 envia simbolo "espaço" para o lcd // retorna da função // // // // // liga o ventilador posiciona o cursor na linha 1.2). portd=0x00. tela_principal(). coluna 3 envia simbolo "maior" para o lcd posiciona o cursor na linha 1. set_tris_a(0b11011111). WDT_2304MS). escreve_lcd(0x3e).2). set_tris_d(0b00000000). escreve_lcd(0x3e). comando_lcd(0xc7). inicializa_lcd(). ventilador = 0.case 4: if (!ventilador) { bip(750. set_tris_b(0b11110011). } else { bip(1000. } break. porta=0x00. escreve_lcd(' '). set_tris_e(0b00000100). ventilador = 1. // incia o watch-dog timer /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Verifica se algum botão foi pressionado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!f_tela_principal) { tela_principal(). portb=0x00. escreve_lcd(' '). comando_lcd(0xc3).

// carrega a tela de menu time_out = 0. incrementa contador de seleção de tarefa sel_tela_menu(). volta para o loop principal /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão S2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_enter: if (filtro != 0) // Ação já foi executada? { filtro --. // sim. executa tarefa if (contador_tela < 2) // De selecionar a próxima tarefa? { contador_tela ++. // re-inicia contagem do tempo de } } goto loop. } * * * * * * * * * * * * * * */ // recarga da variável filtro // testa botão 2 trata_enter.// Volta para a primeira tela do menu sel_tela_menu(). decrementa o filtro if (filtro == 0) // fim do filtro do botão? { // sim. { contador_tela = 1. } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão S1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ trata_menu: //ligar time . decrementa o filtro if (filtro == 0) // fim do filtro do botão? { sel_tela_enter(). // re-inicia contagem do tempo de time-out } } } goto loop. carrega a tela de seleção time_out = 0.//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * if (!menu) { goto } //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * if (!enter) { goto } //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * filtro = t_filtro.// desvia para a rotina de incremento do timer de tarefa time-out 74 Linguagem C para PIC .// desvia para a rotina de incremento do timer // testa botão 1 trata_menu. // sim. // não. // seleciona a tela de menu time_out = 0.// sim. // não.out if (filtro != 0) // Ação já foi executada? { filtro --. // re-inicia contagem do tempo de time-out } else // não.

if (time_out == 250) // já passou 5 segundos? { time_out = 0. // zera contador de tela f_tela_principal = 0. switch(contador) { case 0: temp2 ++. zera time_out contador_tela = 0. // sim. // fim de execução de execução da tarefa case 1: // time_out = 10ms * 250 * 2 time_out ++./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupção de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupção ocorrerá a cada 256us. // não. então não controla o led2 else { led2 = 0. } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // não. // libera atual. liga o led2 } else { led2 = 0. O comando switch será executado a cada 10ms. o led2 está ligado? { led2 = 1.// não. // A variável auxiliar temp1 será utilizada para contar 40 interrupções. Linguagem C para PIC 75 . // sim. // fim de execução de execução da tarefa default: contador = 0. zera contador de interrupção if (led1) // O led1 está ligado { if (!led2) // sim. zera contador de interrupção // seleciona tarefa // controle do led2 // passou 1 segundo? // sim.tela principal } contador ++. if (temp2 == 50) { temp2 = 0. sai da int. // incrementa contador de tarefa break. desliga o led2 } } // não. // totalizando 10ms. #int_rtcc void trata_int_tmr0() { temp1 ++. if (temp1 == 40) { temp1 = 0. // já passou 10ms? // sim. // incrementa contador de tarefa break. mantém o led2 desligado } } contador ++.

aproveite para gerar novos problemas e soluções. Mude a rotina para que seja controlado o buzzer no lugar do led 2. 76 Linguagem C para PIC .1.42 . seguindo os exercícios propostos: 1. 2.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. Crie mais um nível no Menu para controlar o buzzer.

43 .Anotações Linguagem C para PIC 77 .1.

Valor máximo da resolução do AD (10 bits) Valor a ser mostrado no display (5V * ADRES) / 1023 = "n" Volts Tensão de Referência Valor de tensão medido 78 Linguagem C para PIC .Recursos Avançados: Exemplo 7 1.11-pág 206 do livro Programação em C). Para que possamos visualizar o valor de 0 à 5V no LCD.Lógica do exemplo Este exemplo foi elaborado para explicar as funções do CCS para o módulo de conversão analógico digital interno do PIC. foi feita uma segunda conversão o valor digital foi convertido para “Volts” realizando uma regra de 3.44 . Neste exemplo foi utilizado variável do tipo float para armazenar o resultado da conversão A/D.45 .Recursos do Livro Conversor Analógico Digital Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos no exemplo 1 e mais. sendo que este valor pode ser alterado através do potenciômetro P2 da placa MCLAB2 este valor é ajustado entre 0 e 5V e mostrado no LCD. funções do compilador para controle do conversor analógico digital (cap. 1. É convertido o valor analógico presente no pino RA1 do microcontrolador.

46 .7K 330R RA1 +5V 1uF 7 8 9 10 11 12 13 14 DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 VDD 2 VO 3 VSS 1 RS 6 EN 5 R/W 4 10K RS EN LCD +5V RESET 10K MC1 1 2 3 4 5 6 7 +5V VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC6 32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25 +5V RS EN 8 9 10 11 12 13 14 15 4MHz 16 17 18 23 24 MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 16F877A Linguagem C para PIC 79 .1.Esquema Elétrico +5V P2 10K + LM358 4.

WATCHDOG.RA1 e RA3 como entradas analógicas.47 . PRESCALER.Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS.1. adc = 10 bits Tensão de Refêrencia interna (VDD e VSS) Frequencia de conversão = fosc / 32 Selecionado Canal 1 Módulo ligado Inicializa LCD Prepara Tela principal A 80 Linguagem C para PIC . PORTAS. Configura AD: RA0.

A LIMPA WATCHDOG Inicia e lê o resultado da conversão Multiplica valor da conversão por 5 Divide resultado da multiplicação por 1023 Envia resultado para o display Linguagem C para PIC 81 .

float conversao = 0.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C .LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.nolvp.nocpd.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.1.brownout.h> // microcontrolador utilizado #device adc=10 // configura AD para retornar valor em 10 bits /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt. O valor da conversão // A/D é ajustado numa escala de 0 à 5V e mostrado no LCD.Recursos Avançados de programação * Exemplo 7 * * CENTRO DE CAPACITAÇÃO .com. #include <16f877A. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa.br * * E-MAIL: cursos@labtools.com. É convertido o valor analógico // presente no pino RA2 do microcontrolador. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção.wdt.48 .nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000.labtools.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este exemplo foi elaborado para explicar o funcionamento do módulo de // conversão analógico digital interno do PIC. // armazena o resultado da conversão AD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização dos port's * 82 Linguagem C para PIC . sem a necessidade redigitação. sendo que este valor pode ser // alterado através do potenciômetro P2 da placa MCLAB2.put.noprotect. /* * * * * // O //os //de * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ arquivo de definições do pic utilizado deve ser referenciado para que nomes definidos pela Microchip possam ser utilizados.

enable = 1. delay_us(40). } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01). delay_us(1). #bit rs = porte. delay_us(1). enable = 0. enable = 1 .0 #bit enable = porte. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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 portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As saídas devem ser associadas a nomes para facilitar a programação e //futuras alterações do hardware. delay_ms (2). } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1.1 // via do lcd que sinaliza recepção de dados ou comando // enable do lcd * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0. } // // // // // 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 mínimo 40 microsegundos * // // // // // 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 mínimo 40 microsegundos // limpa lcd Linguagem C para PIC 83 . enable = 0. delay_us(40). portd = caracter. portd = caracter.

inicializa_lcd(). // // // // // // configuração da direção dos pinos de I/O limpa limpa limpa limpa limpa porta portb portc portd porte // configura o lcd // imprime a tela principal no LCD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(TRUE) // rotina principal { RESTART_WDT(). // espera 4 milisengundos comando_lcd(0x30). set_tris_b(0b11111111). " V"). tela_principal(). // printf (escreve_lcd. set_tris_d(0b00000000). // das unidades de AD em Volts. // envia comando para inicializar display delay_ms(4)./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicialização do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30).// envia dados para o display de LCD // 1 número inteiro e 9 casas decimais. // liga o display. // envia comando para inicializar display delay_us(100). } * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * */ posiciona o cursor na linha 0. setup_counters (rtcc_internal. portb=0x00. coluna 14 // imprime mensagem no lcd /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (RA0_RA1_RA3_analog). // posiciona o cursor na linha 1. portd=0x00. comando_lcd(0xC2). porta=0x00. coluna 3 // imprime mensagem no lcd posiciona o cursor na linha 1. portc=0x00.9f". 84 Linguagem C para PIC . set_adc_channel (1). porte=0x00. // envia comando para inicializar display comando_lcd(0x38). WDT_2304MS). // limpa lcd comando_lcd(0x0c). set_tris_c(0b11111111). sem cursor e sem blink limpa_lcd(). set_tris_e(0b00000100). conversao = (conversao / 1023). // display sem cursor comando_lcd(0x06). // incia o watch-dog timer conversao = read_adc(). // seleciona o canal 1 do AD set_tris_a(0b11111111)."%1. // desloca cursor para a direita } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * void tela_principal() { comando_lcd(0x83). setup_adc (adc_clock_div_32). conversao). coluna 2 printf (escreve_lcd. // espera 100 microsengundos comando_lcd(0x30). // printf (escreve_lcd. comando_lcd(0xcd). // faz regra de 3 para converter o valor. // inicia conversão AD conversao = (conversao * 5). "Voltimetro").

} } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Linguagem C para PIC 85 .

1. 2. aproveite para gerar novos problemas e soluções. 86 Linguagem C para PIC . 3. Altere a função de escrita no LCD para que ela imprima apenas 3 casas depois da virgula. Mude a configuração do A/D para que ele realize as conversões com a Fosc/8. Mude a configuração do A/D para que ele retorne apenas os 8 bits mais significativos.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido.49 . seguindo os exercícios propostos: 1.

Anotações Linguagem C para PIC 87 .50 .1.

11.51 .11. DC = (valor / T).9990 Então antes de utilizar o PWM. através do timer1(usado como contador) e mostrada no LCD. diretiva #ROM (cap.52 . determina o período do pulso do PWM.10 pág. funções do compilador para controle do PWM (cap. O botão S4 salva o valor de ajuste em EEPROM e o botão S3 restaura o valor salvo atualizando o PWM. Por está razão dependendo da freqüência do PWM não será possível alcançar os 100% de Duty Cyle. com PR2 igual a 255.10. Realizando a operação nestes botões será visualizado no LCD o incremento e o decremento em porcentagem(%) e a rotação do ventilador em rps (rotações por segundo). pág.11. Este conhecimento pode ser adquirido através do livro Conectando o PIC. Este valor pode chegar a 1023.167 do livro Programação em C) e função de manipulação de registradores make8 e make16 (cap. pág.Recursos Avançados: Exemplo 8 Interna 1. A velocidade do ventilador é medida em rotações por segundo.Recursos do Livro Controle do PWM e EEPROM Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos no exemplo 1 e mais. Para que possamos utilizar o PWM do PIC não podemos esquecer de configurar a freqüência do PWM no Timer2.219 do livro Programação em C). Um ventilador terá a sua velocidade controlada através do PWM. o tempo em que a saída do PWM permanecerá em nível lógico 1. enquanto o período do PWM pode chegar a 1024. estude o funcionamento do Módulo CCP para um melhor aproveitamento. 88 Linguagem C para PIC . T = [(PR2 + 1) * 4] * Tosc * Prescaler TMR2 A função set_pwm_duty(valor). 1. o PWM é incrementado e decrementado pelo botão S2.200 e 201 do livro Programação em C). 1023 / 1024 = 0. ou seja.Lógica do exemplo Este exemplo foi elaborado para explicar o funcionamento do módulo de PWM e da escrita da EEPROM interna do microcontrolador.218 do livro Programação em C). o valor ajustado poderá ser salvo na memória EEPROM e restaurado através dos botões.9 pág. Através do botão S1. funções do compilador para operação com EEPROM (cap.

Esquema Elétrico +5V 7 8 9 10 11 12 13 14 DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 VDD 2 VO 3 VSS 1 RS 6 EN 5 R/W 4 10K RS EN LCD +5V RESET 10K MC1 1 2 3 4 5 6 7 +5V VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC6 32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25 +5V RS EN 8 9 10 11 12 13 14 15 16 17 18 4MHz TACOMETRO 23 24 MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 16F877A +5V +5V +5V +5V 10K 10K 10K 10K RB0 S1 +Vcc RB1 S2 RB2 S3 RB3 S4 1N4148 MINI VENTILADOR +5V +5V 4.7K BC337 150R SIR381583F RPT38PT3F 10K 1K TACOMETRO 1K BC337 Linguagem C para PIC 89 .53 .1.

? T rata B otão U P N ÃO BO T ÃO D O W N P R ES S .Fluxograma M A IN C O N FIG U R AÇ Õ E S IN IC IAIS T R IS .54 .? S IM T rata B otão D O W N N ÃO N ÃO G rava D ados em E E PR O M ? SIM S alva dados em EE PR O M N ÃO R estaura D ados da E E PR O M ? SIM Lê E EP R O M N ÃO A tualiza P wm 90 Linguagem C para PIC . P R E SC A LE R . W A T C H D O G . P O R T AS .1. C onfigura T im er0 Inic ializa LC D T ela princ ipal H abilita as interrupç ões A Lim pa W AT C H D O G S IM E sc reve tela princ ipal ? T ela principal NÃO S IM B O T Ã O U P P R ES S.

Trata Botão UP Trata Botão DOWN Ação já foi executada ? SIM Ação já foi executada ? SIM NÃO NÃO Decrementa Filtro Decrementa Filtro Fim do Filtro ? NÃO Fim do Filtro ? NÃO SIM Decrementa Turbo SIM Decrementa Turbo Fim do Turbo ? Fim do Turbo ? Re-carrega variavel do Turbo Re-carrega variavel do Turbo Incrementa PWM do ventilador Atualiza a tela principal Decrementa PWM do ventilador Atualiza a tela principal A A Linguagem C para PIC 91 .

INTERRUPÇÕES Contador de interrupções é igual a zero ? (Temp1 = 0) SIM NÃO Decrementa contador de interrupções Carrega variável rotação com o valor do Timer1 Divide variável rotação por 7 (número de palhetas do ventilador) habilita atualização do LCD FIM DA INTERRUPÇÃO 92 Linguagem C para PIC .

nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000. // inicia turbo das teclas int dado. através do // timer1 e mostrada no lcd.LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www. o valor ajustado poderá ser // salva na memória EEPROM e restaurado através dos botões. // armazena o resultado da conversão AD long int duty_cycle1 = 0.put. // rps do ventilador int end = 0.Recursos Avançados de programação * Exemplo 8 * * CENTRO DE CAPACITAÇÃO .com. float duty_cycle = 0.labtools.0xe8} // carrega eeprom com valor inicial. // variável aux para int de tmr0 int turbo = 1.com. #include <16f877A.wdt.55 . #define t_filtro 200 #define turbo_tecla 5 // tamanho do filtro // turbo dos botões /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa. // inicia filtro dos botões int temp1 = 125. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializa EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #rom 0x2100 = {0x03.br * * E-MAIL: cursos@labtools.nocpd. // armazena o resultado da conversão AD long int periodo_pulso = 0.brownout. // variável de dados para eeprom Linguagem C para PIC 93 .0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este exemplo foi elaborado para explicar o funcionamento do módulo de // PWM e da escrita da EEPROM interna do microcontrolador.noprotect.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . // long int rotacao = 0. inicia PWM com 97% /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção. // variável para endereçamento da eeprom int flags1 = 0.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1. // flags int filtro = t_filtro.1. Um ventilador terá // a sua velocidade controlada através do PWM.nolvp.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt. // A velocidade do ventilador é medida em rotações por segundo.

1 #bit ventilador = portc.2 #bit botao4 = portb.0 #bit botao2 = portb.1 #bit botao3 = portb. // Estado do botão 2 // 1 -> Liberado // 0 -> Pressionado // Estado do botão 3 // 1 -> Liberado // 0 -> Pressionado // Estado do botão 4 // 1 -> Liberado // 0 -> Pressionado // Estado do botão 4 // 1 -> Liberado // 0 -> Pressionado botao1 = portb.3 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As saídas devem ser associadas a nomes para facilitar a programação e //futuras alterações do hardware. #bit atualiza_lcd = flags1. enable = 0. } // // // // // 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 mínimo 40 microsegundos 94 Linguagem C para PIC .0 #bit enable = porte. delay_us(1). #bit rs = porte.0 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware. portd = caracter. enable = 1 ./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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=0x05 portb=0x06 portc=0x07 portd=0x08 porte=0x09 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM.1 // via do lcd que sinaliza recepção de dados ou comando // enable do lcd // pino de I/O para controle do ventilador (PWM) * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0. delay_us(40).

comando_lcd(0x38). delay_us(100). coluna 11 printf (escreve_lcd. // envia dados para o display de LCD } // envia comando para inicializar display // espera 4 milisengundos // envia comando para inicializar display // espera 100 microsengundos // envia comando para inicializar display // liga o display. // posiciona o cursor na linha 1. duty_cycle1). delay_ms(4). delay_us(40). coluna 0 printf (escreve_lcd. comando_lcd(0x30)./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1. coluna 3 printf (escreve_lcd. delay_us(1). enable = 0."%" "3Lu%%". enable = 1. sem cursor e sem blink // limpa lcd // display sem cursor // desloca cursor para a direita Linguagem C para PIC 95 . } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para imprimir a Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { comando_lcd(0x80). portd = caracter. "Duty cycle RPS"). comando_lcd(0x0c). // posiciona o cursor na linha 1. rotacao). comando_lcd(0x30). comando_lcd(0x06). // posiciona o cursor na linha 0. delay_ms (2). } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01). // envia dados para o display de LCD comando_lcd(0xcb)."%" "3Lu". } // // // // // seleciona o envio de um caracter carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable // espera mínimo 40 microsegundos // limpa lcd /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função de inicialização do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30). limpa_lcd(). // imprime mensagem no lcd comando_lcd(0xc3).

/* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Salva Dados na EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ salva dado na eeprom no endereço indicado através da variável "end". inicializa_lcd(). // modo PWM ligado set_pwm2_duty(periodo_pulso). o dado lido é carregado na variável "dado". set_tris_e(0b00000100). } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Atualiza PWM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void atualiza_pwm() { set_pwm2_duty(periodo_pulso). ps: 1:1 setup_timer_2 (t2_div_by_16. portd=0x00. porte=0x00. set_tris_d(0b00000000). /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * loop: while(TRUE) // rotina principal { RESTART_WDT(). pr2=255 e postscale: 1:1 setup_ccp2(ccp_pwm).// tmr0 clock interno.// tmr2 ps=1:16. ps: 1:64 setup_timer_1 (t1_external_sync | t1_div_by_1). enable_interrupts(INT_RTCC). // ajusta duty cycle em 0.dado). enable_interrupts(GLOBAL).// tmr1 clock externo. porta=0x00. } /* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Lê Dados na EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ lê o dado na eeprom no endereço indicado através da variável "end". set_tris_b(0b11111111). } // atualiza duty cicle do PWM /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs). rtcc_div_64). set_tris_c(0b11111101). tela_principal(). * void salva_dados() { write_eeprom (end. set_tris_a(0b11111111). portc=0x00. // desliga as entradas analógicas setup_counters (rtcc_internal. le_dados(end) { dado = read_eeprom (end). o dado a ser salvo é passado para a Função através da variável "dado". portb=0x00.255.1). // incia o watch-dog if (atualiza_lcd != 0) * * */ // configuração da direção dos pinos de I/O // // // // // limpa limpa limpa limpa limpa porta portb portc portd porte // configura o lcd // imprime a tela principal no LCD timer 96 Linguagem C para PIC .

atualiza_lcd = 0. // converte para porcentagem (%) duty_cycle1 = (long int) duty_cycle. // retorna byte_high salva_dados(). // endereço do byte_high dado = make8(periodo_pulso. } // Função para atualizar o PWM // habilita atualização do LCD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão salvar dados na EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao4) // testa botão 4 { end = 0. // salva byte_low } filtro = t_filtro. } // carrega filtro dos botões // fecha while //* * * * * * * * * * * Incrementa duty cycle do PWM * * * * * * * * * * trata_up: { filtro --. // recompõe o dado de 16 bits atualiza_pwm(). // carrega valor da rotação medida duty_cycle = (duty_cycle / 1024).{ duty_cycle = periodo_pulso. // desvia para a rotina de incremento do PWM le_dados(0). periodo_pulso = dado. // carrega os 16 bits menos significativos da parte inteira // do resultado da converão tela_principal(). // decrementa o filtro if (filtro == 0) // fim do filtro do botão? { Linguagem C para PIC 97 . // lê byte_high da eeprom periodo_pulso = make16(dado.0). // desvia para a rotina de decremento do PWM // testa botão 1 trata_up. turbo = 1. // testa botão 3 // lê byte_low da eeprom // carrega valor lido em variável de 16 bits // testa botão 2 trata_dowm. // retorna byte_low salva_dados().1). atualiza_lcd = 1. // salva byte_high end = 1. // endereço do byte_low dado = make8(periodo_pulso. } // imprime a tela principal no LCD // indica LCD atualizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão de incremento (UP) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao1) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão de decremento (down) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao2) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão ler dados da EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao3) { le_dados(1). periodo_pulso). // efetua cálculo do duty cycle duty_cycle = (duty_cycle * 100).

atualiza_lcd = 1. if (turbo == 0) // sim. // le valor do timer 1 // zera timer 1 // divide por 7 (quantidade de palhetas do ventilador) // habilita atualização do LCD // re-inicia temp1 // Não. // decrementa o filtro if (filtro == 0) // fim do filtro do botão? { turbo --. } // ja passou 1 segundo? // Sim. // habilita atualização do LCD } } } } goto loop. Quando isto ocorrer. rotacao = (rotacao / 7). // habilita atualização do LCD } } } } loop. atualiza_pwm(). // Função para atualizar o PWM atualiza_lcd = 1. if (temp1 == 0 ) { rotacao = get_timer1(). if (periodo_pulso < 1023) // limita incremento do periodo do pulso em 1023 { periodo_pulso ++. atualiza_pwm(). if (turbo == 0) // sim. //* * * * * * * * * * * Decrementa duty cycle do PWM * * * * * * * * * * trata_dowm: { filtro --.goto turbo --. fim do turbo do botão ? { turbo = turbo_tecla. fim do turbo do botão ? { turbo = turbo_tecla. // Função para atualizar o PWM atualiza_lcd = 1. // decrementa temp1 } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 98 Linguagem C para PIC . A variável auxiliar temp1 será utilizada para contar 125 interrupções. // decrementa o turbo da tecla filtro = t_filtro. set_timer1 (0). } /* * * // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupção de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Esta interrupção ocorrerá a cada 8ms. } else { temp1 --. temp1 = 125. a variável rotação será carregada com o valor de rotações por segundo do ventilador. totalizando 1 segundo. if (periodo_pulso != 0) // limita decremento do periodo do pulso em 0 { periodo_pulso --. #int_rtcc void trata_int_tmr0(void) { set_rtcc(256-125). // decrementa o turbo da tecla filtro = t_filtro.

seguindo os exercícios propostos: 1. Linguagem C para PIC 99 . 2. Mude a freqüência do PWM para que possamos ajustar o Duty cycle de 0 a 100%. aproveite para gerar novos problemas e soluções.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. Ative os dois PWM`s um para o ventilador e outro para a resistência.1.56 .

Anotações 100 Linguagem C para PIC .1.57 .

Neste exemplo iremos coletar dados do A/D e armazenar estes dados na EEPROM externa (24c04). pág. para a liberação da transmissão de dados. 1. ao final da coleta e enviado para o PC o comando 0x0b. Ao final da transmissão ele aguarda novo comando de inicio de coleta de dados.13 pág 230 do livro Programação em C). O PC controlará as funções do coletor de dados.11. ele inicia a transmissão de dados para o PC plotar os dados na tela. Linguagem C para PIC 101 .59 .Recursos do Livro Coletor de Dados Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos no exemplo 1 e mais. diretiva de configuração #use i2c e #use RS232 (cap.171 e 172 do livro Programação em C).Recursos Avançados: Exemplo 9 1.Lógica do exemplo Este exemplo foi elaborado para explicar as funções de I2C do compilador CCS e comunicação serial com a USART. funções do compilador para controle de comunicação serial RS232 (cap.14 pág 240 do livro Programação em C). estes dados serão enviados ao PC para a visualização dos mesmos. Quando for recebido o dado 0x55 o PIC inicia a coleta de dados.11.10. Após o fim da coleta de dados o PIC aguarda o comando 0xaa.58 . funções do compilador para controle de comunicação serial I2C (cap. recebendo este dado.

60 .Esquema Elétrico +5V P2 10K + 4.7K 330R RA1 1uF +5V +5V 7 8 9 10 11 12 13 14 RESET 10K 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 DB0 DB1 DB2 DB3 DB4 DB5 DB6 DB7 VDD 2 VO 3 VSS 1 RS 6 EN 5 R/W 4 10K RS EN MC1 MCLR 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 RC6 32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25 +5V LCD +5V +5V RS EN 1 2 3 4 A0 A1 A2 GND VCC WP SCL SDA 8 7 6 5 10K 10K 4MHz 17 18 23 24 24C04 16F877A +5V 1uF 1 3 1uF 1uF C1+ C1 C2+ C2 +C 2 -C 6 12 4 5 13 14 8 7 15 T1IN T1OUT R1OUT R1IN 11 T2IN T2OUT R2OUT R2IN 10 GND VCC 16 9 1K +5V 3 2 5 1uF MAX-232 CONECTOR DB9 FEMEA 102 Linguagem C para PIC .1.

W ATCHDOG.61 .1. PORTAS. PRESCALER. rs232 e I2C Inicializa LCD Tela principal Habilita as interrupções A Limpa W ATCHDOG Verifica se chegou comando pela USART B SIM Inicia coleta de dados ? Coleta Dados NÃO Deve transmitir dados para o PC ? SIM TX Dados para o PC NÃO SIM Para a coleta de Dados ? Cancela coleta de dados Transmite para o PC comando de fim de coleta de dados NÃO A Linguagem C para PIC 103 .Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS. Configuração: AD.

Recebe comando do PC Chegou comando do PC ? NÃO SIM SIM Recebeu o comando de inicio de Coleta de Dados ? Tarefa = coleta de dados NÃO B SIM Recebeu o comando de transmissão de dados para o PC ? Tarefa = transmite dados para o PC NÃO B SIM Recebeu o comando de parar coleta de dados ? Tarefa = para coleta de dados NÃO B 104 Linguagem C para PIC .

Coleta Dados Escreve no LCD: "Coletando Dados" Lê Dados do AD Salva em EEPROM Serial NÃO Fim da Coleta de Dados ? SIM Aguarda novo comando do PC Envia para o PC comando de Fim de Coleta de Dados Escreve no LCD: "Pronto para TX" Return Linguagem C para PIC 105 .

" Aguarda novo comando do PC delay de 5 segundos Escreve no LCD: "Press Inicio" delay de 1 segundo Return 106 Linguagem C para PIC ..Transmite dados para o PC Escreve no LCD: "TX para o PC" Lê memória EEPROM Serial Transmite para o PC NÃO Fim da transmissão de Dados ? SIM Escreve no LCD: "Fim da Trans..

Linguagem C para PIC 107 .

Escreve na memória EEPROM Serial Lê dados da memória EEPROM Serial Envia Start bit Envia Start bit Envia Controle Envia Controle Envia endereço low Envia endereço low Envia Dado Envia Start bit Envia Stop bit Envia Controle delay 10ms Recebe dados da memória salva em variável dado Return Envia Stop bit delay 10ms Return 108 Linguagem C para PIC .

noprotect.nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000. parar_coleta }tarefa.com. scl=pin_c3.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.nolvp.sda=pin_c4. transmite_para_pc.nocpd.br * * E-MAIL: cursos@labtools.com.labtools.wdt. coleta_de_dados. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Linguagem C para PIC 109 . Neste exemplo iremos coletar dados do AD e armazenar estes dados na // EEPROM externa (24c04). FORCE_HW) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuração da USART * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use rs232 (baud=9600.62 .h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.1.brownout. #define #define ctrl_le ctrl_escr 0b10100001// byte de controle da memória p/ leitura 0b10100000// byte de controle da memória p/ escrita /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constante internas do tipo Enumeração * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ enum selecao_de_tarefa { aguarda_comando. SLOW.Recursos Avançados de programação * * Exemplo 9 * * * * CENTRO DE CAPACITAÇÃO .put. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuração do Módulo I2C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use i2c(master. rcv = pin_c7) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção. xmit = pin_c6. estes dados serão enviados ao PC para a // visualização dos mesmos.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este exemplo foi elaborado para explicar as funcões de I2C do compilador // CCS.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . O PC controlará as funções do coletor de dados. #include <16f877A.LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www. RESTART_WDT.

1 // enable do lcd /* * * * * * * * * * * * * Função * * * * * * * * * * * * escr_mem_serial () { i2c_start().0 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware. } /* * * * * * * * * * * * * Função * * * * * * * * * * * * le_mem_serial () { i2c_start(). i2c_write(ctrl_escr). i2c_write(end_low). } * * * * * * * * * * * * * * * * * * * * * * * * * * para escrita na EEPROM externa I2C * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Condição de início // Envia o byte de controle de leitura // Envia endereço baixo // Escreve dado na E²PROM // Condição de parada // espera a gravação estar completa * * * * * * * * * * * * * * * * * * * * * * * * * * para leitura na EEPROM externa I2C * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Condição de início // Envia o byte de controle de leitura // Envia endereço baixo // Nova condição de início // Envia o byte de controle de leitura // lê o dado armazenado na E²PROM // Condição de parada /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 110 Linguagem C para PIC . i2c_write(ctrl_le). static int comando = 0. i2c_stop(). i2c_write(ctrl_escr). /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As saídas devem ser associadas a nomes para facilitar a programação e //futuras alterações do hardware. static int tx_pc. i2c_start(). i2c_write(end_low). /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM. i2c_write(dado). static int flags1 = 0. // flags static int dado = 0. delay_ms(10). #bit rs = porte. #bit atualiza_lcd = flags1. dado = i2c_read(0).* Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa. static int end_low = 0.0 // via do lcd que sinaliza recepção de dados ou comando #bit enable = porte. i2c_stop().

enable = 1. delay_us(100). comando_lcd(0x30). delay_ms(4). portd = caracter. delay_ms (2). enable = 0. delay_us(1). enable = 1 . comando_lcd(0x06).* Função que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0. enable = 0. } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01). delay_us(1). comando_lcd(0x38). } // envia comando para inicializar display // espera 4 milisengundos // envia comando para inicializar display // espera 100 microsengundos // envia comando para inicializar display // liga o display. comando_lcd(0x0c). portd = caracter. // posiciona o cursor na linha 0. comando_lcd(0x30). limpa_lcd(). } * // // // // // 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 mínimo 40 microsegundos * // // // // // seleciona o envio de um caracter carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable // espera mínimo 40 microsegundos // limpa lcd /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função de inicialização do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30). "Coletor de dados"). delay_us(40). sem cursor e sem blink // limpa lcd // display sem cursor // desloca cursor para a direita /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para imprimir a Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { limpa_lcd() comando_lcd(0x80). coluna 0 printf (escreve_lcd. } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1. delay_us(40). // imprime mensagem no lcd } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina para coleta de dados * Linguagem C para PIC 111 .

" Fim da Trans. if (comando == 0x55) // recebeu o camando de coleta de dados ? { tarefa = coleta_de_dados. " "). coluna 0 printf (escreve_lcd. // posiciona o cursor na linha 1."). coluna 0 printf (escreve_lcd. // delay de 10 ms }while (end_low != 0). // imprime mensagem no lcd delay_ms(3000). " Pronto para TX "). // fim da transmissão de dados tarefa = aguarda_comando. cancela coleta de dados } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Pic * 112 Linguagem C para PIC . coluna 0 printf (escreve_lcd. // sim. // fim da coleta ? tarefa = aguarda_comando. coluna 0 printf (escreve_lcd.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ coleta_dados() { comando_lcd(0xc0).. // posiciona o cursor na linha 1.// envia ao PC o comando de fim da coleta de dados delay_ms(2000). // delay de 100 ms }while (end_low != 0). "Coletando Dados"). // delay de 1 segundo } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento de recepção serial * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void recebe_comando() { if (kbhit()) { comando = getc(). // delay de 3 segundos comando_lcd(0xc0). // aguarda comando do PC comando_lcd(0xc0). // sim. // imprime mensagem no lcd tx_pc = 11. // delay de 2 segundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina para transmitir dados para o PC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ tx_dados_pc() { comando_lcd(0xc0). // aguarda comando do PC comando_lcd(0xc0). // posiciona o cursor na linha 1. " TX para o PC "). // indica para o pc fim da coleta de dados printf ("%x\r\n". // imprime mensagem no lcd do { le_mem_serial (). seleciona nova posição delay_ms(100). // imprime mensagem no lcd delay_ms(1000). // incrementa endereço. // imprime mensagem no lcd do { dado = read_adc(). // salva em eeprom end_low += 1. // incrementa endereço. // le dados da eeprom printf ("%x\r\n". libera coleta de dados } if (comando == 0xaa) // recebeu o camando de transmissão de dados ? { tarefa = transmite_para_pc.. transmite dados para o PC } if (comando == 0x7f) // recebeu o camando para cancelar coleta de dados ? { tarefa = parar_coleta. // sim. // le resuldado do AD escr_mem_serial (). // posiciona o cursor na linha 1. // posiciona o cursor na linha 1. coluna 0 printf (escreve_lcd.dado). seleciona nova posição delay_ms(10).tx_pc). // envia ao PC o valor da eeprom externa end_low +=1.

porte=0x00. // sim. set_adc_channel (1). // sim. if (tarefa == coleta_de_dados) // inicia coleta de dados ? { end_low = 0. // executa função de transmissão de dados } if (tarefa == parar_coleta) // cancela coleta de dados ? { end_low = 0. set_tris_b(0b11111111). setup_adc (adc_clock_div_8). portc=0x00. inicializa_lcd(). carrega endereço inicial tarefa = aguarda_comando. porta=0x00. carrega endereço inicial tx_dados_pc(). tela_principal(). portb=0x00. // incia o watch-dog timer recebe_comando(). // espera envio de comando do PC tx_pc = 11.* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (RA0_RA1_RA3_analog). set_tris_d(0b00000000). // fim da coleta de dados tx_dados_pc(). setup_counters (rtcc_internal. carrega endereço inicial coleta_dados(). WDT_2304MS). // configuração da direção dos pinos de I/O // // // // // limpa limpa limpa limpa limpa porta portb portc portd porte // configura o lcd // imprime a tela principal no LCD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(true) // rotina principal { RESTART_WDT(). set_tris_e(0b00000100). // executa função de coleta de dados } if (tarefa == transmite_para_pc)// inicia transmissão de dados para o PC ? { end_low = 0. // envia comando para o PC } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Linguagem C para PIC 113 . set_tris_a(0b11111111). // sim. set_tris_c(0b10110111). portd=0x00.

1. aproveite para gerar novos problemas e soluções. Mude a rotina de coleta de dados para que seja armazenado na EEPROM um valor de 0 à 5V e não um valor de 0 a 255. Implemente a regra de três necessária.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. Altere a configuração do A/D para que ele retorne os 10 bits do resultado da conversão e salve este dado na EEPROM. 114 Linguagem C para PIC .63 . seguindo os exercícios propostos: 1. 2.

1.64 - Anotações

Linguagem C para PIC

115

Recursos Avançados: Exemplo 10 Funções Matemáticas
1.65 - Recursos do Livro
Para o bom entendimento deste exemplo são necessários os conhecimentos adquiridos no exemplo 1 e mais, funções matemáticas do compilador (cap.11.1 pág 175 do livro Programação em C).

1.66 - Lógica do exemplo
A elaboração deste exemplo foi pensando na demonstração das funções matemáticas, nele veremos o microcontrolador realizando o calculo do seno de 0 a 2π, um software para PC foi elaborado para coletar os cálculos realizas e plotar os cálculos na tela do PC. Outras funções podem ser visualizadas, bastando para isso alterar a função matemática de nosso programa.

116 Linguagem C para PIC

1.67 - Esquema Elétrico

+5V

RESET

10K MC1
1 2 3 4 5 6 7

+5V
VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC6
32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25

+5V

RS EN

8 9 10 11 12 13 14 15

4MHz

16 17 18 23 24

MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5

16F877A

+5V

1uF
1 3

1uF

1uF

C1+ C1 C2+ C2 +C 2 -C 6
12

4 5 13 14 8 7 15

T1IN T1OUT R1OUT R1IN 11 T2IN T2OUT R2OUT R2IN 10 GND VCC 16
9

1K +5V

3

2

5

1uF

MAX-232

CONECTOR DB9 FEMEA

Linguagem C para PIC

117

Inicializa a variável X=0 NÃO X < (2 * PI) SIM LIMPA W ATCHDO G Y = seno (x) Envia o valor de X para o PC Envia o valor de Y para o PC Incrementa a variável X X = x + 0.01 118 Linguagem C para PIC .68 .1.Fluxograma MAIN CO NFIG URAÇÕ ES INICIAIS TRIS. PO RTAS. W ATCHDO G . PRESCALER.

br * * E-MAIL: cursos@labtools.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C .labtools. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuração da Usart * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use rs232(baud=9600.wdt.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este software foi desenvolvido para mostrar a implementação de funções matemáticas.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1. float x.com.com.h> #device adc=10 // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Carrega bibliteca Matemática * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <math.rcv=pin_c7) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa.69 .noprotect. como exemplo estamos calculando o seno e enviando para o PC os valores de "x" e "y" para serem plotados. * * * * * * * * * * * * * * * * * * * * * dos I/O's e opções de configuração para periféricos * * * * * * * * * * * * * * * * * * * * * */ * /* * * * * * * * * * * * * * * * * Definição * das funções * * * * * * * * * * * * * * * * #include <16f877A.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.nocpd. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção.LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.brownout. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM.1.nowrt // configuração dos fusíveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000.put.xmit=pin_c6. //Este programa não utiliza nenhum flag de usuário Linguagem C para PIC 119 .nolvp.Recursos Avançados de programação * * Exemplo 10 * * * * CENTRO DE CAPACITAÇÃO . float y.

// limpa wdt y = sin (x). * * */ E /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs).y). // envia ao PC o valor de y x = x + 0. portb=0x00. set_tris_b(0b11111111).3f\r\n". // calculo da função printf ("X=%1. // envia ao PC o valor de x printf (" ")./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização 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=0x05 portb=0x06 portc=0x07 portd=0x08 porte=0x09 * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware.01. * * */ e /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SAÍDAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAÇÃO //FUTURAS ALTERAÇÕES DO HARDWARE. // incrementa x } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 120 Linguagem C para PIC . porte=0x00.3f". // configuração da direção dos pinos de I/O // // // // // limpa limpa limpa limpa limpa porta portb portc portd porte /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { x=0. portd=0x00. set_tris_e(0b00000111). porta=0x00. // desliga as entradas analógicas setup_counters (rtcc_internal. set_tris_d(0b11111111).// tmr0 clock interno. while(x < 2*PI) { restart_wdt(). set_tris_c(0b11111111). portc=0x00. printf ("Y=%1.x). wdt_2304ms). ps: 1:64 set_tris_a(0b11111111).

70 1. Linguagem C para PIC 121 . Altere a função matemática para que o PIC calcule o log de um número. seguindo os exercícios propostos: 1.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. aproveite para gerar novos problemas e soluções.1. Altere a função matemática para que o PIC calcule o co-seno. 2.71 .

72 .Anotações 122 Linguagem C para PIC .1.

Sign up to vote on this title
UsefulNot useful