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

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

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

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 .3 .1.

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

br * * E-MAIL: cursos@labtools.LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição das variáveis internas do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.1.noprotect. //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.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.brownout.put.nolvp.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C .5 .wdt. //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.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.nocpd.Recursos Básicos de programação * * Exemplo 1 * * * * CENTRO DE CAPACITAÇÃO . //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 .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.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.

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

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

1.8 .Anotações Linguagem C para PIC 11 .

.

Através dos botões S1 e S2. O camando For (inicialização. nesta rotina não utilizaremos a opção de inicialização do comando For. 1.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. complemento de 1). máximos e mínimos de ajuste da freqüência de oscilação. teste condicional. Up e Down é possível ajustar a freqüência de oscilação dos Leds 3 e 4 da placa McLab2. (NOT.10. 195 do livro Programação em C).Recursos Básicos: Exemplo 2 1.11. sendo a mesma executada fora do laço. o programa fica travado nesta função até o tempo desejado. Para a inversão das portas está sendo utilizado o operador lógico “~”.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.169 do livro Programação em C). definindo a quantidades de vezes que o laço será executado. com este operando estaremos invertendo bit a bit o conteúdo do registrador portb.4 pág. Operadores para criação de expressões lógicas e aritméticas (cap. As constantes min e max determinam os limites. incremento) é utilizado para controle do laço da rotina de delay.6 do livro Programação em C). diretivas de configuração para uso de função de atraso (cap. pág.9 . ou seja. Linguagem C para PIC 13 . funções do compilador para controle de atraso (cap.

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

if (!botao_0) // { if (tempo != max) // { tempo = tempo + 1. 0x0f. incrementa tempo botão_0 liberado. 0x00. set_tris_b(0b11110011). = portb. tempo é diferente de min? { tempo = tempo . // não.1. // carrega portb com valor inicial /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { RESTART_WDT().0 // Estado do botão_0 // 1 -> Liberado // 0 -> Pressionado = portb.#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. decrementa tempo } } // botão_1 liberado contador = tempo.contador!=0. portb = ~portb. set_tris_e(0b00000111). set_tris_c(0b11111111). 0x00. tempo é diferente de max? não. porta portb portc portd porte = = = = = 0x00. // } } // // complemanta o portb O botão_0 foi pressionado? sim. set_tris_a(0b11111111). // comando: delay de 10 milisegundos. set_tris_d(0b11111111). contador--) // contador é diferente de 0? se sim // decrementa contador e executa o comando delay_ms(10). * * */ e /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { setup_counters(rtcc_internal.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 .wdt_2304ms). // carrega contador for (. testa botão 1 if (!botao_1) // O botão 1 foi pressionado ? { if (tempo != min) // sim. 0x00.

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

15 .1.Anotações Linguagem C para PIC 19 .

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

7K BC337 +5V 4MHz 16 17 18 23 24 16F877A +5V +5V 10K 10K RB0 S1 RB1 S2 PIC16F877 Linguagem C para PIC 21 .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.1.18 .

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

? 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 .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 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 .C NÃO BOTÃO S2 PRESS.

// long int filtro1=t_filtro.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.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".nowrt // configuração dos fusíveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000. // long int filtro0=t_filtro.Recursos Básicos de programação * Exemplo 3 * * CENTRO DE CAPACITAÇÃO . #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. // int flags=0. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção.0 #bit bt_DOWN_press = flags. #bit bt_UP_press = flags. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.noprotect.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . O contador está limitado pelas constantes min e max.put.nolvp.nocpd. // 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.LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.1.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.20 . int contador=min.com.com.brownout.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 .br * * E-MAIL: cursos@labtools.labtools.wdt.

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

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

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

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

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 .

* * * * * * * * */ * * * * * * * * * * * * * * * * * * */ tocar o buzzer com acender o led /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIÇÃO DAS VARIÁVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.1.nolvp. int status_leds = 0.com.noprotect. int int int int filtro1 filtro2 filtro3 filtro4 = = = = t_filtro.27 .nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção. t_filtro.brownout.put. t_filtro. além de //indicando a última tecla pressionada. #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.nocpd.labtools.com.br * * E-MAIL: cursos@labtools.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.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt. t_filtro.wdt. // 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 . int per = 0.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . int status_botoes = 0.Recursos Básicos de programação * Exemplo 4 * * CENTRO DE CAPACITAÇÃO .LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.

208.32./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declaração dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de flags ajuda na programação e economiza memória RAM. portc=(0b00000000). set_tris_a(0b11011111). #priority timer0. * * */ e botao1 = status_botoes. pois toda a lógica do // programa é tratada dentro das interrupções. rtcc_div_8). set_tris_d(0b11111111).0 // Estado do botão 1 // 1 -> Liberado // 0 -> Pressionado botao2 = status_botoes.16. enable_interrupts(GLOBAL).2// Estado do botão 3 // 1 -> Liberado // 0 -> Pressionado botao4 = status_botoes. porte=(0b00000000).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.1 status_leds. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuração do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // A rotina principal simplesmente limpa o WDT.per.80.0 status_leds. setup_counters(rtcc_internal . enable_interrupts(INT_RTCC). #bit #bit #bit #bit #bit botao1_press botao2_press botao3_press botao4_press = = = = status_leds.timer2 // prioridade para a int de trm0 Linguagem C para PIC 37 . void main() { setup_adc_ports (no_analogs).176.48.96.128. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware. set_tris_e(0b00000111).1). setup_timer_2 (t2_div_by_16.5 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ byte const tabela[16] = {255. set_tris_c(0b11111111). portb=(0b00000000).160.64.240}.224. porta=(0b00000000).2 status_leds. set_tris_b(0b11110000).112.1 // Estado do botão 2 // 1 -> Liberado // 0 -> Pressionado botao3 = status_botoes.3 buzzer = porta. portd=(0b00000000).192.144.

Esta interrupção é responsável por converter os pinos dos botões em entrada. status_botoes = portb. } /* * * * * * * * * * * * * * * * * * * * * Tratamento do * * * * * * * * * * * * * * * * * * * * if (!botao3) { // // // // testa botão 2 botão 2 está pressionado ? Sim. 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 . botao1_press = 0./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) // rotina principal { RESTART_WDT(). salva em variável // temporária // configura os pinos como saída para // controle dos leds /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Botão 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao1) { filtro1--. } } else { filtro1 = t_filtro. // 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. 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--. } // // // // testa botão 1 botão 1 está pressionado ? Sim. if (filtro1 == 0) { botao1_press = 1. } } else { filtro2 = t_filtro. O filtro dos botões tem duração de 40ms (2048us x 20) e são decrementados a cada interrupção. botao2_press = 0. set_tris_b(0b00000000). if (filtro2 == 0) { botao2_press = 1. salvar a condição dos botões em variável temporária e converter os pinos em saída novamente. #int_rtcc void trata_int_tmr0() { set_tris_b(0b00001111). // incia o watch-dog timer } } /* * * // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupção de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Esta interrupção ocorrerá a cada 2048us. delay_cycles(4).

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

Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. seguindo os exercícios propostos: 1. aproveite para gerar novos problemas e soluções. conforme a tabela abaixo. Modifique o controle dos leds. 2.28 . os botões pares controlam os leds impares e os botões impares controlam os leds pares.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 . Utilize as funções disponíveis do Compilador para inverter o estado do buzzer.

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

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

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

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.7K 4.1.7K 4.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.32 .

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

desliga display do milhar. consulta tabela de conversão para sete segmentos.INTERRUPÇÕES NÃO INT DE TMR0? SIM SWITCH CASE Recarrega Timer1 Incrementa ponteiro de seleção de Display. NÃO SIM Passou 1 segundo ? NÃO Atualiza Display da Dezena? SIM Incrementa ponteiro de seleção de Display. liga display da dezena SIM NÃO Recarrega contador de int. 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. desliga display da dezena. liga display da unidade Atualiza Display da Unidade? decrementa contador de int. consulta tabela de conversão para sete segmentos. desliga display da centena. consulta tabela de conversão para sete segmentos. Atualiza Display da Centena? SIM Incrementa ponteiro de seleção de Display. 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 . consulta tabela de conversão para sete segmentos. 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 .

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

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. #bit estado_timer = portb.7 (1) Linguagem C para PIC 51 .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.6 = portb.2 #bit bt_start_stop = portb.1 #bit bt_down = portb.0 // tmr1if é #bit t0if = 0x0b. // Estado do botão up // 1 -> Liberado // 0 -> Pressionado // Estado do botão down // 1 -> Liberado // 0 -> Pressionado * * */ e bt_up = portb.5 = portb.2 // t0if é o #bit tmr1ie = 0x8c. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programação do hardware./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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.4 = portb.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.

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

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

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

// decrementa o filtro if (filtro == 0) // fim do filtro do botão? { turbo --. // decrementa o timer } } } goto loop. fim do turbo do botão ? { turbo = turbo_tecla./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. // carrega o turbo incrementa_timer(). fim do turbo do botão ? { turbo = turbo_tecla. // decrementa o turbo da tecla if (turbo == 0) // sim. // incrementa o timer } } } goto loop. // carrega o turbo decrementa_timer().// desvia para a rotina de incremento do timer Linguagem C para PIC 55 . // decrementa o turbo da tecla if (turbo == 0) // sim. } //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_up: if (estado_timer == 0) // o timer está parado? { filtro --. turbo = 1. // decrementa o filtro if (filtro == 0) // fim do filtro do botão? { turbo --.// desvia para a rotina de decremento do timer // testa botão up trata_up. //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_dowm: if (estado_timer == 0) // o timer está parado? { filtro --. // testa botão down trata_dowm. // desvia para a rotina para ligar ou // desligar o timer } filtro = t_filtro.

indica que o timer está contando contador = 2.// não. // decrementa o filtro if (filtro == 0) // fim do filtro do botão? { if (estado_timer != 0) // sim. { if (tmr1if) // É int de tmr1 ? { trata_tmr1(). trata tmr1 } } // não.//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_start_stop: if (filtro != 0) // o timer está parado? { filtro --. } /* * * // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função de Tratamento de interrupções * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Todo o tratamento de interrupção é feito manualmente. // carrega timer 1 tmr1if = 0. // limpa flag de int tmr1 tmr1ie = 1. o timer está ligado ? { estado_timer = 0. restaura_contexto(). #int_global Void trata_int() { salva_contexto().// salva os registradores antes do tratamento da int if (t0if) { trata_tmr0(). // desliga o tratamento de interrupção de timer1 } else { if((unidade!=0)||(dezena!=0)||(centena!=0)||(milhar != 0)) // timer está zerado? { estado_timer = 1. 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. // carrega contador auxiliar set_timer1(delta_timer1). // indica timer parado tmr1ie = 0. // sim. trata tmr0 // não. // liga o tratamento de interrupção de timer1 } } } } goto loop. // restaura contexto e sai da int. } 56 Linguagem C para PIC . } else // É int de tmr0 ? // sim.

2. 3. aproveite para gerar novos problemas e soluções.35 .1. Linguagem C para PIC 57 .Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. seguindo os exercícios propostos: 1. 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. Altere a rotina de temporização para que o timer seja decrementado a cada 1 minuto.

36 .Anotações 58 Linguagem C para PIC .1.

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

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.1.39 .

Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS. PORTAS.? SIM Trata Botão ENTER NÃO Recarrega Filtro dos Botões Linguagem C para PIC 61 .40 .1. 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. W ATCHDOG. PRESCALER.? SIM Trata Botão Menu NÃO BOTÃO ENTER PRESS.

Se não: Apaga o led 2. NÃO FIM DA INT ERRUPÇÃO 62 Linguagem C para PIC . limpa o flag "f_tela_principal".out da tela principal SIM Incrementa contador de time out. 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. para liberar atualização da tela principal. após 5 segundos.

coluna 0 do LCD A Linguagem C para PIC 63 .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 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 .

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 .Seleção da Tela de Enter Switch Case SIM Tela 1 do Enter ? Carrega a tela de controle de leds.

com.nocpd. // 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 . o botão Enter seleciona a tarefa e funciona como controle de liga/desliga para a tarefa selecionada.br * E-MAIL: cursos@labtools. Os botões S1 e S2 são respectivamente botão Menu e Enter.labtools.noprotect.nolvp. existe também uma rotina de inicialização necessária para a correta configuração do LCD.h> // microcontrolador utilizado /* * * * * // O //os //de #include /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.LABTOOLS * * TEL: (0XX11) 4992-8775 SITE: www.temp1. <16f877A.nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi elaborado para explicar o funcionamento do módulo de LCD. // registrador de flags int contador_tela = 0.41 . RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção. Foi criada uma rotina para escrever comandos e uma para escrever caracteres. #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. // contador para seleção de tela int time_out = 0. o botão Menu seleciona a tarefa que desejamos executar (controle de Leds ou do Ventilador).Código /* * * * * * * * * * * * /* * * // // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C . // inicia filtro dos botões int flags1 = 0.Recursos Básicos de programação * Exemplo 6 * * CENTRO DE CAPACITAÇÃO .put. // registrador para contagem de tempo de time-out int contador.brownout. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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.1.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.temp2.com. sem a necessidade redigitação. long int filtro = t_filtro.wdt.

enable = 0.1 buzzer = porta.0 enable = porte. enable = 1. enable = 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.3 // led ventilador = portc. } // // // // // // 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. enable = 0. // Estado do botão menu // 1 -> Liberado // 0 -> Pressionado // Estado do botão enter // 1 -> Liberado // 0 -> Pressionado = portb. #bit #bit #bit #bit #bit #bit rs = porte. #bit f_tela_principal = /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit menu flags1. portd = caracter. delay_us(40).1 led1 = portb.0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware.#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. } * // // // // // // 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 .1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // AS SAÍDAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAÇÃO E //FUTURAS ALTERAÇÕES DO HARDWARE.0 #bit enter = portb. delay_us(1). portd = caracter. delay_us(40). delay_us(1).2 // led led2 = portb.

// imprime mensagem no lcd f_tela_principal = 1. } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { comando_lcd(0x80). coluna 0 printf (escreve_lcd. comando_lcd(0x0c). // imprime mensagem no lcd comando_lcd(0xC0). conta_bip = tempo / periodo. delay_ms(periodo/2). } * // limpa lcd /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicialização do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30). } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função de Bip´s * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void bip(long int tempo. 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 . limpa_lcd(). delay_ms(4). comando_lcd(0x38). // 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. " Press Menu "). buzzer = 0. long int periodo) { long int conta_bip. comando_lcd(0x30)./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01). // posiciona o cursor na linha 0. while (conta_bip) { buzzer = 1. delay_ms (2). delay_ms(periodo/2). 8 bits. "Seleciona Tarefa"). // posiciona o cursor na linha 1. coluna 2 printf (escreve_lcd. comando_lcd(0x06). // indica que a tecla foi atualizada time_out = 0. conta_bip--. matriz de 7x5. delay_us(100). comando_lcd(0x30).

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

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

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

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

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

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

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

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.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. funções do compilador para controle do conversor analógico digital (cap.44 .11-pág 206 do livro Programação em C).Recursos Avançados: Exemplo 7 1. Para que possamos visualizar o valor de 0 à 5V no LCD. 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. 1. É convertido o valor analógico presente no pino RA1 do microcontrolador. 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 . Neste exemplo foi utilizado variável do tipo float para armazenar o resultado da conversão A/D.45 . foi feita uma segunda conversão o valor digital foi convertido para “Volts” realizando uma regra de 3.

1.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 .Esquema Elétrico +5V P2 10K + LM358 4.46 .

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 .47 . WATCHDOG.RA1 e RA3 como entradas analógicas. Configura AD: RA0.Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS. PORTAS. PRESCALER.

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 .

labtools.br * * E-MAIL: cursos@labtools.48 .com.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.nolvp. O valor da conversão // A/D é ajustado numa escala de 0 à 5V e mostrado no LCD. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa.brownout.1.LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.com.nocpd. /* * * * * // 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. sem a necessidade redigitação. #include <16f877A. // armazena o resultado da conversão AD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição e inicialização dos port's * 82 Linguagem C para PIC .put.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C .wdt. É convertido o valor analógico // presente no pino RA2 do microcontrolador.noprotect. sendo que este valor pode ser // alterado através do potenciômetro P2 da placa MCLAB2.Recursos Avançados de programação * Exemplo 7 * * CENTRO DE CAPACITAÇÃO . float conversao = 0.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1.h> // microcontrolador utilizado #device adc=10 // configura AD para retornar valor em 10 bits /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt.nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definições para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000. RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definição de constantes facilita a programação e a manutenção.

0 #bit enable = porte. delay_us(40). delay_us(1). /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As saídas devem ser associadas a nomes para facilitar a programação e //futuras alterações do hardware.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. #bit rs = porte. } // // // // // 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 . portd = caracter. } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01).* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #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. enable = 0. enable = 0. portd = caracter. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware. enable = 1. delay_ms (2). delay_us(40). delay_us(1). enable = 1 . } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1.

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

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

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

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

ou seja.200 e 201 do livro Programação em C).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. estude o funcionamento do Módulo CCP para um melhor aproveitamento. determina o período do pulso do PWM. pág. Através do botão S1.9990 Então antes de utilizar o PWM. 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). funções do compilador para controle do PWM (cap. o valor ajustado poderá ser salvo na memória EEPROM e restaurado através dos botões. 1023 / 1024 = 0. T = [(PR2 + 1) * 4] * Tosc * Prescaler TMR2 A função set_pwm_duty(valor). o PWM é incrementado e decrementado pelo botão S2.11. diretiva #ROM (cap.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.11. funções do compilador para operação com EEPROM (cap.167 do livro Programação em C) e função de manipulação de registradores make8 e make16 (cap.10 pág.52 . Por está razão dependendo da freqüência do PWM não será possível alcançar os 100% de Duty Cyle. A velocidade do ventilador é medida em rotações por segundo. através do timer1(usado como contador) e mostrada no LCD. 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. 1. 88 Linguagem C para PIC . Este valor pode chegar a 1023.9 pág. O botão S4 salva o valor de ajuste em EEPROM e o botão S3 restaura o valor salvo atualizando o PWM. Para que possamos utilizar o PWM do PIC não podemos esquecer de configurar a freqüência do PWM no Timer2.218 do livro Programação em C).219 do livro Programação em C). DC = (valor / T).51 .10. enquanto o período do PWM pode chegar a 1024.11. pág.Recursos Avançados: Exemplo 8 Interna 1. com PR2 igual a 255. Este conhecimento pode ser adquirido através do livro Conectando o PIC.

53 .1.7K BC337 150R SIR381583F RPT38PT3F 10K 1K TACOMETRO 1K BC337 Linguagem C para PIC 89 .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.

? 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 . 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.? T rata B otão U P N ÃO BO T ÃO D O W N P R ES S . P O R T AS .1.54 . P R E SC A LE R .Fluxograma M A IN C O N FIG U R AÇ Õ E S IN IC IAIS T R IS . W A T C H D O G .

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 .

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

1 #bit botao3 = portb. portd = caracter. delay_us(40). } // // // // // seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable // espera mínimo 40 microsegundos 94 Linguagem C para PIC .0 #bit botao2 = portb.2 #bit botao4 = portb./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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(1). #bit rs = porte. #bit atualiza_lcd = flags1. enable = 1 .3 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As saídas devem ser associadas a nomes para facilitar a programação e //futuras alterações do hardware.0 #bit enable = porte. enable = 0.0 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações #bit * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware. // 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.1 #bit ventilador = portc.

// posiciona o cursor na linha 1. // envia dados para o display de LCD comando_lcd(0xcb). rotacao). delay_ms(4). delay_us(40). } // // // // // 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). comando_lcd(0x30). portd = caracter. "Duty cycle RPS"). comando_lcd(0x06). coluna 3 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. delay_ms (2). enable = 1."%" "3Lu%%". duty_cycle1). coluna 0 printf (escreve_lcd. limpa_lcd(). comando_lcd(0x0c). enable = 0. delay_us(1). comando_lcd(0x38)./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1. delay_us(100). } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01). coluna 11 printf (escreve_lcd. comando_lcd(0x30). // posiciona o cursor na linha 1. } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para imprimir a Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { comando_lcd(0x80)."%" "3Lu". sem cursor e sem blink // limpa lcd // display sem cursor // desloca cursor para a direita Linguagem C para PIC 95 . // imprime mensagem no lcd comando_lcd(0xc3). // posiciona o cursor na linha 0.

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

periodo_pulso = dado.1). // retorna byte_low salva_dados(). // carrega valor da rotação medida duty_cycle = (duty_cycle / 1024). // efetua cálculo do duty cycle duty_cycle = (duty_cycle * 100). // salva byte_low } filtro = t_filtro. // lê byte_high da eeprom periodo_pulso = make16(dado. // salva byte_high end = 1. atualiza_lcd = 1. // converte para porcentagem (%) duty_cycle1 = (long int) duty_cycle. 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). // carrega os 16 bits menos significativos da parte inteira // do resultado da converão tela_principal().{ duty_cycle = periodo_pulso. // testa botão 3 // lê byte_low da eeprom // carrega valor lido em variável de 16 bits // testa botão 2 trata_dowm. } // carrega filtro dos botões // fecha while //* * * * * * * * * * * Incrementa duty cycle do PWM * * * * * * * * * * trata_up: { filtro --. // desvia para a rotina de incremento do PWM le_dados(0). // desvia para a rotina de decremento do PWM // testa botão 1 trata_up. // recompõe o dado de 16 bits atualiza_pwm(). turbo = 1. // endereço do byte_low dado = make8(periodo_pulso. // endereço do byte_high dado = make8(periodo_pulso. atualiza_lcd = 0. // retorna byte_high salva_dados(). } // 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. // decrementa o filtro if (filtro == 0) // fim do filtro do botão? { Linguagem C para PIC 97 .0).

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

Linguagem C para PIC 99 .Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido.56 . seguindo os exercícios propostos: 1.1. Ative os dois PWM`s um para o ventilador e outro para a resistência. 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.

57 .Anotações 100 Linguagem C para PIC .1.

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

60 .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.Esquema Elétrico +5V P2 10K + 4.

W ATCHDOG. 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 .61 .Fluxograma MAIN CONFIGURAÇÕES INICIAIS TRIS. Configuração: AD. PRESCALER.1. PORTAS.

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 .

.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." Aguarda novo comando do PC delay de 5 segundos Escreve no LCD: "Press Inicio" delay de 1 segundo Return 106 Linguagem C para PIC ..

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 .

nowrt fusíveis // configuração dos /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definição para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000.com.LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.1.nolvp.nocpd. parar_coleta }tarefa. O PC controlará as funções do coletor de dados. estes dados serão enviados ao PC para a // visualização dos mesmos. RESTART_WDT.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações para gravação * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt. SLOW.sda=pin_c4.brownout.put.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSÃO : 1. #include <16f877A.Código /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programação em C .wdt.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrição geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este exemplo foi elaborado para explicar as funcões de I2C do compilador // CCS. coleta_de_dados. #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. xmit = pin_c6. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Linguagem C para PIC 109 .62 . 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. scl=pin_c3.br * * E-MAIL: cursos@labtools.noprotect.labtools.Recursos Avançados de programação * * Exemplo 9 * * * * CENTRO DE CAPACITAÇÃO . 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. transmite_para_pc.com.

i2c_stop().0 // via do lcd que sinaliza recepção de dados ou comando #bit enable = porte. i2c_write(ctrl_escr). static int comando = 0. static int flags1 = 0.* Definição e inicialização das variáveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco estão definidas as variáveis globais do programa. i2c_write(end_low). delay_ms(10). /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SAÍDAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As saídas devem ser associadas a nomes para facilitar a programação e //futuras alterações do hardware.1 // enable do lcd /* * * * * * * * * * * * * Função * * * * * * * * * * * * escr_mem_serial () { i2c_start(). #bit rs = porte. i2c_write(dado). i2c_write(end_low). #bit atualiza_lcd = flags1. // flags static int dado = 0. i2c_start(). i2c_write(ctrl_le). i2c_stop(). } /* * * * * * * * * * * * * Função * * * * * * * * * * * * le_mem_serial () { i2c_start(). i2c_write(ctrl_escr).0 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alterações * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programação e do hardware. static int tx_pc. } * * * * * * * * * * * * * * * * * * * * * * * * * * 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 . static int end_low = 0. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. dado = i2c_read(0).

comando_lcd(0x30). } * // // // // // 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). // posiciona o cursor na linha 0. coluna 0 printf (escreve_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.* Função que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0. delay_ms (2). enable = 0. delay_us(1). limpa_lcd(). portd = caracter. } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1. delay_us(1). comando_lcd(0x30). delay_us(40). comando_lcd(0x0c). comando_lcd(0x38). } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Função para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01). "Coletor de dados"). enable = 0. delay_us(40). portd = caracter. comando_lcd(0x06). enable = 1 . delay_us(100). // imprime mensagem no lcd } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina para coleta de dados * Linguagem C para PIC 111 . enable = 1. delay_ms(4). 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).

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

set_tris_a(0b11111111). inicializa_lcd(). set_tris_d(0b00000000). carrega endereço inicial coleta_dados(). setup_adc (adc_clock_div_8). // fim da coleta de dados tx_dados_pc(). porta=0x00. portd=0x00. if (tarefa == coleta_de_dados) // inicia coleta de dados ? { end_low = 0. set_tris_b(0b11111111). set_adc_channel (1). portc=0x00. portb=0x00. // incia o watch-dog timer recebe_comando(). // sim. carrega endereço inicial tx_dados_pc(). porte=0x00. tela_principal(). set_tris_e(0b00000100).* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (RA0_RA1_RA3_analog). // sim. WDT_2304MS). // executa função de transmissão de dados } if (tarefa == parar_coleta) // cancela coleta de dados ? { end_low = 0. // executa função de coleta de dados } if (tarefa == transmite_para_pc)// inicia transmissão de dados para o PC ? { end_low = 0. // espera envio de comando do PC tx_pc = 11. // sim. setup_counters (rtcc_internal. // envia comando para o PC } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Linguagem C para PIC 113 . // 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(). carrega endereço inicial tarefa = aguarda_comando. set_tris_c(0b10110111).

2. Implemente a regra de três necessária. seguindo os exercícios propostos: 1.63 . 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. 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.1.Exercícios Propostos Agora que o exemplo já foi estudado e esclarecido. 114 Linguagem C para PIC .

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

Fluxograma MAIN CO NFIG URAÇÕ ES INICIAIS TRIS.68 . W ATCHDO G .01 118 Linguagem C para PIC . PO RTAS.1. 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. PRESCALER.

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

porta=0x00. set_tris_b(0b11111111). portc=0x00.// tmr0 clock interno. ps: 1:64 set_tris_a(0b11111111).01. // incrementa x } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 120 Linguagem C para PIC . wdt_2304ms). * * */ 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. portd=0x00. while(x < 2*PI) { restart_wdt(). // 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. * * */ E /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurações do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs).3f\r\n". // calculo da função printf ("X=%1. // desliga as entradas analógicas setup_counters (rtcc_internal.3f". portb=0x00. set_tris_c(0b11111111). // envia ao PC o valor de y x = x + 0. set_tris_d(0b11111111).x).y)./* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. // limpa wdt y = sin (x). // envia ao PC o valor de x printf (" "). printf ("Y=%1. porte=0x00. set_tris_e(0b00000111).

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

Anotações 122 Linguagem C para PIC .1.72 .

Sign up to vote on this title
UsefulNot useful