Escolar Documentos
Profissional Documentos
Cultura Documentos
Roteiros de Experiencias
PIC 16F877A
COMPILADOR CCSC
Sumrio
SUMRIO .....................................................................................................................................................................3 RECURSOS BSICOS: EXEMPLO 1 BOTO E LED ............................................................................................5 RECURSOS DO LIVRO ..................................................................................................................................................5 LGICA DO EXEMPLO ...................................................................................................................................................5 ESQUEMA ELTRICO....................................................................................................................................................6 FLUXOGRAMA ..............................................................................................................................................................7 CDIGO ......................................................................................................................................................................8 EXERCCIOS PROPOSTOS ..........................................................................................................................................10 ANOTAES ..............................................................................................................................................................11 RECURSOS BSICOS: EXEMPLO 2 PISCA PISCA VARIVEL .....................................................................13 RECURSOS DO LIVRO ................................................................................................................................................13 LGICA DO EXEMPLO .................................................................................................................................................13 ESQUEMA ELTRICO..................................................................................................................................................14 FLUXOGRAMA ............................................................................................................................................................15 CDIGO ....................................................................................................................................................................16 EXERCCIOS PROPOSTOS ..........................................................................................................................................18 ANOTAES ..............................................................................................................................................................19 RECURSOS BSICOS: EXEMPLO 3 CONTADOR HEXADECIMAL ..................................................................20 RECURSOS DO LIVRO ................................................................................................................................................20 LGICA DO EXEMPLO .................................................................................................................................................20 ESQUEMA ELTRICO..................................................................................................................................................21 FLUXOGRAMA ............................................................................................................................................................22 CDIGO ....................................................................................................................................................................25 EXERCCIOS PROPOSTOS ..........................................................................................................................................28 ANOTAES ..............................................................................................................................................................29 RECURSOS AVANADOS: EXEMPLO 4 MAXIMIZAO DE PINOS DE I/O...................................................30 RECURSOS DO LIVRO ................................................................................................................................................30 LGICA DO EXEMPLO .................................................................................................................................................30 ESQUEMA ELTRICO..................................................................................................................................................31 FLUXOGRAMA ............................................................................................................................................................32 CDIGO ....................................................................................................................................................................36 EXERCCIOS PROPOSTOS ..........................................................................................................................................40 ANOTAES ..............................................................................................................................................................41 RECURSOS AVANADOS: EXEMPLO 5 VARREDURA DE DISPLAY .............................................................42 RECURSOS DO LIVRO ................................................................................................................................................42 LGICA DO EXEMPLO .................................................................................................................................................42 ESQUEMA ELTRICO..................................................................................................................................................44 FLUXOGRAMA ............................................................................................................................................................45 CDIGO ....................................................................................................................................................................50 EXERCCIOS PROPOSTOS ..........................................................................................................................................57 ANOTAES ..............................................................................................................................................................58 RECURSOS AVANADOS: EXEMPLO 6 CONTROLE DO LCD ............................................................................59 RECURSOS DO LIVRO ................................................................................................................................................59 LGICA DO EXEMPLO .................................................................................................................................................59 ESQUEMA ELTRICO..................................................................................................................................................60 FLUXOGRAMA ............................................................................................................................................................61 CDIGO ....................................................................................................................................................................68 EXERCCIOS PROPOSTOS ..........................................................................................................................................76 ANOTAES ..............................................................................................................................................................77 RECURSOS AVANADOS: EXEMPLO 7 CONVERSOR ANALGICO DIGITAL..............................................78 RECURSOS DO LIVRO ................................................................................................................................................78 LGICA DO EXEMPLO .................................................................................................................................................78 Linguagem C para PIC 3
ESQUEMA ELTRICO..................................................................................................................................................79 FLUXOGRAMA ............................................................................................................................................................80 CDIGO ....................................................................................................................................................................82 EXERCCIOS PROPOSTOS ..........................................................................................................................................86 ANOTAES ..............................................................................................................................................................87 RECURSOS AVANADOS: EXEMPLO 8 CONTROLE DO PWM E EEPROM INTERNA ..................................88 RECURSOS DO LIVRO ................................................................................................................................................88 LGICA DO EXEMPLO .................................................................................................................................................88 ESQUEMA ELTRICO..................................................................................................................................................89 FLUXOGRAMA ............................................................................................................................................................90 CDIGO ....................................................................................................................................................................93 EXERCCIOS PROPOSTOS ..........................................................................................................................................99 ANOTAES ............................................................................................................................................................100 RECURSOS AVANADOS: EXEMPLO 9 COLETOR DE DADOS ....................................................................101 RECURSOS DO LIVRO ..............................................................................................................................................101 LGICA DO EXEMPLO ...............................................................................................................................................101 ESQUEMA ELTRICO................................................................................................................................................102 FLUXOGRAMA ..........................................................................................................................................................103 CDIGO ..................................................................................................................................................................109 EXERCCIOS PROPOSTOS ........................................................................................................................................114 ANOTAES ............................................................................................................................................................115 RECURSOS AVANADOS: EXEMPLO 10 FUNES MATEMTICAS..............................................................116 RECURSOS DO LIVRO ..............................................................................................................................................116 LGICA DO EXEMPLO ...............................................................................................................................................116 ESQUEMA ELTRICO................................................................................................................................................117 FLUXOGRAMA ..........................................................................................................................................................118 CDIGO .................................................................................................................................................................119 EXERCCIOS PROPOSTOS ........................................................................................................................................121 ANOTAES ............................................................................................................................................................122
Boto e Led
Para o bom entendimento deste nosso primeiro exemplo so necessrios os conhecimentos de programao em linguagem C, comandos de controle de Fluxo (cap.7 do livro Programao em C), declarao de variveis, constantes e tipos de dados (cap.5 do livro Programao em C), diretivas de configurao dos pinos de I/O (cap.10-pg.170, cap.11.5; 11.6-pg.202; 11.7 e cap.12.2-pg. 250 do livro Programao em C).
+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
1.4 - Fluxograma
MAIN
A LIMPA WATCHDOG
NO
BOTO S1 PRESS.?
SIM
APAGA LED L2
ACENDE LED L2
1.5 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * * Exemplo 1 * * * * CENTRO DE CAPACITAO - LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * Este software est preparado para demonstrar o controle este primeiro programa demonstrar o estado de um boto * * * * * * * * * * * * * * * * */ dos pinos de I/O por meio de um led.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. //Este programa no utiliza nenhuma varivel de usurio /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. //Este programa no utiliza nenhuma constante de usurio /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. //Este programa no utiliza nenhum flag de usurio /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use #use #use #use #use #byte #byte #byte #byte #byte fast_io(a) fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09
* * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. // Estado do boto // 1 -> Liberado // 0 -> Pressionado
* * */ e
botao = portb.0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // As sadas devem ser associadas a nomes para facilitar a programao //futuras alteraes do Hardware. #bit led = portb.1 // Led correspondente ao boto // 1 -> Led ligado // 0 -> Led desligado
* * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { setup_counters(RTCC_INTERNAL, WDT_2304MS); set_tris_a(0b11111111); set_tris_b(0b11111101); set_tris_c(0b11111111); set_tris_d(0b11111111); set_tris_e(0b00000111); porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00; // // // // // // configurao dos pinos de I/O
// testa boto // Se boto = 0, ento led = 1 // caso contrrio, led = 0 // FIM DO PROGRAMA
1.6 -
1.8 - Anotaes
11
Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos no exemplo 1 e mais, funes do compilador para controle de atraso (cap.11.4 pg. 195 do livro Programao em C), Operadores para criao de expresses lgicas e aritmticas (cap.6 do livro Programao em C), diretivas de configurao para uso de funo de atraso (cap.10, pg.169 do livro Programao em C).
13
+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
1.12 - Fluxograma
A MAIN
NO
BOTO S1 PRESS.?
SIM
SIM
TEMPO = MAX?
NO
SIM
TEMPO = MIN?
NO
DECREMENTA TEMPO
NO
CONTADOR 0
15
1.13 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * * Exemplo 2 * * * * CENTRO DE CAPACITAO - LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Este software demonstrar a utilizao da funo de delay e //a frequncia de oscilao dos leds controlada pelos botes * * * * * * * * * * * * */ a inverso de portas S1 (UP) e S2 (DOWN).
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio das variveis internas do PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt // configurao dos fusveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT) // diretiva para o uso da funo delay /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int contador = 0 ; int tempo = 9; /* * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * //A definio de constantes facilita a programao //Este programa no utiliza constantes #define max 255 // Limite de ajuste do #define min 10 * * * * * * * * * * * * * * * * * * * * * * * * */ e a manuteno. tempo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. //Este programa no utiliza nenhum flag de usurio. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte porta portb portc portd = = = = 0x05 0x06 0x07 0x08
#byte porte = 0x09 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit botao_0 #bit botao_1
* * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. = portb.0 // Estado do boto_0 // 1 -> Liberado // 0 -> Pressionado = portb.1 // Estado do boto_1 // 1 -> Liberado // 0 -> Pressionado
* * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // As sadas devem ser associadas a nomes para facilitar a programao //futuras alteraes do hardware.
* * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { setup_counters(rtcc_internal,wdt_2304ms); set_tris_a(0b11111111); set_tris_b(0b11110011); set_tris_c(0b11111111); set_tris_d(0b11111111); set_tris_e(0b00000111); porta portb portc portd porte = = = = = 0x00; 0x0f; 0x00; 0x00; 0x00; // carrega portb com valor inicial
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { RESTART_WDT(); portb = ~portb; if (!botao_0) // { if (tempo != max) // { tempo = tempo + 1; // } } // // complemanta o portb O boto_0 foi pressionado? sim, tempo diferente de max? no, incrementa tempo boto_0 liberado, testa boto 1
if (!botao_1) // O boto 1 foi pressionado ? { if (tempo != min) // sim, tempo diferente de min? { tempo = tempo - 1; // no, decrementa tempo } } // boto_1 liberado contador = tempo; // carrega contador for (;contador!=0; contador--) // contador diferente de 0? se sim // decrementa contador e executa o comando delay_ms(10); // comando: delay de 10 milisegundos. } } // FIM DO PROGRAMA
17
1.15 - Anotaes
19
Contador Hexadecimal
Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos nos exemplos anteriores e tabela de constante (cap.12.21 pg. 309 do livro Programao em C).
MC1
MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC6
32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25
a b c d e f g Dp
DS4
a f e d g b c Dp
220R 4,7K
BC337
+5V
4MHz
16 17 18 23 24
16F877A
+5V
+5V
10K
10K
RB0 S1
RB1 S2
PIC16F877
21
1.19 - Fluxograma
MAIN
NO
BOTO S1 PRESS.?
SIM
SIM
NO
NO
Filtro 0 ?
SIM
Decrementa o Filtro NO
Contador Max ?
23
NO
BOTO S2 PRESS.?
SIM
SIM
NO
NO
Filtro 0 ?
SIM
Decrementa o Filtro NO
Contador Min ?
1.20 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 3 * * CENTRO DE CAPACITAO - LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * // // * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Contador hexadecimal que utiliza dois botes para incrementar e decrementar o valor da varivel "contador". O contador est limitado pelas constantes min e max.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <16f877A.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt // configurao dos fusveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 400 #define min 0 #define max 15 // tamanho do filtro // valor mnimo para o contador // valor mximo para o contador
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int contador=min; // long int filtro0=t_filtro; // long int filtro1=t_filtro; // int flags=0; // inicia contador com mnimo inicia filtro do bot1 inicia filtro do bot2 limpa os flags
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. #bit bt_UP_press = flags.0 #bit bt_DOWN_press = flags.1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e)
25
= = = = =
0x05 0x06 0x07 0x08 0x09 * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. // Estado do boto UP // 1 -> Liberado // 0 -> Pressionado * * */ e
botao_UP = portb.0
#bit
/* * * // //
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * As sadas devem ser associadas a nomes para facilitar a programao futuras alteraes do hardware.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ byte const tabela[16] = { //PGFEDCBA ; POSIO RELATIVA AOS SEGMENTOS 0b00111111, // 0H - 0 0b00000110, // 1H - 1 0b01011011, // 2H - 2 0b01001111, // 3H - 3 0b01100110, // 4H - 4 0b01101101, // 5H - 5 0b01111101, // 6H - 6 0b00000111, // 7H - 7 0b01111111, // 8H - 8 0b01101111, // 9H - 9 0b01110111, // AH - A 0b01111100, // BH - B 0b00111001, // CH - C 0b01011110, // DH - D 0b01111001, // EH - E 0b01110001}; // FH - F /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_counters(rtcc_internal, wdt_2304ms); set_tris_a(0b11111111); set_tris_b(0b11101111); set_tris_c(0b11111111); set_tris_d(0b00000000); set_tris_e(0b00000111); porta = 0x00; portb=(0b00010000); // seleciona display ds4 portc = 0x00; portd = (tabela[contador]); // mostra no display valor inicial do contador porte = 0x00;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog timer /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao_UP) // O boto UP est pressionado ? { // sim, if (!(bt_UP_press)) // O boto UP j foi tratato ? { // no. if (filtro0 !=0) // Fim do filtro do boto UP ? { filtro0--; // No, ento decrementa o filtro } else // Sim, Faz a ao do boto { bt_UP_press = 1; // Marca que o boto est pressionado if (contador != max) { contador++; // incrementa o contador portd = (tabela[contador]); // consulta tabela, atualiza // display } } } } else { // boto 0 liberado filtro0 = t_filtro; // inicia o filtro do boto 0 bt_UP_press = 0; // marca que o boto foi liberado } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao_DOWN) // testa boto DOWN { // boto DOWN pressionado if (!(bt_DOWN_press)) // o boto DOWN j foi tratato ? { // no if (filtro1 !=0) // Fim do filtro do boto DOWN ? { filtro1--; // no, ento decrementa o filtro } else // SIM. Faz a ao do boto { bt_DOWN_press = 1; // marca que o boto est pressionado if (contador != min) { contador--; // decrementa o contador portd = (tabela[contador]);// consulta tabela, atualiza // display } } } } else { // boto 1 liberado filtro1 = t_filtro; // inicia o filtro do boto 1 bt_DOWN_press = 0; // marca que o boto foi liberado } } }
27
1.22 - Anotaes
29
Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos nos exemplos anteriores e mais, funes do compilador para controle de interrupo, tratamento automtico (cap.12 pg.254 do livro Programao em C), controle do processador (cap.11 pg.223 do livro Programao em C), manipulao de Timers (cap.11.8 pg.211 do livro Programao em C), diretivas de configurao para uso de interrupes, #int_xxx e #priority (cap.10, pg.161 e pg.166 do livro Programao em C).
Alm disso, o sistema possui um filtro, regulado pela constante FILTRO_BOTAO, para evitar o debounce da tecla. Este filtro garante que a tecla fique pressionada pelo tempo de FILTRO_BOTAO x 2048s. Quanto freqncia do buzzer, esta ser controlada por TMR2. Calibramos os valores de pre e postscale para que a freqncia da interrupo do TMR2 varie entre 100Hz e 2kHz, com a variao de PR2 entre 16 e 240: Ciclo de Mq. 1 s 1 s Prescale 16 16 Postscale 1 1 PR2 16 240 Perodo 256 s 3840 s Freqncia 3906 Hz 260 Hz
Para facilitar a implementao, a cada interrupo inverteremos o estado do pino de acionamento do buzzer. Desta forma, a freqncia deste ser equivalente metade da freqncia da interrupo do TMR2. O Livro Conectando o PIC, possui um cpitulo dedicado a este assunto.
+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
31
1.26 - Fluxograma
MAIN
LIGA AS INTERRUPES
LIMPA WATCHDOG
INTERRUPES
NO
INT DE TMR0?
SIM
Trata TMR2
Trata TMR0
TRATA TMR2
NO
SIM
FIM DA INTERRUPO
33
TRATA TMR0
CHECA BOTO S1 NO
Reinicia Filtro
Boto S1 PRESS ?
SIM
Fim do Filtro ?
NO
CHECA BOTO S2
CHECA BOTO S3
CHECA BOTO S4
AO DOS BOTES
NO
SIM
Inicializa TMR2
FIM DA INTERRUPO
35
1.27 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 4 * * CENTRO DE CAPACITAO - LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Este software est preparado para ler quatro botes e //durao variavel conforme a tecla pressionada, alm de //indicando a ltima tecla pressionada. * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 20 // tamanho do filtro
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int status_botoes = 0; int status_leds = 0; int per = 0; int int int int filtro1 filtro2 filtro3 filtro4 = = = = t_filtro; t_filtro; t_filtro; t_filtro; // armazena o estado lgico dos botes // atualiza leds conforme o boto pressionado // limitador de contagem do Timer2 // // // // inicia inicia inicia inicia filtro filtro filtro filtro do do do do botao1 botao2 botao3 botao4
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use #use #use #use #use #byte #byte #byte #byte #byte fast_io(a) fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. * * */ e
botao1 = status_botoes.0 // Estado do boto 1 // 1 -> Liberado // 0 -> Pressionado botao2 = status_botoes.1 // Estado do boto 2 // 1 -> Liberado // 0 -> Pressionado botao3 = status_botoes.2// Estado do boto 3 // 1 -> Liberado // 0 -> Pressionado botao4 = status_botoes.3 // Estado do boto 4 // 1 -> Liberado // 0 -> Pressionado * * */ E
#bit
#bit
#bit
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO //FUTURAS ALTERAES DO HARDWARE. #bit #bit #bit #bit #bit botao1_press botao2_press botao3_press botao4_press = = = = status_leds.0 status_leds.1 status_leds.2 status_leds.3
buzzer = porta.5
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ byte const tabela[16] = {255,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurao do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // A rotina principal simplesmente limpa o WDT, pois toda a lgica do // programa tratada dentro das interrupes. void main() { setup_adc_ports (no_analogs); setup_counters(rtcc_internal , rtcc_div_8); setup_timer_2 (t2_div_by_16,per,1); set_tris_a(0b11011111); set_tris_b(0b11110000); set_tris_c(0b11111111); set_tris_d(0b11111111); set_tris_e(0b00000111); porta=(0b00000000); portb=(0b00000000); portc=(0b00000000); portd=(0b00000000); porte=(0b00000000); enable_interrupts(GLOBAL); enable_interrupts(INT_RTCC); #priority timer0,timer2
37
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog timer } } /* * * // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Esta interrupo ocorrer a cada 2048us. O filtro dos botes tem durao de 40ms (2048us x 20) e so decrementados a cada interrupo. Esta interrupo responsvel por converter os pinos dos botes em entrada, salvar a condio dos botes em varivel temporria e converter os pinos em sada novamente.
// configura os pinos como entrada para // testar os botes // aguarda 4 ciclos de mquina para a // estabilizao do portb // l o status dos botoes, salva em varivel // temporria // configura os pinos como sada para // controle dos leds
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao1) { filtro1--; if (filtro1 == 0) { botao1_press = 1; } } else { filtro1 = t_filtro; botao1_press = 0; } // // // // testa boto 1 boto 1 est pressionado ? Sim, ento decrementa o filtro acabou o filtro do boto 1 ?
// boto 1 liberado // inicia o filtro do boto 1 // marca que o boto foi liberado
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao2) { filtro2--; if (filtro2 == 0) { botao2_press = 1; } } else { filtro2 = t_filtro; botao2_press = 0; } /* * * * * * * * * * * * * * * * * * * * * Tratamento do * * * * * * * * * * * * * * * * * * * * if (!botao3) { // // // // testa boto 2 boto 2 est pressionado ? Sim, ento decrementa o filtro fim do filtro do boto 2 ?
// boto 2 liberado // inicia o filtro do boto 2 // marca que o boto foi liberado * * * * * * * * * * * * * * * * Boto 3 * * * * * * * * * * * * * * * * */ // testa boto 3 // boto 3 est pressionado ?
filtro3--; if (filtro3 == 0) { botao3_press = 1; } } else { filtro3 = t_filtro; botao3_press = 0; } /* * * * * * * * * * * * * * * * * * * * * Tratamento do * * * * * * * * * * * * * * * * * * * * if (!botao4) { filtro4--; if (filtro4 == 0) { botao4_press = 1; } } else { filtro4 = t_filtro; botao4_press = 0; }
// Sim, ento decrementa o filtro // fim do filtro do boto 3 ? // marca que o boto est pressionado
// boto 3 liberado // inicia o filtro do boto 3 // marca que o boto foi liberado * * * * * * * * * * * * * * * * Boto 4 * * * * * * * * * * * * * * * * */ // testa boto 4 // boto 4 est pressionado ? // Sim, ento decrementa o filtro // fim do filtro do boto 4 ? // marca que o boto est pressionado
// boto 4 liberado // inicia o filtro do boto 4 // marca que o boto foi liberado
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Atualiza Leds conforme botes pressionados * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ portb = status_leds; // atualiza os leds if (status_leds == 0) { per = 0xff; setup_timer_2 (t2_div_by_16,per,1); disable_interrupts (INT_TIMER2); buzzer = 0; } else { per = (tabela[status_leds]);// consulta tabela e inicializa timer2. setup_timer_2 (t2_div_by_16,per,1); enable_interrupts (INT_TIMER2); // habilita interrupo de timer2. } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Est interrupo s ir ocorrer quando alguma tecla estiver pressionada, // o periodo de ocorrncia depende do boto ou da conbinao de botes pressionados, // ela ir inverter o pino de I/O do buzzer a cada interrupo. #int_timer2 void trata_int_tmr2() { if (buzzer != 0) // o buzzer est ligado ? { buzzer = 0; // sim, ento desliga } else { buzzer = 1; // no, ento liga } }
39
1.29 - Anotaes
41
Varredura de Display
Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos nos exemplos anteriores e mais, funes do compilador para controle de interrupo, tratamento manual (cap.12 pg.254 do livro Programao em C), controle do processador (cap.11 pg.223 do livro Programao em C), manipulao de Timers (cap.11.8 pg.211 do livro Programao em C), introduo de cdigo em assembly no programa em C (cap.10, pg.151 do livro Programao em C),retorno de valores em funes assembly (cap.9, pg.147 do livro Programao em C), diretivas de configurao para uso de interrupes, #int_global e #priority (cap.10, pg.162 e pg.166 do livro Programao em C).
Os demais botes apresentam as funes de controle do temporizador: Boto S2 S3 S4 Descrio Incrementa o valor inicial em 1 segundo Decrementa o valor inicial em 1 segundo Inicia e paralisa o temporizador
Os botes de incremento e decremento operam de forma rotativa, isto , comutam automaticamente entre 0000 e 9999. Outra caracterstica destes botes que eles executam suas funes repetidamente quando mantidos pressionados e s funcionam quando o temporizador est paralisado. Ao atingir o valor zero (0000) o temporizador automaticamente paralisado, desligandose o led indicativo (L1). Para o sistema de varredura foram criadas 4 variveis para armazenamento dos dgitos mostrados nos respectivos displays: UNIDADE, DEZENA, CENTENA e MILHAR. Estas variveis representam o valor atual do temporizador e so incrementadas e decrementadas atravs dos botes. Na verdade, os botes alteram diretamente o valor da unidade. A lgica do sistema compara este valor com os limites (0 e 9) para alterar ou no os demais dgitos. A freqncia de varredura controlada pela interrupo de Timer0. Ajustamos seus parmetros para que a comutao entre displays (tempo da interrupo) seja de aproximadamente 4kHz: Ciclo de Mq. 1 s
42 Linguagem C para PIC
Prescale 1
Auxiliar -
Perodo 256 s
Freqncia 3900 Hz
A freqncia de varredura ser a freqncia de comutao dividida pelo nmero de displays, que no nosso caso ser de aproximadamente 1kHz. Dentro do tratamento da interrupo de TMR0 desligado o display atual, carregado o valor do dgito correspondente ao display e ligado o display seguinte. Quanto contagem dos segundos, utilizamos a interrupo de Timer1 para esta finalidade. Veja os ajustes dos parmetros para esta interrupo: Ciclo de Mq. 1 s Prescale 8 Conta TMR1 62500 Auxiliar 2 Perodo 1.000.000 s Freqncia 1 Hz
Para isso, configuramos o prescale de TMR1 em 1:8 e iniciamos o contador com o valor total menos o desejado para a contagem (65.536 62.500). Desta maneira a interrupo acontecer a cada 0,5 segundo. Para podermos contar 1 segundo foi criado uma varivel auxiliar denominada DIVISOR_TMR1. Cada vez que o sistema entrar na interrupo de TMR1 e o contador auxiliar (DIVISOR_TMR1) terminar, o tempo decrementado, comeando pela unidade e chegando at a milhar, se for necessrio. Quando o tempo termina (0000) tanto o led quanto o TMR1 so desligado. Neste exemplo est sendo utilizado o tratamento Manual de interrupes, neste modo ns devemos providenciar todo o cdigo necessrio para o tratamento da interrupo, tais como: salvar contexto, restaurar contexto, limpar os flags de indicao de interrupo e criar os registradores para as rotinas de salvar e restaurar contexto. A prioridade de tratamento da interrupo depende da seqncia de teste dos flags de int, que tambm de responsabilidade do programador. Para este tipo de tratamento estamos utilizando a diretiva #int global.
43
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
4,7K
4,7K
4,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
1.33 - Fluxograma
MAIN
Configura Timer1
BOTO UP PRESS.?
SIM
Trata Boto UP
NO
SIM
NO
SIM
NO
45
INTERRUPES
NO
INT DE TMR0?
SIM
SWITCH CASE Recarrega Timer1 Incrementa ponteiro de seleo de Display, desliga display do milhar, consulta tabela de converso para sete segmentos, liga display da unidade
SIM
Passou 1 segundo ?
NO
SIM
Incrementa ponteiro de seleo de Display, desliga display da unidade, consulta tabela de converso para sete segmentos, liga display da dezena
SIM
NO
Incrementa ponteiro de seleo de Display, desliga display da dezena, consulta tabela de converso para sete segmentos, liga display da centena
Decrementa Timer
NO
NO
SIM
Zera ponteiro de seleo de Display, desliga display da centena, consulta tabela de converso para sete segmentos, liga display do milhar
NO SIM
FIM DA INTERRUPO
Trata Boto UP
Timer Ligado ?
SIM
Timer Ligado ?
SIM
NO
NO
Decrementa Filtro
Decrementa Filtro
NO
SIM
SIM
Decrementa Turbo
Decrementa Turbo
NO
NO
SIM
SIM
Incrementa Timer
Decrementa Timer
47
NO
NO Filtro terminou ?
SIM
NO Timer ligado ?
SIM SIM Timer igual a zero ? Apaga led de indicao de Timer ligado
Carrega Timer1
Incrementa Timer
Decrementa Timer
Incrementa unidade
Decrementa unidade
NO
SIM
SIM
NO
SIM
SIM
NO
SIM
SIM
NO
SIM Milhar = 9
Return
Return
49
1.34 - Cdigo
/* * * * * * * * * * * * /* * * // // // // // // // // /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 5 * * CENTRO DE CAPACITAO - LABTOOLS * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi preparado para demonstrar o funcionamento do TIMER de 16 bits do PIC (TMR1), da varredura de displays e do tratamento manual de int. Consiste num temporizador de segundos. dois botes foram utilizados para programar o tempo da contagem. Um outro boto foi utilizado para disparar o contador. O temporizador consegue contar at 9999 segundos, de forma que os 4 displays de 7 segmentos foram necessrios. A contagem regressiva. um led indica que o temporizador est operando. Quando o sistema chega a 0000 (ZERO) o led desligado automaticamente. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ <16f877A.h> // microcontrolador utilizado
#include
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 250 // tamanho do filtro #define turbo_tecla 60 #define delta_timer1 (65536 - 62500) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. int int int int int int int int display = 0 ; contador = 2; filtro = t_filtro; turbo = 1; unidade = 9; dezena = 9; centena = 9; milhar = 9; int int int INT W_TEMP; STATUS_TEMP; FSR_TEMP; PCLATH_TEMP; // atualiza os displays // contador de interrupes de timer1 // inicia filtro dos botes // inicia turbo das teclas // varivel unidade do timer de 1 seg // varivel dezena do timer de 1 seg // varivel centena do timer de 1 seg // varivel milhar do timer de 1 seg // variveis para salvar contexto
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte #byte porta=0x05 portb=0x06 portc=0x07 portd=0x08 porte=0x09 * * * * * * * * * * * * * * * * * * * * * * */ o bit 0 do sfr pir1 bit 2 do sfr intcon o bit 0 do fsr pie1 do reg de status do reg de fsr do reg de pclath
/* * * * * * * * * * * * * * * * * * * * * * * * * * * Definio de SFR's * * * * * * * * * * * * * * * * * * * * * * * * * * #bit tmr1if = 0x0c.0 // tmr1if #bit t0if = 0x0b.2 // t0if o #bit tmr1ie = 0x8c.0 // tmr1ie #byte status = 0x03 // define endereo #byte fsr = 0x04 // define endereo #byte pclath = 0x0a // define endereo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. // Estado do boto up // 1 -> Liberado // 0 -> Pressionado // Estado do boto down // 1 -> Liberado // 0 -> Pressionado * * */ e
bt_up = portb.1
#bit
bt_down
= portb.2
#bit
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO //FUTURAS ALTERAES DO HARDWARE. #bit estado_timer = portb.0 // led de estado do timer // 1 -> timer contando // 0 -> timer parado // seleo do display unidade (0) // seleo do display dezena // seleo do display centena (2) // seleo do display milhar (3)
(1)
51
/* * * * * * * * * * * * * * * * * * * * * * * * Tabela de Valores * * * * * * * * * * * * * * * * * * * * * * * byte const converte[11] = { //PGFEDCBA 0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111, 0b00000000}; /* * * * * * * * * * * * * * Funo * * * * * * * * * * * * * decrementa_timer() { unidade --; if (unidade == 0xff) { unidade = 9; dezena --; } if (dezena == 0xff) { dezena = 9; centena --; } if (centena == 0xff) { centena = 9; milhar --; } if (milhar == 0xff) { milhar = 9; } } /* * * * * * * * * * * * * * Funo * * * * * * * * * * * * * incrementa_timer() { unidade ++; if (unidade == 10) { unidade = 0; dezena ++; } if (dezena == 10) { dezena = 0; centena ++; } if (centena == 10) { centena = 0; milhar ++; } if (milhar == 10) { milhar = 0; } }
* * * * * * * * * * * * * * * * * * * * * * * de decremento do Timer * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * de incremento do Timer * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de tratamento de interrupo de Timer1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupo ocorrer a cada 0,5 segundos, a rotina de tratamento executada a // cada 2 interrupes (contador). #inline trata_tmr1() { set_timer1(delta_timer1); // carraga timer1 tmr1if = 0; // limpa flag de interrupo contador --; // decrementa contador de interrupes if (contador == 0) { set_timer1(delta_timer1); // carraga timer1 contador = 2; // carrega contador de int decrementa_timer(); if((unidade==0)&&(dezena==0)&&(centena==0)&&(milhar==0))// timer est zerado? { estado_timer = 0; // sim, apaga o led e tmr1ie = 0; // desliga tratamento de interrupo de timer1 } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupo ocorrer a cada 256us. #inline trata_tmr0() { t0if = 0; switch(display) // incio da varredura dos displays { case 0: display++; // incrementa a varivel de varredura disp3 = 0; // desliga o display 3 portd = (converte[unidade]); // atualiza o portd disp0 = 1; // liga o display 0 break; // sai case 1: display++; // disp0 = 0; // portd = (converte[dezena]); disp1 = 1; // break; // case 2: display++; // disp1 = 0; // portd = (converte[centena]); disp2 = 1; // break; // case 3: display disp2 = portd = disp3 = break; } } = 0; // 0; // (converte[milhar]); 1; // // incrementa a varivel de varredura desliga o display 0 // atualiza o portd liga o display 1 sai incrementa a varivel de varredura desliga o display 1 // atualiza o portd liga o display 2 sai inicia a varivel de varredura desliga o display 2 // atualiza o portd liga o display 3 sai
53
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para salvar contexto * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ salva_contexto() { #asm MOVWF W_TEMP // SALVA REGISTRADOR DE TRABALHO E SWAPF STATUS,W // DE STATUS DURANTE O TRATAMENTO MOVWF STATUS_TEMP // DA INTERRUPO. MOVF FSR,W MOVWF FSR_TEMP // SALVA REGISTRADOR FSR MOVF PCLATH,W MOVWF PCLATH_TEMP // SALVA REGISTRADOR PCLATH CLRF PCLATH // LIMPA REGISTRADOR PCLATH, SELECIONA PAGINA 0 CLRF STATUS // LIMPA REGISTRADOR STATUS #endasm } /* * * * * * * * * * * * * * * * * * * * * * * * * * Funo para restaurar contexto * * * * * * * * * * * * * * * * * * * * * * * * * restaura_contexto() { #asm MOVF PCLATH_TEMP,W MOVWF PCLATH // RECUPERA REG. MOVF FSR_TEMP,W MOVWF FSR // RECUPERA REG. SWAPF STATUS_TEMP,W MOVWF STATUS // RECUPERA REG. SWAPF W_TEMP,F SWAPF W_TEMP,W // RECUPERA REG. #endasm } * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurao do Microcontrolador * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs); setup_counters(rtcc_internal, wdt_2304ms); setup_timer_1 (t1_internal | t1_div_by_8); set_tris_a(0b11111111); set_tris_b(0b00001110); set_tris_c(0b11111111); set_tris_d(0b00000000); set_tris_e(0b00000111); porta=(0b00000000); portb=(0b00000000); portc=(0b00000000); portd=(0b00000000); porte=(0b00000000); enable_interrupts(INT_RTCC ); enable_interrupts(GLOBAL); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(TRUE) { RESTART_WDT(); // rotina principal // incia o watch-dog timer
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de incremento (UP) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!bt_up) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de decremento (down) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!bt_down) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de Start / Stop * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!bt_start_stop) // testa boto start_stop { goto trata_start_stop; // desvia para a rotina para ligar ou // desligar o timer } filtro = t_filtro; turbo = 1; } //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_up: if (estado_timer == 0) // o timer est parado? { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? { turbo --; // decrementa o turbo da tecla if (turbo == 0) // sim, fim do turbo do boto ? { turbo = turbo_tecla; // carrega o turbo incrementa_timer(); // incrementa o timer } } } goto loop; //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_dowm: if (estado_timer == 0) // o timer est parado? { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? { turbo --; // decrementa o turbo da tecla if (turbo == 0) // sim, fim do turbo do boto ? { turbo = turbo_tecla; // carrega o turbo decrementa_timer(); // decrementa o timer } } } goto loop; // testa boto down trata_dowm;// desvia para a rotina de decremento do timer // testa boto up trata_up;// desvia para a rotina de incremento do timer
55
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_start_stop: if (filtro != 0) // o timer est parado? { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? { if (estado_timer != 0) // sim, o timer est ligado ? { estado_timer = 0; // indica timer parado tmr1ie = 0; // desliga o tratamento de interrupo de timer1 } else { if((unidade!=0)||(dezena!=0)||(centena!=0)||(milhar != 0)) // timer est zerado? { estado_timer = 1;// no, indica que o timer est contando contador = 2; // carrega contador auxiliar set_timer1(delta_timer1); // carrega timer 1 tmr1if = 0; // limpa flag de int tmr1 tmr1ie = 1; // liga o tratamento de interrupo de timer1 } } } } goto loop; } /* * * // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de Tratamento de interrupes * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Todo o tratamento de interrupo feito manualmente. As funes salva contexto e restaura contexto foram feitas em assembler Observe que a prioridade das interrupes realizada atravs do comando IF e a ordem do teste determina a prioridade no tratamento da interrupo.
#int_global Void trata_int() { salva_contexto();// salva os registradores antes do tratamento da int if (t0if) { trata_tmr0(); } else // int de tmr0 ? // sim, trata tmr0
// no, { if (tmr1if) // int de tmr1 ? { trata_tmr1(); // sim, trata tmr1 } } // no. // restaura contexto e sai da int.
restaura_contexto(); }
57
1.36 - Anotaes
Uma vez que a tela de controle foi escolhida, pressione a tecla enter para entrar na tela de controle, de acordo com a tela selecionada poderemos visualizar as seguintes telas: c t r d o s l e d s O N > O F F
V e n t i l a d o r O N > O F F Na tela de controle, deve se pressionar enter para escolher a opo desejada, ON ou OFF, quando a tecla for pressionada o smbolo > ser deslocado para a condio desejada.
59
7 8 9 1 0 1 1 1 2 1 3 1 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 1 OSC2 5 1 RC0 6 RC1 1 7 RC2 1 8 2 RC3 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,7K
1.40 - Fluxograma
MAIN
Configura Timer0
Inicializa LCD
Tela principal
SIM
Tela principal
NO
BOTO MENUPRESS.?
SIM
NO
SIM
NO
61
INT ERRUP ES
Temp1 = 40
SIM
NO
Controle do Led2
SIM
Verifica se o led 1 est aceso Se sim: Pisca o Led 2 a cada 1 segundo. Se no: Apaga o led 2.
NO
SIM
Incrementa contador de time out, aps 5 segundos, limpa o flag "f_tela_principal", para liberar atualizao da tela principal.
NO
Ao j foi executada ?
SIM
NO
Decrementa Filtro
SIM
Fim do Filtro ?
NO
NO
63
Ao j foi executada ?
SIM
NO
Decrementa Filtro
SIM
Fim do Filtro ?
NO
Re-inicia time-out
65
NO
NO
Return
Beep
SIM
NO
Return
SIM Tela 1 do Enter ? Carrega a tela de controle de leds. Carrega contador para tela 3
NO
SIM Tela 2 do Enter Carrega a tela de controle do Ventilador Carrega contador para tela 4
NO
SIM Tela 3 do Enter Indica estado dos leds On ou Off emite beep.
NO
NO
Return
67
1.41 - Cdigo
/* * * * * * * * * * * * /* * * // // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Bsicos de programao * Exemplo 6 * * CENTRO DE CAPACITAO - LABTOOLS * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este exemplo foi elaborado para explicar o funcionamento do mdulo de LCD. Foi criada uma rotina para escrever comandos e uma para escrever caracteres, existe tambm uma rotina de inicializao necessria para a correta configurao do LCD. Os botes S1 e S2 so respectivamente boto Menu e Enter, o boto Menu seleciona a tarefa que desejamos executar (controle de Leds ou do Ventilador), o boto Enter seleciona a tarefa e funciona como controle de liga/desliga para a tarefa selecionada. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ arquivo de definies do pic utilizado deve ser referenciado para que nomes definidos pela Microchip possam ser utilizados, sem a necessidade redigitao. <16f877A.h> // microcontrolador utilizado
/* * * * * // O //os //de
#include
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 500 // tamanho do filtro
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. long int filtro = t_filtro; // inicia filtro dos botes int flags1 = 0; // registrador de flags int contador_tela = 0; // contador para seleo de tela int time_out = 0; // registrador para contagem de tempo de time-out int contador,temp1,temp2; // variaveis para a rotina de int de Timer0 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a)
fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. #bit f_tela_principal = /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit menu flags1.0
* * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programao e do hardware. // Estado do boto menu // 1 -> Liberado // 0 -> Pressionado // Estado do boto enter // 1 -> Liberado // 0 -> Pressionado
= portb.0
#bit
enter = portb.1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO E //FUTURAS ALTERAES DO HARDWARE. #bit #bit #bit #bit #bit #bit rs = porte.0 enable = porte.1 led1 = portb.2 // led led2 = portb.3 // led ventilador = portc.1 buzzer = porta.5 // // s3 s4 // // via do lcd que sinaliza recepo de dados ou comando enable do lcd controle do ventilador controle do buzzer *
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0; portd = caracter; enable = 1 ; delay_us(1); enable = 0; delay_us(40); }
// // // // //
// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable espera mnimo 40 microsegundos
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1; portd = caracter; enable = 1; delay_us(1); enable = 0; delay_us(40); }
// // // // //
// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable espera mnimo 40 microsegundos
69
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30); delay_ms(4); comando_lcd(0x30); delay_us(100); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de Bips * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void bip(long int tempo, long int periodo) { long int conta_bip; conta_bip = tempo / periodo; while (conta_bip) { buzzer = 1; delay_ms(periodo/2); buzzer = 0; delay_ms(periodo/2); conta_bip--; } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { comando_lcd(0x80); // posiciona o cursor na linha 0, coluna 0 printf (escreve_lcd, "Seleciona Tarefa"); // imprime mensagem no lcd comando_lcd(0xC0); // posiciona o cursor na linha 1, coluna 2 printf (escreve_lcd, " Press Menu "); // imprime mensagem no lcd f_tela_principal = 1; // indica que a tecla foi atualizada time_out = 0; // re-inicia contagem do tempo de time-out } // define varivel local // contabiliza quantas vezes ter // que fazer o loop de bips // faa o loop at acabar o conta_bip
// envia comando para inicializar display // espera 4 milisengundos // envia comando para inicializar display // espera 100 microsengundos // envia comando para inicializar display // configura LCD, 8 bits, matriz de 7x5, 2 linhas // limpa lcd // display sem cursor // desloca cursor para a direita
// liga o buzzer // conta tempo para o perodo escolhido // desliga o buzzer // conta tempo para o perodo excolhido // decrementa o conta_bip
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Menu * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_menu() { limpa_lcd(); comando_lcd(0x82); // posiciona o cursor na linha 0, coluna 2 printf (escreve_lcd, "ctr dos leds"); // imprime mensagem no lcd comando_lcd(0xc2); // posiciona o cursor na linha 1, coluna 2 printf (escreve_lcd, "ctr do vent"); // imprime mensagem no lcd } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Seleo de tela aps pressionar a tecla enter * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_ctr_led() { limpa_lcd(); comando_lcd(0x82); // posiciona o cursor na linha 0, coluna 2 printf (escreve_lcd, "ctr dos leds"); // imprime mensagem no lcd comando_lcd(0xc4); printf (escreve_lcd, "ON // posiciona o cursor na linha 1, coluna 4 OFF"); // imprime mensagem no lcd *
if (!led1) { comando_lcd(0xc7); escreve_lcd(0x3e); comando_lcd(0xc3); escreve_lcd(' '); } else { comando_lcd(0xc3); escreve_lcd(0x3e); comando_lcd(0xc7); escreve_lcd(' '); } }
// // // //
posiciona o cursor na linha 1, coluna 7 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 3 envia simbolo "espao" para o lcd
// // // //
posiciona o cursor na linha 1, coluna 3 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 7 envia simbolo "espao" para o lcd
void tela_ctr_ventilador() { limpa_lcd(); comando_lcd(0x83); // posiciona o cursor na linha 0, coluna 3 printf (escreve_lcd, "Ventilador"); // imprime mensagem no lcd comando_lcd(0xc4); printf (escreve_lcd, "ON // posiciona o cursor na linha 1, coluna 4 OFF"); // imprime mensagem no lcd
if (!ventilador) { comando_lcd(0xc7); escreve_lcd(0x3e); comando_lcd(0xc3); escreve_lcd(' '); } else { comando_lcd(0xc3); escreve_lcd(0x3e); comando_lcd(0xc7); escreve_lcd(' '); } }
// // // //
posiciona o cursor na linha 1, coluna 7 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 3 envia simbolo "espao" para o lcd
// // // //
posiciona o cursor na linha 1, coluna 3 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 7 envia simbolo " " para o lcd
71
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Seleo das telas de Menu * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void sel_tela_menu() { switch(contador_tela) { case 1: tela_menu(); comando_lcd(0x80); // posiciona o cursor na linha 0, coluna 0 escreve_lcd(0x7e); // envia simbolo "seta" para o lcd break; // retorna case 2: tela_menu(); comando_lcd(0xc0); // posiciona o cursor na linha 1, coluna 0 escreve_lcd(0x7e); // envia simbolo "seta" para o lcd break; // retorna da funo } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Seleo das telas aps pressionar Enter * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void sel_tela_enter() { switch(contador_tela) { case 1: tela_ctr_led(); contador_tela = 3; break; case 2: tela_ctr_ventilador(); contador_tela = 4; break; *
// retorna da funo
// retorna da funo
case 3: if (!led1) { led1 = 1; // acende o led bip(50,2); comando_lcd(0xc3);// posiciona o cursor na escreve_lcd(0x3e);// envia simbolo "maior" comando_lcd(0xc7);// posiciona o cursor na escreve_lcd(' ');// envia simbolo "espao" } else { led1 = 0; // apaga o led comando_lcd(0xc7);// posiciona o cursor na escreve_lcd(0x3e);// envia simbolo "maior" comando_lcd(0xc3);// posiciona o cursor na escreve_lcd(' ');// envia simbolo "espao" bip(50,2); delay_ms(250); bip(50,2); } break; // retorna da funo
case 4: if (!ventilador) { bip(750,2); ventilador = 1; comando_lcd(0xc3); escreve_lcd(0x3e); comando_lcd(0xc7); escreve_lcd(' '); } else { bip(1000,2); ventilador = 0; comando_lcd(0xc7); escreve_lcd(0x3e); comando_lcd(0xc3); escreve_lcd(' '); } break; } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs); setup_counters (rtcc_internal, WDT_2304MS); set_tris_a(0b11011111); set_tris_b(0b11110011); set_tris_c(0b11111101); set_tris_d(0b00000000); set_tris_e(0b00000100); porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00; inicializa_lcd(); tela_principal(); // // // // // // configurao da direo dos pinos de I/O // desliga o ventilador posiciona o cursor na linha 1, coluna 7 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 3 envia simbolo "espao" para o lcd // retorna da funo
// // // //
// liga o ventilador posiciona o cursor na linha 1, coluna 3 envia simbolo "maior" para o lcd posiciona o cursor na linha 1, coluna 7 envia simbolo "espao" para o lcd
// // // //
enable_interrupts(INT_RTCC); enable_interrupts(GLOBAL); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog timer /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Verifica se algum boto foi pressionado * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!f_tela_principal) { tela_principal(); }
73
//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * if (!menu) { goto } //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * if (!enter) { goto } //* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * filtro = t_filtro; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto S1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ trata_menu: //ligar time - out if (filtro != 0) // Ao j foi executada? { filtro --; // no, decrementa o filtro if (filtro == 0) // fim do filtro do boto? { // sim, executa tarefa if (contador_tela < 2) // De selecionar a prxima tarefa? { contador_tela ++;// sim, incrementa contador de seleo de tarefa sel_tela_menu(); // seleciona a tela de menu time_out = 0; // re-inicia contagem do tempo de time-out } else // no, { contador_tela = 1;// Volta para a primeira tela do menu sel_tela_menu(); // carrega a tela de menu time_out = 0; // re-inicia contagem do tempo de time-out } } } goto loop; // sim, volta para o loop principal /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto S2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * trata_enter: if (filtro != 0) // Ao j foi executada? { filtro --; // no, decrementa o filtro if (filtro == 0) // fim do filtro do boto? { sel_tela_enter(); // sim, carrega a tela de seleo time_out = 0; // re-inicia contagem do tempo de } } goto loop; } * * * * * * * * * * * * * * */ // recarga da varivel filtro // testa boto 2 trata_enter;// desvia para a rotina de incremento do timer // testa boto 1 trata_menu;// desvia para a rotina de incremento do timer
de tarefa time-out
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Esta interrupo ocorrer a cada 256us. // A varivel auxiliar temp1 ser utilizada para contar 40 interrupes, // totalizando 10ms. O comando switch ser executado a cada 10ms. #int_rtcc void trata_int_tmr0() { temp1 ++; if (temp1 == 40) { temp1 = 0; switch(contador) { case 0: temp2 ++; if (temp2 == 50) { temp2 = 0; // j passou 10ms? // sim, zera contador de interrupo // seleciona tarefa // controle do led2 // passou 1 segundo? // sim, zera contador de interrupo
if (led1) // O led1 est ligado { if (!led2) // sim, o led2 est ligado? { led2 = 1; // no, liga o led2 } else { led2 = 0; // sim, desliga o led2 } } // no, ento no controla o led2 else { led2 = 0;// no, mantm o led2 desligado } } contador ++; // incrementa contador de tarefa break; // fim de execuo de execuo da tarefa case 1: // time_out = 10ms * 250 * 2 time_out ++; if (time_out == 250) // j passou 5 segundos? { time_out = 0; // sim, zera time_out contador_tela = 0; // zera contador de tela f_tela_principal = 0; // libera atual.tela principal } contador ++; // incrementa contador de tarefa break; // fim de execuo de execuo da tarefa default: contador = 0; } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // no, sai da int.
75
1.43 - Anotaes
77
Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos no exemplo 1 e mais, funes do compilador para controle do conversor analgico digital (cap.11-pg 206 do livro Programao em C).
Tenso de Referncia
+5V
P2 10K
+ LM358
4,7K
7 8 9 10 11 12 13 14
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
79
1.47 - Fluxograma
MAIN
Configura AD: RA0,RA1 e RA3 como entradas analgicas. adc = 10 bits Tenso de Refrencia interna (VDD e VSS) Frequencia de converso = fosc / 32 Selecionado Canal 1 Mdulo ligado
Inicializa LCD
LIMPA WATCHDOG
81
1.48 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Avanados de programao * Exemplo 7 * * CENTRO DE CAPACITAO - LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este exemplo foi elaborado para explicar o funcionamento do mdulo de // converso analgico digital interno do PIC. convertido o valor analgico // presente no pino RA2 do microcontrolador, sendo que este valor pode ser // alterado atravs do potencimetro P2 da placa MCLAB2. O valor da converso // A/D ajustado numa escala de 0 5V e mostrado no LCD. /* * * * * // O //os //de * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO DAS VARIVEIS INTERNAS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ arquivo de definies do pic utilizado deve ser referenciado para que nomes definidos pela Microchip possam ser utilizados, sem a necessidade redigitao.
#include <16f877A.h> // microcontrolador utilizado #device adc=10 // configura AD para retornar valor em 10 bits /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt fusveis // configurao dos
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. float conversao = 0; // armazena o resultado da converso AD /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte #byte porta portb portc portd porte = = = = = 0x05 0x06 0x07 0x08 0x09
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programao e do hardware.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #bit rs = porte.0 #bit enable = porte.1 // via do lcd que sinaliza recepo de dados ou comando // enable do lcd *
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0; portd = caracter; enable = 1 ; delay_us(1); enable = 0; delay_us(40); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1; portd = caracter; enable = 1; delay_us(1); enable = 0; delay_us(40); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01); delay_ms (2); }
// // // //
// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable
// // // //
// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable
// limpa lcd
83
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30); // envia comando para inicializar display delay_ms(4); // espera 4 milisengundos comando_lcd(0x30); // envia comando para inicializar display delay_us(100); // espera 100 microsengundos comando_lcd(0x30); // envia comando para inicializar display comando_lcd(0x38); // liga o display, sem cursor e sem blink limpa_lcd(); // limpa lcd comando_lcd(0x0c); // display sem cursor comando_lcd(0x06); // desloca cursor para a direita } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * void tela_principal() { comando_lcd(0x83); // printf (escreve_lcd, "Voltimetro"); comando_lcd(0xcd); // printf (escreve_lcd, " V"); } * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * */ posiciona o cursor na linha 0, coluna 3 // imprime mensagem no lcd posiciona o cursor na linha 1, coluna 14 // imprime mensagem no lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (RA0_RA1_RA3_analog); setup_adc (adc_clock_div_32); setup_counters (rtcc_internal, WDT_2304MS); set_adc_channel (1); // seleciona o canal 1 do AD set_tris_a(0b11111111); set_tris_b(0b11111111); set_tris_c(0b11111111); set_tris_d(0b00000000); set_tris_e(0b00000100); porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00; inicializa_lcd(); tela_principal(); // // // // // // configurao da direo dos pinos de I/O
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog timer conversao = read_adc(); // inicia converso AD conversao = (conversao * 5); // faz regra de 3 para converter o valor, conversao = (conversao / 1023); // das unidades de AD em Volts. comando_lcd(0xC2); // posiciona o cursor na linha 1, coluna 2 printf (escreve_lcd,"%1.9f", conversao);// envia dados para o display de LCD // 1 nmero inteiro e 9 casas decimais.
} } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
85
1.50 - Anotaes
87
Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos no exemplo 1 e mais, funes do compilador para controle do PWM (cap.11.9 pg.218 do livro Programao em C), funes do compilador para operao com EEPROM (cap.11.10 pg.219 do livro Programao em C), diretiva #ROM (cap.10, pg.167 do livro Programao em C) e funo de manipulao de registradores make8 e make16 (cap.11, pg.200 e 201 do livro Programao em C).
7 8 9 10 11 12 13 14
10K
RS EN
LCD +5V
RESET
10K MC1
1 2 3 4 5 6 7
+5V
VDD VSS RB7 RB6 RB5 RB4 RB3 RB2 RB1 RB0 RD7 RD6 RD5 RD4 RD3 RD2 RD1 RD0 RC7 RC6
32 31 40 39 38 37 36 35 34 33 30 29 28 27 22 21 20 19 26 25
+5V
RS EN
8 9 10 11 12 13 14 15 16 17 18
4MHz TACOMETRO
23 24
MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5
16F877A
+5V
+5V
+5V
+5V
10K
10K
10K
10K
RB0 S1
+Vcc
RB1 S2
RB2 S3
RB3 S4
1N4148
MINI VENTILADOR
+5V
+5V
4,7K
1K
BC337
89
1.54 - Fluxograma
M A IN
C O N FIG U R A E S IN IC IAIS T R IS , P O R T AS , W A T C H D O G , P R E SC A LE R .
C onfigura T im er0
Inic ializa LC D
NO
N O
BO T O D O W N P R ES S .?
S IM
T rata B oto 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
Trata Boto UP
Ao j foi executada ?
SIM
Ao j foi executada ?
SIM
NO
NO
Decrementa Filtro
Decrementa Filtro
Fim do Filtro ?
NO
Fim do Filtro ?
NO
Fim do Turbo ?
Fim do Turbo ?
91
INTERRUPES
SIM
NO
Divide varivel rotao por 7 (nmero de palhetas do ventilador) habilita atualizao do LCD
FIM DA INTERRUPO
1.55 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Avanados de programao * Exemplo 8 * * CENTRO DE CAPACITAO - LABTOOLS * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este exemplo foi elaborado para explicar o funcionamento do mdulo de // PWM e da escrita da EEPROM interna do microcontrolador. Um ventilador ter // a sua velocidade controlada atravs do PWM, o valor ajustado poder ser // salva na memria EEPROM e restaurado atravs dos botes. // A velocidade do ventilador medida em rotaes por segundo, atravs do // timer1 e mostrada no lcd. #include <16f877A.h> // microcontrolador utilizado
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializa EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #rom 0x2100 = {0x03,0xe8} // carrega eeprom com valor inicial, inicia PWM com 97% /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define t_filtro 200 #define turbo_tecla 5 // tamanho do filtro // turbo dos botes
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. float duty_cycle = 0; // armazena o resultado da converso AD long int duty_cycle1 = 0; // armazena o resultado da converso AD long int periodo_pulso = 0; // long int rotacao = 0; // rps do ventilador int end = 0; // varivel para endereamento da eeprom int flags1 = 0; // flags int filtro = t_filtro; // inicia filtro dos botes int temp1 = 125; // varivel aux para int de tmr0 int turbo = 1; // inicia turbo das teclas int dado; // varivel de dados para eeprom
93
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use #use #use #use #use #byte #byte #byte #byte #byte fast_io(a) fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta=0x05 portb=0x06 portc=0x07 portd=0x08 porte=0x09
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. #bit atualiza_lcd = flags1.0 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #bit * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programao e do hardware. // Estado do boto 2 // 1 -> Liberado // 0 -> Pressionado // Estado do boto 3 // 1 -> Liberado // 0 -> Pressionado // Estado do boto 4 // 1 -> Liberado // 0 -> Pressionado // Estado do boto 4 // 1 -> Liberado // 0 -> Pressionado
botao1 = portb.0
#bit
botao2 = portb.1
#bit
botao3 = portb.2
#bit
botao4 = portb.3
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #bit rs = porte.0 #bit enable = porte.1 #bit ventilador = portc.1 // via do lcd que sinaliza recepo de dados ou comando // enable do lcd // pino de I/O para controle do ventilador (PWM) *
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0; portd = caracter; enable = 1 ; delay_us(1); enable = 0; delay_us(40); }
// // // //
// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1; portd = caracter; enable = 1; delay_us(1); enable = 0; delay_us(40); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01); delay_ms (2); }
// // // //
// seleciona o envio de um caracter carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30); delay_ms(4); comando_lcd(0x30); delay_us(100); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para imprimir a Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { comando_lcd(0x80); // posiciona o cursor na linha 0, coluna 0 printf (escreve_lcd, "Duty cycle RPS"); // imprime mensagem no lcd comando_lcd(0xc3); // posiciona o cursor na linha 1, coluna 3 printf (escreve_lcd,"%" "3Lu%%", duty_cycle1); // envia dados para o display de LCD comando_lcd(0xcb); // posiciona o cursor na linha 1, coluna 11 printf (escreve_lcd,"%" "3Lu", rotacao); // 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, sem cursor e sem blink // limpa lcd // display sem cursor // desloca cursor para a direita
95
/* * * // //
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Salva Dados na EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ salva dado na eeprom no endereo indicado atravs da varivel "end", o dado a ser salvo passado para a Funo atravs da varivel "dado".
void salva_dados() { write_eeprom (end,dado); } /* * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * L Dados na EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ l o dado na eeprom no endereo indicado atravs da varivel "end", o dado lido carregado na varivel "dado".
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs); // desliga as entradas analgicas setup_counters (rtcc_internal, rtcc_div_64);// tmr0 clock interno, ps: 1:64 setup_timer_1 (t1_external_sync | t1_div_by_1);// tmr1 clock externo, ps: 1:1 setup_timer_2 (t2_div_by_16,255,1);// tmr2 ps=1:16, pr2=255 e postscale: 1:1 setup_ccp2(ccp_pwm); // modo PWM ligado set_pwm2_duty(periodo_pulso); // ajusta duty cycle em 0. set_tris_a(0b11111111); set_tris_b(0b11111111); set_tris_c(0b11111101); set_tris_d(0b00000000); set_tris_e(0b00000100); porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00; inicializa_lcd(); tela_principal(); enable_interrupts(INT_RTCC); enable_interrupts(GLOBAL); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * loop: while(TRUE) // rotina principal { RESTART_WDT(); // incia o watch-dog if (atualiza_lcd != 0) * * */ // configurao da direo dos pinos de I/O
// // // // //
timer
{ duty_cycle = periodo_pulso; // carrega valor da rotao medida duty_cycle = (duty_cycle / 1024); // efetua clculo do duty cycle duty_cycle = (duty_cycle * 100); // converte para porcentagem (%) duty_cycle1 = (long int) duty_cycle; // carrega os 16 bits menos significativos da parte inteira // do resultado da convero tela_principal(); atualiza_lcd = 0; } // imprime a tela principal no LCD // indica LCD atualizado
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de incremento (UP) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao1) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto de decremento (down) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao2) { goto } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto ler dados da EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao3) { le_dados(1); periodo_pulso = dado; // testa boto 3 // l byte_low da eeprom // carrega valor lido em varivel de 16 bits // testa boto 2 trata_dowm; // desvia para a rotina de decremento do PWM // testa boto 1 trata_up; // desvia para a rotina de incremento do PWM
le_dados(0); // l byte_high da eeprom periodo_pulso = make16(dado, periodo_pulso); // recompe o dado de 16 bits atualiza_pwm(); atualiza_lcd = 1; } // Funo para atualizar o PWM // habilita atualizao do LCD
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto salvar dados na EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (!botao4) // testa boto 4 { end = 0; // endereo do byte_high dado = make8(periodo_pulso,1); // retorna byte_high salva_dados(); // salva byte_high end = 1; // endereo do byte_low dado = make8(periodo_pulso,0); // retorna byte_low salva_dados(); // salva byte_low } filtro = t_filtro; turbo = 1; } // carrega filtro dos botes // fecha while
//* * * * * * * * * * * Incrementa duty cycle do PWM * * * * * * * * * * trata_up: { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? {
97
goto
turbo --; // decrementa o turbo da tecla filtro = t_filtro; if (turbo == 0) // sim, fim do turbo do boto ? { turbo = turbo_tecla; if (periodo_pulso < 1023) // limita incremento do periodo do pulso em 1023 { periodo_pulso ++; atualiza_pwm(); // Funo para atualizar o PWM atualiza_lcd = 1; // habilita atualizao do LCD } } } } loop;
//* * * * * * * * * * * Decrementa duty cycle do PWM * * * * * * * * * * trata_dowm: { filtro --; // decrementa o filtro if (filtro == 0) // fim do filtro do boto? { turbo --; // decrementa o turbo da tecla filtro = t_filtro; if (turbo == 0) // sim, fim do turbo do boto ? { turbo = turbo_tecla; if (periodo_pulso != 0) // limita decremento do periodo do pulso em 0 { periodo_pulso --; atualiza_pwm(); // Funo para atualizar o PWM atualiza_lcd = 1; // habilita atualizao do LCD } } } } goto loop; } /* * * // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR0 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Esta interrupo ocorrer a cada 8ms. A varivel auxiliar temp1 ser utilizada para contar 125 interrupes, totalizando 1 segundo. Quando isto ocorrer, a varivel rotao ser carregada com o valor de rotaes por segundo do ventilador.
#int_rtcc void trata_int_tmr0(void) { set_rtcc(256-125); if (temp1 == 0 ) { rotacao = get_timer1(); set_timer1 (0); rotacao = (rotacao / 7); atualiza_lcd = 1; temp1 = 125; } else { temp1 --; }
// ja passou 1 segundo? // Sim, // le valor do timer 1 // zera timer 1 // divide por 7 (quantidade de palhetas do ventilador) // habilita atualizao do LCD // re-inicia temp1 // No, // decrementa temp1
} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
99
1.57 - Anotaes
Coletor de Dados
Para o bom entendimento deste exemplo so necessrios os conhecimentos adquiridos no exemplo 1 e mais, funes do compilador para controle de comunicao serial I2C (cap.11.14 pg 240 do livro Programao em C), funes do compilador para controle de comunicao serial RS232 (cap.11.13 pg 230 do livro Programao em C), diretiva de configurao #use i2c e #use RS232 (cap.10, pg.171 e 172 do livro Programao em C).
101
+5V
P2 10K
4,7K
330R RA1
1uF
+5V
+5V
7 8 9 10 11 12 13 14
RESET 10K
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
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
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
1uF
MAX-232
1.61 - Fluxograma
MAIN
Inicializa LCD
Tela principal
NO
NO
NO
103
Recebe comando do PC
Chegou comando do PC ?
NO
SIM
SIM
NO
NO
NO
Coleta Dados
NO
SIM
Return
105
NO
Return
107
Envia Controle
Envia Controle
Envia Dado
Envia Controle
delay 10ms
Return
delay 10ms
Return
1.62 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Avanados de programao * * Exemplo 9 * * * * CENTRO DE CAPACITAO - LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este exemplo foi elaborado para explicar as funces de I2C do compilador // CCS. Neste exemplo iremos coletar dados do AD e armazenar estes dados na // EEPROM externa (24c04), estes dados sero enviados ao PC para a // visualizao dos mesmos. O PC controlar as funes do coletor de dados. #include <16f877A.h> // microcontrolador utilizado
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurao do Mdulo I2C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use i2c(master,sda=pin_c4, scl=pin_c3, SLOW, RESTART_WDT, FORCE_HW) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configurao da USART * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use rs232 (baud=9600, xmit = pin_c6, rcv = pin_c7) /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define #define ctrl_le ctrl_escr 0b10100001// byte de controle da memria p/ leitura 0b10100000// byte de controle da memria p/ escrita
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constante internas do tipo Enumerao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ enum selecao_de_tarefa { aguarda_comando, coleta_de_dados, transmite_para_pc, parar_coleta }tarefa;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
109
* Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. static int flags1 = 0; // flags static int dado = 0; static int end_low = 0; static int tx_pc; static int comando = 0; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use fast_io(a) #use fast_io(b) #use fast_io(c) #use fast_io(d) #use fast_io(e) #byte #byte #byte #byte #byte porta=0x05 portb=0x06 portc=0x07 portd=0x08 porte=0x09
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. #bit atualiza_lcd = flags1.0 /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programao e do hardware.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #bit rs = porte.0 // via do lcd que sinaliza recepo de dados ou comando #bit enable = porte.1 // enable do lcd /* * * * * * * * * * * * * Funo * * * * * * * * * * * * escr_mem_serial () { i2c_start(); i2c_write(ctrl_escr); i2c_write(end_low); i2c_write(dado); i2c_stop(); delay_ms(10); } /* * * * * * * * * * * * * Funo * * * * * * * * * * * * le_mem_serial () { i2c_start(); i2c_write(ctrl_escr); i2c_write(end_low); i2c_start(); i2c_write(ctrl_le); dado = i2c_read(0); i2c_stop(); } * * * * * * * * * * * * * * * * * * * * * * * * * * para escrita na EEPROM externa I2C * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Condio de incio // Envia o byte de controle de leitura // Envia endereo baixo // Escreve dado na EPROM // Condio de parada // espera a gravao estar completa * * * * * * * * * * * * * * * * * * * * * * * * * * para leitura na EEPROM externa I2C * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Condio de incio // Envia o byte de controle de leitura // Envia endereo baixo // Nova condio de incio // Envia o byte de controle de leitura // l o dado armazenado na EPROM // Condio de parada
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Funo que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(int caracter) { rs = 0; portd = caracter; enable = 1 ; delay_us(1); enable = 0; delay_us(40); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(int caracter) { rs = 1; portd = caracter; enable = 1; delay_us(1); enable = 0; delay_us(40); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd() { comando_lcd(0x01); delay_ms (2); }
// // // //
// seleciona o envio de um comando carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable
// // // //
// seleciona o envio de um caracter carrega o portd com o caracter gera pulso no enable espera 1 microsegundo desce o pino de enable
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd() { comando_lcd(0x30); delay_ms(4); comando_lcd(0x30); delay_us(100); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); }
// envia comando para inicializar display // espera 4 milisengundos // envia comando para inicializar display // espera 100 microsengundos // envia comando para inicializar display // liga o display, sem cursor e sem blink // limpa lcd // display sem cursor // desloca cursor para a direita
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para imprimir a Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal() { limpa_lcd() comando_lcd(0x80); // posiciona o cursor na linha 0, coluna 0 printf (escreve_lcd, "Coletor de dados"); // imprime mensagem no lcd }
111
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ coleta_dados() { comando_lcd(0xc0); // posiciona o cursor na linha 1, coluna 0 printf (escreve_lcd, "Coletando Dados"); // imprime mensagem no lcd do { dado = read_adc(); // le resuldado do AD escr_mem_serial (); // salva em eeprom end_low += 1; // incrementa endereo, seleciona nova posio delay_ms(10); // delay de 10 ms }while (end_low != 0); // fim da coleta ? tarefa = aguarda_comando; // aguarda comando do PC comando_lcd(0xc0); // posiciona o cursor na linha 1, coluna 0 printf (escreve_lcd, " Pronto para TX "); // imprime mensagem no lcd tx_pc = 11; // indica para o pc fim da coleta de dados printf ("%x\r\n",tx_pc);// envia ao PC o comando de fim da coleta de dados delay_ms(2000); // delay de 2 segundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina para transmitir dados para o PC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ tx_dados_pc() { comando_lcd(0xc0); // posiciona o cursor na linha 1, coluna 0 printf (escreve_lcd, " TX para o PC "); // imprime mensagem no lcd do { le_mem_serial (); // le dados da eeprom printf ("%x\r\n",dado); // envia ao PC o valor da eeprom externa end_low +=1; // incrementa endereo, seleciona nova posio delay_ms(100); // delay de 100 ms }while (end_low != 0); // fim da transmisso de dados tarefa = aguarda_comando; // aguarda comando do PC comando_lcd(0xc0); // posiciona o cursor na linha 1, coluna 0 printf (escreve_lcd, " Fim da Trans..."); // imprime mensagem no lcd delay_ms(3000); // delay de 3 segundos comando_lcd(0xc0); // posiciona o cursor na linha 1, coluna 0 printf (escreve_lcd, " "); // imprime mensagem no lcd delay_ms(1000); // delay de 1 segundo } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento de recepo serial * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void recebe_comando() { if (kbhit()) { comando = getc(); if (comando == 0x55) // recebeu o camando de coleta de dados ? { tarefa = coleta_de_dados; // sim, libera coleta de dados } if (comando == 0xaa) // recebeu o camando de transmisso de dados ? { tarefa = transmite_para_pc; // sim, transmite dados para o PC } if (comando == 0x7f) // recebeu o camando para cancelar coleta de dados ? { tarefa = parar_coleta; // sim, cancela coleta de dados } } }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (RA0_RA1_RA3_analog); setup_adc (adc_clock_div_8); set_adc_channel (1); setup_counters (rtcc_internal, WDT_2304MS); set_tris_a(0b11111111); set_tris_b(0b11111111); set_tris_c(0b10110111); set_tris_d(0b00000000); set_tris_e(0b00000100); porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00; inicializa_lcd(); tela_principal(); // configurao da direo dos pinos de I/O
// // // // //
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ loop: while(true) // rotina principal { RESTART_WDT(); // incia o watch-dog timer recebe_comando(); if (tarefa == coleta_de_dados) // inicia coleta de dados ? { end_low = 0; // sim, carrega endereo inicial coleta_dados(); // executa funo de coleta de dados } if (tarefa == transmite_para_pc)// inicia transmisso de dados para o PC ? { end_low = 0; // sim, carrega endereo inicial tx_dados_pc(); // executa funo de transmisso de dados } if (tarefa == parar_coleta) // cancela coleta de dados ? { end_low = 0; // sim, carrega endereo inicial tarefa = aguarda_comando; // espera envio de comando do PC tx_pc = 11; // fim da coleta de dados tx_dados_pc(); // envia comando para o PC } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
113
1.64 - Anotaes
115
+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
1uF
MAX-232
117
1.68 - Fluxograma
MAIN
NO X < (2 * PI)
SIM
LIMPA W ATCHDO G
Y = seno (x)
1.69 - Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Programao em C - Recursos Avanados de programao * * Exemplo 10 * * * * CENTRO DE CAPACITAO - LABTOOLS * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * E-MAIL: cursos@labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 05/06/2003 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Este software foi desenvolvido para mostrar a implementao de funes matemticas, como exemplo estamos calculando o seno e enviando para o PC os valores de "x" e "y" para serem plotados. * * * * * * * * * * * * * * * * * * * * * dos I/O's e opes de configurao para perifricos * * * * * * * * * * * * * * * * * * * * * */ *
// microcontrolador utilizado
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Carrega bibliteca Matemtica * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <math.h> // microcontrolador utilizado /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #fuses xt,wdt,noprotect,put,brownout,nolvp,nocpd,nowrt // configurao dos fusveis /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definies para uso de Rotinas de Delay * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use delay(clock=4000000, RESTART_WDT)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. float y; float x; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. //Este programa no utiliza nenhum flag de usurio
119
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #use #use #use #use #use #byte #byte #byte #byte #byte fast_io(a) fast_io(b) fast_io(c) fast_io(d) fast_io(e) porta=0x05 portb=0x06 portc=0x07 portd=0x08 porte=0x09 * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. * * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO //FUTURAS ALTERAES DO HARDWARE.
* * */ E
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { setup_adc_ports (no_analogs); // desliga as entradas analgicas setup_counters (rtcc_internal, wdt_2304ms);// tmr0 clock interno, ps: 1:64 set_tris_a(0b11111111); set_tris_b(0b11111111); set_tris_c(0b11111111); set_tris_d(0b11111111); set_tris_e(0b00000111); porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00; // configurao da direo dos pinos de I/O
// // // // //
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(TRUE) { x=0; while(x < 2*PI) { restart_wdt(); // limpa wdt y = sin (x); // calculo da funo printf ("X=%1.3f",x); // envia ao PC o valor de x printf (" "); printf ("Y=%1.3f\r\n",y); // envia ao PC o valor de y x = x + 0.01; // incrementa x } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Fim do Programa * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
121
1.72 - Anotaes