McMaster
Desenvolvimento de Sistemas com Microcontroladores PIC
01/05/2010
ndice
CAPTULO 1 - INTRODUO ......................................................................................................................... 5 CAPTULO 2 - MCMASTER DESENVOLVIMENTO DE SISTEMAS COM MICROCONTROLADORES PIC ..................................................................................................................................................................... 7 INTRODUO .................................................................................................................................................... 7 VISO MACRO DO SISTEMA ............................................................................................................................... 7 MDULOS PADRO........................................................................................................................................... 9 Microcontrolador ......................................................................................................................................... 9 LCD alfanumrico ....................................................................................................................................... 9 Displays de leds com 7 segmentos ............................................................................................................ 9 Leds .......................................................................................................................................................... 10 Teclado matricial ...................................................................................................................................... 10 Buzzer ...................................................................................................................................................... 11 Memria E2PROM externa ...................................................................................................................... 12 Relgio de tempo real (RTC) ................................................................................................................... 12 Comunicao serial RS-232..................................................................................................................... 13 Converso analgica / digital (A/D) .......................................................................................................... 13 PERIFRICOS ADICIONAIS ............................................................................................................................... 16 Placa de experincias EXP01 .................................................................................................................. 16 Placa de experincias EXP02 .................................................................................................................. 17 Placa de experincias EXP03 .................................................................................................................. 17 Placa de experincias EXP04 .................................................................................................................. 18 Adaptador McMaster ................................................................................................................................ 18 Gravador ICD2BR .................................................................................................................................... 18 CAPTULO 3 - EXPERINCIA 1 - LEITURA DE UMA TECLA E ACIONAMENTO DE UM LED................ 19 OBJETIVO ...................................................................................................................................................... 19 DESCRIO.................................................................................................................................................... 19 ESQUEMA ELTRICO....................................................................................................................................... 20 FLUXOGRAMA ................................................................................................................................................. 21 CDIGO ......................................................................................................................................................... 22 DICAS E COMENTRIOS .................................................................................................................................. 25 EXERCCIOS PROPOSTOS ............................................................................................................................... 25 CAPTULO 4 - EXPERINCIA 2 CONTADOR SIMPLIFICADO ................................................................ 26 OBJETIVO ...................................................................................................................................................... 26 DESCRIO.................................................................................................................................................... 26 ESQUEMA ELTRICO....................................................................................................................................... 27 FLUXOGRAMA ................................................................................................................................................. 28 CDIGO ......................................................................................................................................................... 30 DICAS E COMENTRIOS .................................................................................................................................. 34 EXERCCIOS PROPOSTOS ............................................................................................................................... 34 CAPTULO 5 - EXPERINCIA 3 PISCA - PISCA ...................................................................................... 35 OBJETIVO ...................................................................................................................................................... 35 DESCRIO.................................................................................................................................................... 35 ESQUEMA ELTRICO....................................................................................................................................... 36 FLUXOGRAMA ................................................................................................................................................. 37 CDIGO ......................................................................................................................................................... 39 DICAS E COMENTRIOS .................................................................................................................................. 43 EXERCCIOS PROPOSTOS ............................................................................................................................... 43 CAPTULO 6 - EXPERINCIA 4 CONVERSO BCD PARA DISPLAYS DE 7 SEGMENTOS ................. 44 OBJETIVO ...................................................................................................................................................... 44 DESCRIO.................................................................................................................................................... 44 ESQUEMA ELTRICO....................................................................................................................................... 46 FLUXOGRAMA ................................................................................................................................................. 47 CDIGO ......................................................................................................................................................... 49 DICAS E COMENTRIOS .................................................................................................................................. 53 EXERCCIOS PROPOSTOS ............................................................................................................................... 53 Manual do Usurio Sistema de Treinamento em Microcontroladores PIC McMaster rev5 2010 1
CAPTULO 7 - EXPERINCIA 5 TIMER DE SEGUNDOS......................................................................... 54 OBJETIVO ...................................................................................................................................................... 54 DESCRIO.................................................................................................................................................... 54 FLUXOGRAMA ................................................................................................................................................. 56 CDIGO ......................................................................................................................................................... 59 DICAS E COMENTRIOS .................................................................................................................................. 64 EXERCCIOS PROPOSTOS ............................................................................................................................... 64 CAPTULO 8 - EXPERINCIA 6 ACESO MEMRIA DE DADOS EEPROM ........................................ 65 OBJETIVO ...................................................................................................................................................... 65 DESCRIO.................................................................................................................................................... 65 ESQUEMA ELTRICO....................................................................................................................................... 66 FLUXOGRAMA ................................................................................................................................................. 67 CDIGO ......................................................................................................................................................... 70 DICAS E COMENTRIOS .................................................................................................................................. 75 EXERCCIOS PROPOSTOS ............................................................................................................................... 75 CAPTULO 9 - EXPERINCIA 7 - DIMMER .................................................................................................. 76 OBJETIVO ...................................................................................................................................................... 76 DESCRIO.................................................................................................................................................... 76 ESQUEMA ELTRICO....................................................................................................................................... 77 FLUXOGRAMA ................................................................................................................................................. 78 CDIGO ......................................................................................................................................................... 81 DICAS E COMENTRIOS .................................................................................................................................. 86 EXERCCIOS PROPOSTOS ............................................................................................................................... 86 CAPTULO 10 - EXPERINCIA 8 BOTES, LEDS E BUZZER ............................................................... 87 OBJETIVO ...................................................................................................................................................... 87 DESCRIO.................................................................................................................................................... 87 ESQUEMA ELTRICO....................................................................................................................................... 88 FLUXOGRAMA ................................................................................................................................................. 89 CDIGO ......................................................................................................................................................... 93 DICAS E COMENTRIOS .................................................................................................................................. 98 EXERCCIOS PROPOSTOS ............................................................................................................................... 98 CAPTULO 11 - EXPERINCIA 9 VARREDURA DE DISPLAYS E UTILIZAO DO TIMER 1 ............. 99 OBJETIVO ...................................................................................................................................................... 99 DESCRIO.................................................................................................................................................... 99 FLUXOGRAMA ............................................................................................................................................... 102 CDIGO ....................................................................................................................................................... 107 DICAS E COMENTRIOS ................................................................................................................................ 117 EXERCCIOS PROPOSTOS ............................................................................................................................. 117 CAPTULO 12 - EXPERINCIA 10 DISPLAY DE CRISTAL LQUIDO LCD........................................... 118 OBJETIVO .................................................................................................................................................... 118 DESCRIO.................................................................................................................................................. 118 ESQUEMA ELTRICO..................................................................................................................................... 119 FLUXOGRAMA ............................................................................................................................................... 120 CDIGO ....................................................................................................................................................... 125 DICAS E COMENTRIOS ................................................................................................................................ 132 EXERCCIOS PROPOSTOS ............................................................................................................................. 132 CAPTULO 13 - EXPERINCIA 11 CONVERSOR A/D ........................................................................... 133 OBJETIVO .................................................................................................................................................... 133 DESCRIO.................................................................................................................................................. 133 ESQUEMA ELTRICO..................................................................................................................................... 134 FLUXOGRAMA ............................................................................................................................................... 135 CDIGO ....................................................................................................................................................... 138 DICAS E COMENTRIOS ................................................................................................................................ 143 EXERCCIOS PROPOSTOS ............................................................................................................................. 143 CAPTULO 14 - EXPERINCIA 12 CONVERSO A/D VIA RC .............................................................. 144 OBJETIVO .................................................................................................................................................... 144 2
DESCRIO.................................................................................................................................................. 144 ESQUEMA ELTRICO..................................................................................................................................... 146 FLUXOGRAMA ............................................................................................................................................... 147 CDIGO ....................................................................................................................................................... 149 DICAS E COMENTRIOS ................................................................................................................................ 154 EXERCCIOS PROPOSTOS ............................................................................................................................. 154 CAPTULO 15 - EXPERINCIA 13 LEITURA DE JUMPERS VIA RC .................................................... 155 OBJETIVO .................................................................................................................................................... 155 DESCRIO.................................................................................................................................................. 155 ESQUEMA ELTRICO..................................................................................................................................... 156 FLUXOGRAMA ............................................................................................................................................... 157 CDIGO ....................................................................................................................................................... 159 DICAS E COMENTRIOS ................................................................................................................................ 163 EXERCCIOS PROPOSTOS ............................................................................................................................. 163 CAPTULO 16 - EXPERINCIA 14 MODULO PWM................................................................................ 164 OBJETIVO .................................................................................................................................................... 164 DESCRIO.................................................................................................................................................. 164 ESQUEMA ELTRICO..................................................................................................................................... 166 CDIGO ....................................................................................................................................................... 170 DICAS E COMENTRIOS ................................................................................................................................ 177 EXERCCIOS PROPOSTOS ............................................................................................................................. 177 CAPTULO 17 - EXPERINCIA 15 ACESSO S MEMRIAS DE DADOS E PROGRAMA ................. 178 OBJETIVO .................................................................................................................................................... 178 DESCRIO.................................................................................................................................................. 178 ESQUEMA ELTRICO..................................................................................................................................... 179 CDIGO ....................................................................................................................................................... 185 DICAS E COMENTRIOS ................................................................................................................................ 194 EXERCCIOS PROPOSTOS ............................................................................................................................. 194 CAPTULO 18 - EXPERINCIA 16 MASTER I2C .................................................................................... 195 OBJETIVO .................................................................................................................................................... 195 DESCRIO.................................................................................................................................................. 195 ESQUEMA ELTRICO..................................................................................................................................... 197 FLUXOGRAMA ............................................................................................................................................... 198 CDIGO ....................................................................................................................................................... 204 DICAS E COMENTRIOS ................................................................................................................................ 211 EXERCCIOS PROPOSTOS ............................................................................................................................. 211 CAPTULO 19 - EXPERINCIA 17 COMUNICAO SERIAL RS232 VIA USART ............................... 212 OBJETIVO .................................................................................................................................................... 212 DESCRIO.................................................................................................................................................. 212 ESQUEMA ELTRICO..................................................................................................................................... 213 FLUXOGRAMA ............................................................................................................................................... 214 CDIGO ....................................................................................................................................................... 216 DICAS E COMENTRIOS ................................................................................................................................ 222 EXERCCIOS PROPOSTOS ............................................................................................................................. 222 CAPTULO 20 - EXPERINCIA 18 TECLADO MATRICIAL 4X4 ............................................................ 223 OBJETIVO .................................................................................................................................................... 223 DESCRIO.................................................................................................................................................. 223 ESQUEMA ELTRICO..................................................................................................................................... 224 FLUXOGRAMA ............................................................................................................................................... 225 CDIGO ....................................................................................................................................................... 229 DICAS E COMENTRIOS ................................................................................................................................ 235 EXERCCIOS PROPOSTOS ............................................................................................................................. 235 CAPTULO 21 - EXPERINCIA 19 RELGIO DE TEMPO REAL (RTC) ............................................... 236 OBJETIVO .................................................................................................................................................... 236 DESCRIO.................................................................................................................................................. 236 ESQUEMA ELTRICO..................................................................................................................................... 237 Manual do Usurio Sistema de Treinamento em Microcontroladores PIC McMaster rev5 2010 3
FLUXOGRAMACDIGO .................................................................................................................................. 238 CDIGO ....................................................................................................................................................... 242 DICAS E COMENTRIOS ................................................................................................................................ 247 EXERCCIOS PROPOSTOS ............................................................................................................................. 247 CAPTULO 22 - EXPERINCIA 20 SISTEMA DE TEMPERATURA E TACMETRO ........................... 248 OBJETIVO .................................................................................................................................................... 248 DESCRIO.................................................................................................................................................. 248 O sensor de temperatura ....................................................................................................................... 248 O aquecimento ....................................................................................................................................... 248 O resfriamento ........................................................................................................................................ 249 Comunicao serial ................................................................................................................................ 249 Consideraes gerais ............................................................................................................................. 249 ESQUEMA ELTRICO..................................................................................................................................... 250 FLUXOGRAMA ............................................................................................................................................... 251 CDIGO ....................................................................................................................................................... 255 DICAS E COMENTRIOS ................................................................................................................................ 263 EXERCCIOS PROPOSTOS ............................................................................................................................. 263 CAPTULO 23 - EXEMPLO PLACA DE EXPERINCIA EXP01 ................................................................ 264 OBJETIVO .................................................................................................................................................... 264 DESCRIO.................................................................................................................................................. 264 CAPTULO 24 - EXEMPLO PLACA DE EXPERINCIA EXP02 ................................................................ 265 OBJETIVO .................................................................................................................................................... 265 DESCRIO.................................................................................................................................................. 265 ESQUEMA ELTRICO..................................................................................................................................... 266 CDIGO ....................................................................................................................................................... 268 CAPTULO 25 - EXEMPLO PLACA DE EXPERINCIA EXP03 ................................................................ 271 OBJETIVO .................................................................................................................................................... 271 DESCRIO.................................................................................................................................................. 271 ESQUEMA ELTRICO..................................................................................................................................... 272 PLACA DE EXPERINCIAS .............................................................................................................................. 273 CDIGO ....................................................................................................................................................... 275 CAPTULO 26 - EXEMPLO PLACA DE EXPERINCIA EXP04 ................................................................ 285 OBJETIVO .................................................................................................................................................... 285 DESCRIO.................................................................................................................................................. 285 CAPTULO 27 - SOFTWARE DE COMUNICAO SERIAL ..................................................................... 286 CAPTULO 28 - SOFTWARE DEMO PARA TESTE DO HARDWARE...................................................... 287 CAPTULO 29 - APNDICE A ESQUEMA ELTRICO COMPLETO DO MCMASTER ......................... 288 CAPTULO 30 - APNDICE B ESQUEMA ELTRICO COMPLETO DA PLACA DE EXPERINCIAS EXP01 ............................................................................................................................................................ 291 CAPTULO 31 - APNDICE B ESQUEMA ELTRICO COMPLETO DA PLACA DE EXPERINCIAS EXP02 ............................................................................................................................................................ 292 CAPTULO 32 - APNDICE C ESQUEMA ELTRICO COMPLETO DA PLACA DE EXPERINCIAS EXP03 ............................................................................................................................................................ 294 CAPTULO 33 - APNDICE D ESQUEMA ELTRICO COMPLETO DA PLACA DE EXPERINCIAS EXP04 ............................................................................................................................................................ 296 CAPTULO 34 - APNDICE D ESQUEMA ELTRICO COMPLETO DA PLACA ADAPTADORA MCMASTER .................................................................................................................................................. 297 Pinagem Adaptador McMaster ............................................................................................................... 298 CAPTULO 35 - CERTICADO DE GARANTIA ........................................................................................... 300
Captulo 1 - Introduo
Inicialmente gostaramos de parabeniz-lo por estar adquirindo o sistema didtico McMaster. Este sistema utiliza o microcontrolador PIC18F4550 como objeto central. Junto ao microcontrolador, uma srie de perifricos foram adicionados. O objetivo disponibilizar uma placa de desenvolvimento onde o usurio possa testar seus conhecimentos em software, sem se preocupar com a montagem do hardware. Basta escrever o software. Veja todos os recursos que o sistema oferece: LCD alfanumrico; Displays de leds de 7 segmentos; Teclado matricial; Leds; Buzzer; Memria serial EEPROM (protocolo I2C); Relgio de tempo real (protocolo I2C); Comunicao serial padro RS232; Converso A/D; Leitura de jumpers; Sensor de temperatura; Aquecedor; Ventilador; Tacmetro; Lmpada Incandescente; Gravao in-circuit; Placas de experincias; Fonte de alimentao bivolt (interno ao mdulo).
Aliado a todos estes recursos, utilizou-se o microcontrolador PIC18F4550 que o mais completo da famlia 18F. Suas principais caractersticas so: Capacidade de processamento de 12MIPS; Fonte de clock interna de 31kHz e 8MHz do tipo RC; PLL interno para multiplicar a freqncia de clock; Prioridade no tratamento de interrupo possvel escolher entre alta ou baixa prioridade; Hardware de multiplicao 8X8 bits executado em 1 ciclo de mquina; Alta capacidade de corrente nos pinos de I/O, 25mA por pino; Trs fontes de interrupo externa; Uma interrupo de mudana de estado, quatro fontes; Timer 0 de 8 ou 16 bits configurvel; Timer 1 e 3 de 16 bits;
Timer 2 de 8 bits; Mdulo ECCP; Mdulo MSSP (SPI e I2C); EUSART (com suporte ao barramento LIN); ADC de 10bits; HLVD; BOR; WDT.
Fazem parte do kit de desenvolvimento: 1 Sistema de Treinamento em Microcontroladores PIC McMaster; com entrada de alimentao bivolt; 1 PIC18F4550; 1 Manual do Usurio; 1 CD-ROM; 1 Placa de experincia EXP01 1 Placa de experincia EXP02 1 Placa de experincia EXP03 1 Placa de experincia EXP04 1 Cabo USB 1 Cabo Serial
Introduo
O McMaster um equipamento para desenvolvimento de sistemas completo para o estudo da tecnologia de microcontroladores Microchip e em particular ao estudo do microcontrolador PIC18F4550. Na verdade, este sistema serve para muito mais que simplesmente o aperfeioamento dos conhecimentos da famlia PIC. Com ele o usurio capaz de criar projetos completos, colocando em teste tambm a eficincia de seus conceitos e algoritmos. Tudo isso possvel porque este sistema foi desenvolvido pensando na didtica de ensino e nos problemas mais comuns do mercado em relao ao uso de microcontroladores.
Com o intuito de maximizar a compatibilidade entre as famlias de microcontroladores suportadas pela McMaster com seus mdulos padro optou-se pela utilizao de jumpers de configurao para que pontos importantes do circuito possam ser desabilitados. Desta forma, atravs de 7 jumpers , descritos de acordo com a seqncia em que esto dispostos na placa McMaster, podemos configurar a ferramenta de acordo com a aplicao desejada: Cap USB (RC3) Este jumper seleciona a ligao do capacitor de desacoplamento da referncia de tenso utilizada pelo mdulo USB do PIC18F4550. Selecione OFF para que o capacitor no seja desligado pois a comunicao USB utilizada e ON para que o capacitor seja desligado pois a comunicao USB no utilizada. Obs: quando for utilizado o PIC16F877A ou PIC18F4520 obrigatoriamente este jumper dever permanecer na posio ON Data I2C Este jumper seleciona o pino de via de dado I2C do microcontrolador utilizado com os perifricos padres. Selecione ON quando utilizar a via de dado do PIC18F4550 e OFF quando utilizar a via de dado do PIC16F877A ou PIC18F4520. Obs: quando for utilizado o PIC18F4550 com a via de dado I2C selecionada obrigatoriamente o jumper Coluna 1 (RB0) dever permanecer na posio OFF. Clock I2C Este jumper seleciona o pino de via de clock I2C do microcontrolador utilizado com os perifricos padres. Selecione ON quando utilizar a via de dado do PIC18F4550 e OFF quando utilizar a via de dado do PIC16F877A ou PIC18F4520. Obs: quando for utilizado o PIC18F4550 com a via de clock I2C selecionado obrigatoriamente o jumper Coluna 2 (RB1) dever permanecer na posio OFF. Coluna 2 (RB1) Este jumper desliga o pino RB1 utilizado para ler os botes da coluna 2 do teclado. Selecione ON quando utilizar a coluna 2 do teclado e OFF quando no utilizar a coluna 2 do teclado. Coluna 1 (RB0) Este jumper desliga o pino RB0 utilizado para ler os botes da coluna 1 do teclado. Selecione ON quando utilizar a coluna 1 do teclado e OFF quando no utilizar a coluna 1 do teclado. Linha 1 / Display Milhar (RB4) Este jumper desliga o pino RB4 utilizado para ativar a linha 1 do teclado matricial e o display do milhar. Selecione ON quando utilizar a linha 1 do teclado matricial e o display do milhar e OFF quando no utilizar a linha 1 do teclado matricial e o display do milhar. Leds Especiais (RC0, RC1 e RC2) Este jumper desabilita os leds ligados aos pinos RC0, RC1 e RC2 utilizados pelos mdulos CPP e TIMER1 do microcontrolador. Selecione ON quando utilizar os leds especiais e OFF quando no utilizar os leds especiais.
Mdulos Padro
Nesta seo sero abordados cada um dos mdulos padro do McMaster.
Microcontrolador
O sistema utiliza o microcontrolador PIC18F4550 como centro de todo o hardware. Este microcontrolador est ligado a todos os perifricos disponveis, possibilitando o estudo de praticamente todas as suas funes. Devido tambm ao grande poder de recursos deste modelo de PIC, possvel, junto aos demais recursos da placa, o desenvolvimento de projetos simples e/ou complexos, como por exemplo um controlador de temperatura com algoritmo de controle PID.
LCD alfanumrico
Nos dias de hoje, qualquer programador sabe da importncia da interface com o usurio dentro de um sistema qualquer. Por isso, muito importante o aprendizado de operao de um display do tipo LCD. No caso do McMaster, este display possui 2 linhas de 16 caracteres cada, sendo um padro de mercado atual. Possui um chip de controle prprio, com o qual realizada a interface com o microcontrolador. Com este perifrico os sistemas desenvolvidos no McMaster podero possuir telas explicativas, informaes claras e menus de navegao. A comunicao com o LCD paralela com 8 vias de dados. Alm destas, mais duas vias so utilizadas para controlar o LCD, uma denominada de ENABLE e a outra de RS. A comunicao com o LCD somente de escrita, desta forma, o pino de R/W do LCD est diretamente ligado ao terra (GND), no permitindo a leitura do mesmo. As 8 vias de dados do LCD esto ligadas ao PORTD do microcontrolador, de RD0 (LSB) at RD7 (MSB). O pino de ENABLE est conectado ao pino RE1 do PIC e o pino RS do LCD ao pino RE0 do microcontrolador. Assim, o esquema de ligao segue a tabela abaixo:
PIC RD0...RD7 RE0 RE1 Terra (GND) LCD D0...D7 RS ENABLE R/W
Para maiores informaes a respeito do LCD pode-se consultar o data sheet contido no CD que acompanha o McMaster.
segmentos interligados e os controles (comum) independentes, possibilitando a operao por varredura. Atualmente, muito comum encontrar em produtos do mercado, a combinao de ambos os tipos de display, para uma visualizao mais completa e eficiente. Com o McMaster esta combinao tambm possvel. A conexo dos displays com o microcontrolador segue a tabela abaixo:
PIC RD0 RD1 RD2 RD3 RD4 RD5 RD6 RD7 Segmento A B C D E F G DP
Para a ativao dos displays deve-se selecionar nvel lgico 1 nos pinos de seleo. Os segmentos tambm so ativados com nvel lgico 1.
Leds
O McMaster possui um grupo de 8 leds que compartilha o mesmo barramento que os displays de 7 segmentos e o display LCD. Desta forma, o seu acionamento deve ser feito via varredura sendo que os leds esto conectados ao PORTD e a seleo feita pelo pino RA4. Da mesma forma que os displays, os leds so ativados com nvel lgico 1, tanto na via de seleo (RA4) como individualmente (PORTD).
Teclado matricial
A maioria dos sistemas desenvolvidos atualmente utilizam algum tipo de teclado para a entrada de dados pelo usurio. O McMaster est provido de um teclado matricial de 4 linhas e 4 colunas, totalizando 16 teclas. O acionamento das linhas do teclado feito simultaneamente com os comuns dos displays de 7 segmentos. Desta forma, ao acionar o display da unidade aciona-se tambm a linha 4 do teclado matricial. Junto com o display da dezena a linha 3 e assim por diante. A tabela a seguir mostra esta relao:
10
Estado 1 0 1 0 1 0 1 0
Teclado Matricial linha 4 ativada linha 4 desativada linha 3 ativada linha 3 desativada linha 2 ativada linha 2 desativada linha 1 ativada linha 1 desativada
Display de 7 segmentos unidade ativada unidade desativada dezena ativada dezena desativada centena ativada centena desativada milhar ativada milhar desativada
As colunas podem ser lidas atravs dos pinos RB0, RB1, RB2 e RB3, conforme a tabela a seguir: Pino PIC RB0 RB1 RB2 RB3 Estado 1 0 1 0 1 0 1 0 Teclado Matricial Alguma tecla pressionada na coluna 1 Nenhuma tecla pressionada na coluna 1 Alguma tecla pressionada na coluna 2 Nenhuma tecla pressionada na coluna 2 Alguma tecla pressionada na coluna 3 Nenhuma tecla pressionada na coluna 3 Alguma tecla pressionada na coluna 4 Nenhuma tecla pressionada na coluna 4
Vale observar que para o correto funcionamento do teclado os jumpers relacionados com os pinos RB0 e RB4 devem estar configurados na posio ON.
Buzzer
Para chamar a ateno do usurio e confirmar certas aes, cada vez mais os sistemas esto fazendo uso de tcnicas sonoras, seja atravs de simples bips ou por complexas melodias. Para que os usurios no fiquem sem o uso deste recurso, disponibilizou-se tambm um buzzer piezoeltrico com oscilao comandada diretamente pelo PIC, tornando possvel a criao de sons diversos. O microcontrolador deve ento gerar (atravs do software) uma onda quadrada capaz de excitar o buzzer. Para gerar um simples beep pode-se utilizar uma onda quadrada com freqncia em torno de 650Hz e durao aproximada de 100ms. O buzzer est conectado ao pino RE2 do microcontrolador.
11
Novamente os jumpers de configuraes relacionados devem estar habilitados para a utilizao da memria serial externa. Note que a posio 3-2 habilita os pinos RC3 e RC4. J a posio 2-1 habilita os pinos RB0 e RB1. Como a memria serial compartilha o mesmo barramento I2C do relgio de tempo real (PCF8583P) se faz necessria a utilizao de endereos diferentes para que o barramento seja compatvel com os dois perifricos. Sendo assim, escolheu-se o endereo 7h (111b) para a memria serial. Para maiores informaes sobre o protocolo de comunicao da memria serial 24LC256 pode-se consultar o data sheet disponvel no CD. Para detalhes a respeito da configurao dos jumpers utilizados na comunicao I2C consulte o Captulo 2.
12
Faz parte tambm do mdulo de comunicao serial, o conector DB9 fmea que segue a pinagem abaixo: Pino 1 2 3 4 5 6 7 8 9 Funo TX (sada) RX (entrada) Terra (GND) -
13
10K
4,7K
330R
RA0
LM358 1uF
A tenso de entrada presente no pino RA0 do microcontrolador pode ser ajustada entre 0 e 5V. Caso se utilize o conversor A/D interno do PIC, o capacitor de 1uF e o resistor de 4K7 formam um filtro passa baixa til para filtrar rudos e deixar o sinal de entrada mais estvel. Caso se utilize o sistema de leitura via RC o conjunto de resistores e capacitores assume outra funo. Neste sistema, para realizar a converso deve-se executar as etapas a seguir: Inicialmente, atravs do software, deve-se descarregar o capacitor, colocando o pino do microcontrolador como sada em nvel lgico 0. O capacitor se descarregar pelo resistor de 330R. Aps o capacitor estar descarregado, coloca-se o pino do microcontrolador em entrada e comea-se a contar o tempo que o capacitor leva para se carregar (atravs do resistor de 4K7), ou seja, quanto tempo o capacitor leva para atingir nvel lgico 1. Como tempo de carga inversamente proporcional tenso aplicada pelo potencimetro, sabendo-se o tempo de carga pode-se estimar a tenso aplicada. Jumpers O sistema de jumpers est ligado ao pino RA5 do microcontrolador e segue o esquema eltrico representado a seguir.
+5V ON Posio 1 22K 1 2 3 OFF JP1
Posio 2 33K 1 2 3
JP2
Jumpers RA5
JP3
JP4
Divisor Capacitivo
Divisor Resistivo
100nF
10K
14
Se configurarmos o sistema para divisor resistivo, basta ler com o conversor A/D do PIC a tenso presente no pino RA5 para estimar a posio do jumper. Se configurarmos o sistema para resistor/capacitor, devemos seguir a mesma metodologia explicada no caso do potencimetro, ou seja: Inicialmente descarregar o capacitor atravs do resistor de 330R colocando o pino do microcontrolador como sada em nvel lgico 0. Aps o capacitor estar descarregado, colocar o pino do microcontrolador em entrada e comear a contar o tempo que o capacitor leva para se carregar, ou seja, quanto tempo o capacitor leva para atingir nvel lgico 1. Este tempo de carga proporcional ao valor do circuito RC e portanto, pode ser utilizado para determinar a posio do jumper.
15
Perifricos Adicionais
A seguir sero explanados os perifricos adicionais (placas de expanso) contidos na placa de experincias EXP01, EXP02, EXP03, EXP04 que acompanham o kit MCMASTER.
16
Lmpada incandescente Consiste numa lmpada incandescente de 12V que pode ser acionada atravs do pino RC5 do microcontrolador. Com nvel lgico 1 a lmpada acende e com nvel lgico 0 a lmpada apaga. Tenso de referncia O circuito medidor de temperatura ambiente utiliza uma tenso de referncia fixa e estvel em 2,5V e como este recurso j estava presente na placa de experincias EXP01 resolveu-se tambm disponibilizar este recurso ao usurio. Assim, a tenso de referncia de 2,5V foi conectada ao pino RA3 do PIC que pode ser configurado para utilizar este pino como entrada de referncia externa do conversor A/D. Isto permite que o conversor A/D possa trabalhar em outra faixa de converso e conseqentemente com outra resoluo.
17
Entrada USB A placa possui entrada USB para utilizao com o PIC18F4550. Com esta entrada podemos emular, por exemplo, uma RS232, um mouse, entre outros.
Adaptador McMaster
A placa Adaptador McMaster pode ser substituda na posio ocupada pelo microcontrolador do McMaster permitindo a conexo de outros microcontraldores da famlia Microchip que sejam compatveis ao esquema da Adaptador. Consulte o Captulo 31 para mairores detalhes.
Gravador ICD2BR
Para utilizar o gravador presente no McMaster basta selecionar corretamente o seu modelo no software de desenvolvimento MPLAB da Microchip. Por se tratar de um gravador in-circuit o microcontrolador no precisa ser retirado da placa. Ao habilitar o gravador no MPLAB o software atual do PIC18F4550 ser paralisado e instantes aps o final da gravao do novo software, o microcontrolador ser automaticamente inicializado. Durante todas as etapas de comunicao entre o ICD2BR e o microcontrolador (casos de gravao e depurao) o boto ICSP dever ser mantido pressionado (LED ICSP ON aceso). Como trata-se de um sistema de gravao conjugado ao McMaster, o usurio dever sempre estabelecer a conexo USB entre o Kit e o MPLAB para correta operao do kit e execuo dos exemplos. Para a execuo dos exemplos posteriormente gravados no microcontrolador, o usurio poder decidir entre liberar a tecla ICSP (LED ICSP ON apagado) ou liberar via MPLAB o reset do ICD2BR; Liberando o boto ICSP o microcontrolador sair do estado de reset independentemente do comando de reset via MPLAB.
Obs: (1) O boto de reset do McMaster funcionar somente quando o reset do gravador (controlado atravs do software MPLAB) estiver liberado caso o boto ICSP esteja pressionado (LED ICSP ON aceso) (2) Para maiores detalhes a respeito da utilizao do gravador ICD2BR consulte o seu manual de operao.
18
Descrio
Sistema muito simples para representar o estado de um boto atravs de um led. Com o boto pressionado o led ligado e com o boto solto o led apagado. O software inicia configurando os pinos de I/Os atravs dos registradores TRIS e dos registradores de perifricos pertinentes. Em seguida, o software habilita a linha 4 do teclado matricial e o grupo de leds ligados ao PORTD. A partir da, o software entra num loop infinito onde o boto da linha 1 coluna 4 testado e seu estado reproduzido no led 0 ligado ao pino RD0.
19
Esquema Eltrico
20
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
HABILITA LEDS
No
APAGA LED
21
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 1 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // Este software est preparado para demonstrar o controle dos pinos de I/O // este primeiro programa demonstrar o estado de um boto por meio de um led. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF
22
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e * * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LED PORTDbits.RD0
//PORTA DO LED //0 -> APAGADO //1 -> ACESO //PINO PARA ATIVAR GRUPO DE 8 LEDS //1 -> LEDS ATIVADOS //0 -> LEDS DESATIVADOS //PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
#define
C_LEDS
PORTAbits.RA4
#define
LINHA_4
PORTBbits.RB7
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE
23
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011001; 0b00000000; 0b00000000;
PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ C_LEDS = 1; //ATIVA LEDS LIGADOS AO PORTD LINHA_4 = 1; /* * * * * * * * * * * * * * * * * * * while(1) { ClrWdt(); if (BOTAO) else LED = } } //ATIVA LINHA 4 DO TECLADO MATRICIAL * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * */
LED = 1; 0;
// FIM DO PROGRAMA
24
Dicas e Comentrios
Veja que os pinos do microcontrolador, tanto os de entrada como os de sada so declarados atravs de DEFINES no incio do software o que facilita futuras alteraes na pinagem do hardware. Repare tambm que o exemplo extremamente simples e nenhum tipo de tratamento de debounce para a tecla foi utilizado.
Exerccios Propostos
1. Altere a lgica do sistema, ou seja, com o boto pressionado o led deve permanecer apagado e com o boto liberado o led deve permanecer acesso. 2. Altere o software a fim de trocar a tecla ativa, passando por exemplo a utilizar a tecla da linha 4 coluna 2. 3. Altere o software para ligar/desligar outro led, por exemplo, o led ligado ao pino RD3.
25
Objetivo
O objetivo desta experincia ensinar os recursos de software comumente utilizados para tratamento de debounce de teclas e a manipulao de variveis declaradas na RAM do microcontrolador.
Descrio
O software faz uso do grupo de leds para representar de forma binria o valor da varivel CONTADOR declarada na RAM do microcontrolador. Utilizando o boto da linha 4 coluna 1 altera-se o valor da varivel atravs de instrues de incremento e decremento. O valor est limitado por constantes declaradas no incio do cdigo. Como apenas um boto utilizado, a varivel incrementada at o valor mximo e em seguida decrementada at o valor mnimo, permanecendo neste looping indefinidamente. Foi utilizado um flag para alterar o sentido da contagem sempre que um dos extremos atingido. Foi feito o tratamento de debounce da tecla que consiste em testar repetidas vezes se a tecla foi realmente pressionada para somente depois executar a ao correspondente. Sempre que a tecla estiver solta o contador de debounce (varivel FILTRO) inicializado e sempre que a tecla for pressionada o valor da varivel FILTRO decrementado, de forma que a tecla somente considerada pressionada quando o valor de FILTRO for igual a zero.
26
Esquema Eltrico
27
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
HABILITA LEDS
ATUALIZA LEDS
No
BOTO PRESS.?
DECREMENTA FILTRO
FILTRO=0?
Sim 1
28
Sim
SENTIDO=1?
No
DECREMENTA CONTADOR
INCREMENTA CONTADOR
CONTADOR<MN?
No
No
CONTADOR>MX?
SENTIDO = 0
SENTIDO = 1
ATUALIZA LEDS
No
29
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 2 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Este exemplo mostra um contador simplificado /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF
30
VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. struct flags { unsigned char BIT0 :1; unsigned char BIT1 :1; unsigned char BIT2 :1; unsigned char BIT3 :1; unsigned char BIT4 :1; unsigned char BIT5 :1; unsigned char BIT6 :1; unsigned char BIT7 :1; }; unsigned char unsigned char CONTADOR; FILTRO;
struct flags FLAG_0; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define #define MIN MAX 10 30
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. #define #define #define sentido C_LEDS LINHA_4 FLAG_0.BIT0 LATAbits.LATA4 LATBbits.LATB4
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e * * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal *
31
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011001; 0b00000000; 0b00000000;
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ C_LEDS = 1; LINHA_4 = 1; sentido = 0; CONTADOR = MIN; PORTD = CONTADOR; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { ClrWdt(); FILTRO = 200; if(!BOTAO) continue; while(BOTAO) { ClrWdt(); FILTRO--; if(FILTRO) continue; else break; } if(sentido == 0) { CONTADOR++; if(CONTADOR > MAX) { CONTADOR--; sentido = 1; continue; } } else { CONTADOR--; if(CONTADOR < MIN) { CONTADOR++; sentido = 0; continue; } //ATIVA LEDS LIGADOS AO PORTD //ATIVA LINHA 4 DO TECLADO MATRICIAL
32
33
Dicas e Comentrios
O tempo do debounce pode ser calculado pelo tempo de execuo da varredura da tecla multiplicado pelo valor inicial da varivel de filtro. No exemplo estudado o tempo de debounce de 1,15ms e foi calculado seguindo a equao abaixo: Tempo de Debounce = ciclo de mquina X nmero de ciclos de mquina na varredura da tecla X valor inicial da varivel FILTRO Tempo de Debounce = 1us x 5 x 230 Tempo de Debounce = 1150us = 1,15ms No existe uma regra para calcular o tempo ideal que deva ser utilizado no debounce de teclas. Isso ir depender do projeto, do tipo de tecla em utilizao, do ambiente de trabalho onde o sistema ir operar, etc. Na prtica, tempos longos da ordem de grandeza de dezenas de milisegundos podem ser necessrios.
Exerccios Propostos
1. Alterar os limites da contagem. 2. Retirar o tratamento de debounce do software e verificar os efeitos prticos.
34
Objetivo
O objetivo desta experincia ensinar ao aluno com criar rotinas de delays alm de apresentar uma tcnica simples utilizada para inverter o estado de um bit.
Descrio
O software desta experincia utiliza um dos displays de 7 segmentos para implementar um pisca-pisca sendo que a freqncia das piscadas controlada atravs do uso de uma rotina de delay. A rotina de delay genrica pode ser utilizada para gerar delays entre 1ms e 256ms. Na realidade, a rotina recebe um argumento passado pelo WORK para determinar o atraso que deve ser gerado, sempre em mltiplos de 1ms. Como o argumento de 8 bits existem 256 possveis delays, indo de 1ms at 256ms. Basta portanto, carregar o WORK com o delay desejado e chamar a rotina. O pisca-pisca visualizado no display de 7 segmentos na posio da unidade. Sempre que o delay finalizado o PORTD deve ser invertido e para inverter o estado destes bits utilizou-se a operao lgica boleana XOR. Conforme a tabela verdade apresentada a seguir A 0 0 1 1 B 0 1 0 1 XOR 0 1 1 0
pode-se verificar que sempre que a operao realizada quando os bits da coluna A esto em 1 o resultado fica invertido em relao coluna B e sempre que os bits da coluna A esto em 0 o resultado se mantm em relao coluna B. Assim, sempre que ser desejar inverter um bit, basta fazer uma operao XOR entre um bit em 1 e o bit que se deseja inverter. Esta uma tcnica simples de inverter o estado de um bit sem testar o estado original. No software, pode-se utilizar as teclas da linha 4 colunas 1 e 2 para alterar o tempo do delay e conseqentemente a freqncia das piscadas do display. A tecla da coluna 1 incrementa o valor do delay enquanto a tecla da coluna 2 decrementa.
35
Esquema Eltrico
36
Fluxograma
INCIO
Sim
BOTO 1 PRESS.? No
Sim
BOTO 2 PRESS.? No
No
37
CONTADOR<MN?
No
CONTADOR>MX?
No
No
No
DELAY
NOP [1us]
No [3us]
FIM DO TEMPO1 ?
Sim RETURN
38
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 3 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //PISCA-PISCA VARIVEL PARA DEMONSTRAR A IMPLEMENTAO DE DELAYS E A INVERSO //DE PORTAS. APENAS OS BOTES DA LINHA 4 ESTO ATIVADOS SENDO QUE O DA //COLUNA 1 UTILIZADO PARA INCREMENTAR O TEMPO ENTRE AS PISCADAS. //O BOTO DA COLUNA 2 UTILIZADO PARA DIMINUIR O TEMPO ENTRE AS PISCADAS. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1
39
FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char CONTADOR; //BASE DE TEMPO PARA A PISCADA unsigned char TEMPO1; //REGISTRADORES AUXILIARES DE TEMPO /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define MIN 10 #define MAX 240 #define STEP 5 #define MULTIPLO 5 //A CONSTANTE DISPLAY REPRESENTA O SMBOLO QUE APARECER PISCANDO NO //DISPLAY. 1=LED LIGADO E 0=LED DESLIGADO. A RELAO ENTRE BITS E //SEGMENTOS A SEGUINTE: '.GFEDCBA' // a // ********** // * * // f * * b // * g * // ********** // * * // e * * c // * d * // ********** *. #define DISPLAY 0b01110110 //(LETRA H)
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //As entradas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define BT1 PORTBbits.RB0 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO
#define
BT2
PORTBbits.RB1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
40
//As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define DSP_UNIDADE PORTBbits.RB7 //PORTA DO LED //0 -> APAGADO //1 -> ACESO //PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
#define
LINHA_4
PORTBbits.RB7
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011111; 0b00000000; 0b00000111;
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ DSP_UNIDADE = 1; PORTD = DISPLAY; //ACENDE O VALOR CERTO NO DISPLAY CONTADOR = MIN; //INICIA CONTADOR COM VALOR MIN. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * while(1) { ClrWdt(); TEMPO1 = MULTIPLO; do { Delay1KTCYx(CONTADOR); if (BT1) { CONTADOR = CONTADOR - STEP; //INCREMENTA O CONTADOR EM if (CONTADOR < MIN) { CONTADOR = MIN; while(BT1) ClrWdt(); } continue; } * * */
STEP
if (BT2) { CONTADOR = CONTADOR + STEP; //INCREMENTA O CONTADOR EM STEP if (CONTADOR >= MAX) { CONTADOR = MAX;
41
while(BT2) ClrWdt(); } continue; } }while(--TEMPO1); PORTD = PORTD ^ DISPLAY; } } // FIM DO PROGRAMA //VOLTA PARA O INICIO ENQUANTO //TEMPO1 DIFERENTE DE ZERO //INVERTE O PORTD
42
Dicas e Comentrios
A rotina de delay recebe o argumento passado pelo WORK para determinar o delay que deve ser gerado, no entanto, o valor mximo assumido pelo WORK 255 e conforme comentado o delay mximo gerado de 256ms. Como isto possvel? Acontece que a rotina foi escrita de forma que ela executada pelo menos uma vez. Assim, a rotina executa um delay de 1ms, decrementa o argumento e quando este igual a zero retorna. Porm, quando o argumento passado pelo WORK zero, ao primeiro decremento, o argumento estoura e pula para 255. Como a condio testada aps o decremento e como aps o decremento o valor do argumento 255, o delay continua a ser gerado, por mais 255 vezes e desta forma obtm-se um delay de 256ms. A proposta da rotina de delay foi gerar um delay fundamental em 1ms, porm, a mesma idia pode ser utilizada para criar rotinas com delays fundamentais diferentes.
Exerccios Propostos
1. Alterar a rotina de delay para gerar um delay fundamental de 100us. 2. Alterar a rotina de delay para gerar um delay fundamental de 10ms. 3. Incluir o tratamento de debounce nas teclas
43
Objetivo
O objetivo desta experincia ensinar ao aluno como criar um decodificar BCD para displays de 7 segmentos.
Descrio
Os displays utilizados no McMaster so conhecidos como displays de leds de 7 segmentos, pois os nmeros so compostos por 7 traos. Estes componentes possuem ainda o ponto decimal e so considerados displays numricos, por no possurem traos suficientes para a exibio de todas as letras do nosso alfabeto. Para facilitar a vida do projetista o mercado padronizou uma nomenclatura para todos os traos do display, possibilitando que tratemos cada um deles individualmente:
G F Comum E D D E F
A B G C Dp
A B Comum C Dp
Desta forma, temos um pino para controlar cada um dos segmentos (A...G) e mais o ponto decimal (Dp). Os dois pinos adicionais so os comuns, que podem ser ligados a todos os catodos ou anodos dos leds internos. Por causa disso, estes displays so fornecidos em 2 tipos: catodo comum ou anodo comum. No nosso caso, os displays utilizados so do tipo catodo comum, isto , o pino comum deve ser ligado ao terra e os segmentos devem ser ligados ao Vcc para acenderem. Outra observao importante que a pinagem descrita no desenho vlida para o tipo de display utilizado no McMaster. Existem displays de outros tamanhos que possuem uma disposio de pinos diferente. Como cada segmento um led individual, precisa-se de um pino do PIC para controlar cada segmento. Desta forma, so necessrios 8 pinos para acionar os 7 segmentos e mais o ponto decimal. A fim de converter o valor binrio de um algarismo em um valor de 8 bits que represente o este algarismo num display de 7 segmentos fez-se uso de uma tabela de converso. Por exemplo, para representar o algarismo 2 no display, deve-se acender os segmentos A, B, D, E e G. Como no kit McMaster o PORTD est conectado aos segmentos conforme a tabela
PIC 44 Segmento
A B C D E F G DP
para acender o algarismo 2 no display precisa-se colocar o valor 01011011b no PORTD, ou seja, colocar em 1 os bits ligados aos segmentos que se deseja acender. Assim, no software deve ser criada uma tabela para converter cada valor binrio numa representao que posta nos segmentos (PORTD) reproduza o valor binrio original. A tabela criada utilizando-se a instruo RETLW. O valor binrio que se deseja converter adicionado ao PCL (program counter) de forma a desviar o fluxo do programa para a linha que contm a combinao de 0 e 1 que formaro o caractere no display. O software utiliza as teclas da linha 4 colunas 1 e 2 para incrementar e decrementar o valor da varivel CONTADOR. Esta varivel est limitada pelas constantes "MIN" e "MAX". A tabela de converso foi utilizada a fim de visualizar o valor da varivel CONTADOR no display de 7 segmentos.
45
Esquema Eltrico
46
Fluxograma
INCIO
CARREGA CONTADOR COM VALOR MNIMO 3 RECARREGA FILTRO DE DEBOUNCE 4 BOTO 1 PRESS.? No BOTO 2 PRESS.? No Sim Sim
47
No
No
CONTADOR=MN?
Sim
CONTADOR=MX?
Sim
No DECREMENTA CONTADOR
No INCREMENTA CONTADOR
48
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 4 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //SOFTWARE QUE UTILIZA DOIS BOTES PARA INCREMENTAR E DECREMENTAR UM //CONTADOR. O VALOR MOSTRADO NO DISPLAY DE 7 SEGMENTOS. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF
49
VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char CONTADOR; //ARMAZENA O VALOR DA CONTAGEM unsigned char FILTRO11; //FILTRAGEM 1 PARA O BOTO 1 unsigned char FILTRO12; //FILTRAGEM 2 PARA O BOTO 1 unsigned char FILTRO21; //FILTRAGEM 1 PARA O BOTO 2 unsigned char FILTRO22; //FILTRAGEM 2 PARA O BOTO 2 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define MIN 0 #define MAX 15 #define T_FILTRO 5 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE #define #define ST_BT1 ST_BT2 FLAGSbits.BIT0 FLAGSbits.BIT1 //STATUS DO BOTO 1 //STATUS DO BOTO 2
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //As entradas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define BT1 PORTBbits.RB0 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e
#define
BT2
PORTBbits.RB1
50
#define
LINHA_4
PORTBbits.RB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
// // // // // // // // // // // // // // // //
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ROTINA DE CONVERSO BINRIO -> DISPLAY * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ESTA ROTINA IR RETORNAR EM W, O SIMBOLO CORRETO QUE DEVE SER MOSTRADO NO DISPLAY PARA CADA VALOR DE INTENSIDADE. O RETORNO J EST FORMATADO PARA AS CONDIES DE LIGAO DO DISPLAY AO PORTD. a ********** * * f * * b * g * ********** * * e * * c * d * ********** *.
const rom unsigned char CONVERTE[16] = {// .GFEDCBA POSIO CORRETA DOS SEGMENTOS 0b00111111, // 00 - RETORNA SMBOLO CORRETO 0b00000110, // 01 - RETORNA SMBOLO CORRETO 0b01011011, // 02 - RETORNA SMBOLO CORRETO 0b01001111, // 03 - RETORNA SMBOLO CORRETO 0b01100110, // 04 - RETORNA SMBOLO CORRETO 0b01101101, // 05 - RETORNA SMBOLO CORRETO 0b01111101, // 06 - RETORNA SMBOLO CORRETO 0b00000111, // 07 - RETORNA SMBOLO CORRETO 0b01111111, // 08 - RETORNA SMBOLO CORRETO 0b01101111, // 09 - RETORNA SMBOLO CORRETO 0b01110111, // 10 - RETORNA SMBOLO CORRETO 0b01111100, // 11 - RETORNA SMBOLO CORRETO 0b00111001, // 12 - RETORNA SMBOLO CORRETO 0b01011110, // 13 - RETORNA SMBOLO CORRETO 0b01111001, // 14 - RETORNA SMBOLO CORRETO 0b01110001}; // 15 - RETORNA SMBOLO CORRETO
0 1 2 3 4 5 6 7 8 9 A b C d E F
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011001; 0b00000000; 0b00000000;
= = = = =
ADCON1 = 0b00001111;
51
ST_BT1 = 0; ST_BT2 = 0; CONTADOR = MIN; PORTD = CONVERTE[CONTADOR]; /* * * * * * * * * * * * * * * * * * * while(1) { ClrWdt(); FILTRO11 = FILTRO21 = FILTRO12 = FILTRO22 =
* * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0; 0; T_FILTRO; T_FILTRO;
while (BT1) { ClrWdt(); if (--FILTRO11 == 0) { FILTRO12--; if(FILTRO12 == 0) { if (CONTADOR != MIN) { if (!ST_BT1) { CONTADOR--; PORTD = CONVERTE[CONTADOR]; ST_BT1 = 1; } } } } } ST_BT1 = 0; // BOTO LIBERADO, LIMPA O FLAG while (BT2) { ClrWdt(); if (--FILTRO21 == 0) { FILTRO22--; if(FILTRO22 == 0) { if (CONTADOR != MAX) { if (!ST_BT2) { CONTADOR++; PORTD = CONVERTE[CONTADOR]; ST_BT2 = 1; } } } } } ST_BT2 = 0; // BOTO LIBERADO, LIMPA O FLAG } } // FIM DO PROGRAMA
52
Dicas e Comentrios
A tabela implementada neste exemplo apresenta 16 linhas, assim, possvel representar qualquer valor hexadecimal entre 0h e Fh. No entanto, utilizando o mesmo conceito poderamos criar representaes para praticamente todas as letras do alfabeto. E para escrever mensagens no display bastaria associar a cada letra um nmero binrio. O conceito da tabela no se limita apenas utilizao com displays de 7 segmentos, infinitas situaes podem ser resolvidas com o uso de uma tabela. Por exemplo, pode-se criar uma tabela para converter nmeros binrios em caracteres ASCII e vice-versa.
Exerccios Propostos
1. Mantendo as 16 linhas atuais, alterar a tabela para mostrar as letras: A, b, C, d, E, F, G, H, I, J, L, n, O, P, r e S. 2. Alterar o software a fim de utilizar uma tabela que contenha todos os nmeros e todas as possveis letras.
53
Objetivo
O uso de rotinas de delays para contagem de tempo nem sempre pode ser aplicado, uma vez que este tipo de rotina deixa o processador parado. Um recurso muito mais adequado para a contagem de tempos a utilizao do timer do microcontrolador. Este o objetivo desta experincia. Ensinar ao aluno como configurar e utilizar o timer e a interrupo.
Descrio
Esta experincia cria um timer decrescente em segundos. O valor inicial determinado pela constante V_INICIO e pode estar entre 1 e 15 segundos. Os botes ativos so os da linha 4. O boto da coluna 1 dispara o timer, mostrando o tempo restante no display. O da coluna 2 paralisa o timer. O led ligado ao pino RC0 utilizado para indicar o estado atual do timer sendo acesso se o timer estiver rodando e apagado se o timer estiver parado. O timer utiliza como base de tempo a interrupo de TMR0 sendo que esta ocorre quando o timer estoura, ou seja, quando o valor do TMR0 pula de 0xFF para 0x00. Assim, o intervalo de tempo entre interrupes ir depender do prescaler configurado para o timer, do valor inicial com que ele carregado e do tempo de execuo de um ciclo de mquina. No exemplo desta experincia, sempre que se entra na interrupo de TMR0, o contador do timer carregado com 131, de forma que sempre se faa 125 contagens, pois, o timer ir contar de 131 at 256 e quando voltar a estourar ser novamente carregado com 131. Desta forma, podemos calcular o tempo entre interrupes seguindo a equao abaixo: Tempo TMR0 = (256 valor com que carregado) * prescaler * ciclo de mquina Tempo TMR0 = (256 131) * 64 * 1us Tempo TMR0 = 8ms Portanto, a interrupo ir ocorrer a cada 8ms. A fim de criar a base de tempo de 1 segundo, foi acrescentado um contador auxiliar que conta o nmero de ocorrncias da interrupo de TMR0. Com este contador auxiliar pode-se estender a base de tempo sempre em mltiplos de 8ms. Caso este contador auxiliar seja configurado para contar 125 interrupes de TMR0, pode-se obter a base de tempo de 1 segundo, fundamental para a criao do timer da experincia.
54
Esquema Eltrico
55
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURA I/Os PRESCALER TMR0 -> 1:64 HABILITA INTERRUPO DE TMR0 HABILITA DISPLAY DA UNIDADE E LINHA 4 DO TECLADO MATRICIAL
56
No
No
INTERRUPO LIGADA? No INICIALIZA TMR0 COM 131d INICIALIZA TEMP1 COM 125d ACENDE LED LIGA INTERRUPO
Sim
3 (256d-125d)=131d Prescale 1:64 Ciclo de Mquina = 1us TMR0 = 125*64us = 8ms TMR0 * TEMP1 = 8ms * 125 =
57
INT. TMR0 SALVA CONTEXTO LIMPA FLAG DA INTERRUPO RECARREGA TMR0 COM 131d
FIM DO TEMP1?
No
No
RECUPERA CONTEXTO
SAI DA INTERRUPO
58
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 5 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* TIMER DECRESCENTE EM SEGUNDOS. O VALOR INICIAL DETERMINADO PELA CONSTANTE V_INICIO E PODE ESTAR ENTRE 1 E 15 SEGUNDOS. OS BOTES ATIVOS SO O DA LINHA 4. O BOTO DA COLUNA 1 DISPARA O TIMER, MOSTRANDO O TEMPO RESTANTE NO DISPLAY. O DA COLUNA 2 PARALIZA O TIMER. O LED (RC0) UTILIZADO PARA INDICAR O ESTADO ATUAL DO TIMER: ACESO=RODANDO E APAGADO=PARADO */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF
59
#pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma
config config config config config config config config config config
PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char TEMPO; //ARMAZENA O VALOR DO TEMPO unsigned char FILTRO11; //FILTRAGEM 1 PARA O BOTO 1 unsigned char FILTRO12; //FILTRAGEM 2 PARA O BOTO 1 unsigned char FILTRO21; //FILTRAGEM 1 PARA O BOTO 2 unsigned char FILTRO22; //FILTRAGEM 2 PARA O BOTO 2 unsigned char TEMP1; //REGISTRADORES AUXILIARES unsigned char TEMP2; // /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define V_INICIO 15 #define T_FILTRO 255 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE #define #define #define ST_BT1 ST_BT2 F_FIM FLAGSbits.BIT0 FLAGSbits.BIT1 FLAGSbits.BIT2 //STATUS DO BOTO 1 //STATUS DO BOTO 2 //FLAG DE FIM DE TEMPO
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void TRATA_INT_TIMER0 (void); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //As entradas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define BT1 PORTBbits.RB0 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO
#define
BT2
PORTBbits.RB1
60
//1 -> PRESSIONADO //0 -> LIBERADO /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4 * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e
LATBbits.LATB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA //DEFINE PINO DO LED //0 -> LED APAGADO //1 -> LED ACESO
#define
LED
LATCbits.LATC0
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // * ROTINA DE TRATAMENTO DE INT DE TIMER0 * // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #pragma code TIMER0_interrupt = 0x0008 void TIMER0_int (void) { _asm goto TRATA_INT_TIMER0 _endasm } #pragma code #pragma interrupt TRATA_INT_TIMER0 void TRATA_INT_TIMER0 (void) { INTCONbits.TMR0IF = 0; WriteTimer0(256 - 125); TEMP1--; if (TEMP1 == 0) { TEMP1 = 125; if(F_FIM == 1) return; TEMPO--; if(TEMPO == 0) F_FIM = 1; } } // // // // // // // // // // // // // // // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ROTINA DE CONVERSO BINRIO -> DISPLAY * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ESTA ROTINA IR RETORNAR EM W, O SIMBOLO CORRETO QUE DEVE SER MOSTRADO NO DISPLAY PARA CADA VALOR DE INTENSIDADE. O RETORNO J EST FORMATADO PARA AS CONDIES DE LIGAO DO DISPLAY AO PORTD. a ********** * * f * * b * g * ********** * * e * * c * d * ********** *.
const rom unsigned char CONVERTE[16] = {// .GFEDCBA POSIO CORRETA DOS SEGMENTOS 0b00111111, // 00 - RETORNA SMBOLO CORRETO 0b00000110, // 01 - RETORNA SMBOLO CORRETO 0b01011011, // 02 - RETORNA SMBOLO CORRETO 0b01001111, // 03 - RETORNA SMBOLO CORRETO 0b01100110, // 04 - RETORNA SMBOLO CORRETO 0b01101101, // 05 - RETORNA SMBOLO CORRETO 0b01111101, // 06 - RETORNA SMBOLO CORRETO 0b00000111, // 07 - RETORNA SMBOLO CORRETO
0 1 2 3 4 5 6 7
61
// // // // // // // //
08 09 10 11 12 13 14 15
8 9 A b C d E F
/* * * // //
//CONVERTE CONTADOR NO NMERO DO //DISPLAY E ATUALIZA O PORTD PARA //VISUALIZARMOS O VALOR DE CONTADOR //NO DISPLAY
} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ROTINA DE DESLIGAR O TIMER * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // ESTA ROTINA EXECUTA AS AES NECESSRIAS PARA DESLIGAR O TIMER void DESL_TIMER(void) { INTCONbits.GIE = 0; LED = 0; }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ROTINA DE LIGAR O TIMER * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // ESTA ROTINA EXECUTA AS AES NECESSRIAS PARA LIGAR O TIMER void LIGA_TIMER(void) { if(INTCONbits.GIE == 1) { return; } INTCONbits.TMR0IF = 0; WriteTimer0(256 - 125); TEMP1 = 125; INTCONbits.GIE = 1; LED = 1; //LIMPA FLAG DE INTERRUPO //INICIA TIMER0 E TEMP1 //LIGA CHAVE GERAL DE INT. //LIGA O LED
} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
62
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_EDGE_FALL & T0_PS_1_64); LINHA_4 = 1; ST_BT1 = 0; ST_BT2 = 0; F_FIM = 0; //ATIVA A LINHA 4 DO TECLADO E DISPLAY DA UNIDADE //LIMPA FLAGS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { FILTRO11 = 0; FILTRO21 = 0; FILTRO12 = T_FILTRO; FILTRO22 = T_FILTRO; LATD = CONVERTE[TEMPO]; //ATUALIZA O DISPLAY while (BT1) { ClrWdt(); if (--FILTRO11 == 0) { FILTRO12--; if(FILTRO12 == 0) { if (!ST_BT1) { LIGA_TIMER(); ST_BT1 = 1; } } } } ST_BT1 = 0; // BOTO LIBERADO, LIMPA O FLAG while (BT2) { ClrWdt(); if (--FILTRO21 == 0) { FILTRO22--; if(FILTRO22 == 0) { if (!ST_BT2) { DESL_TIMER(); ST_BT2 = 1; } } } } ST_BT2 = 0; // BOTO LIBERADO, LIMPA O FLAG } } // FIM DO PROGRAMA ST_BT2 = 0; // BOTO LIBERADO, LIMPA O FLAG
63
Dicas e Comentrios
No exemplo desta experincia, sempre que ocorre a interrupo, o valor do TMR0 carregado com 131 de forma a obter uma contagem de 125 ciclos. Porm, o contador do TMR0 no ficou parado entre o instante em que a interrupo ocorreu e o instante em que ele foi novamente carregado. Por este motivo, pode ocorrer, que no instante em que o contador novamente carregado com 131 ele j esteja com outro valor diferente de zero e a a contagem no seria de exatamente 125 ciclos. No o caso deste exemplo, mais se o prescaler fosse de 1:1, ou seja, se o contador fosse incrementado a cada ciclo de mquina, quando a interrupo ocorresse e o contador fosse carregado, com certeza, o seu valor j seria diferente de zero. No caso do exemplo, o contador valeria 10, pois foram gastos 2 ciclos de mquina para desviar o programa para o vetor de interrupo, mais 3 ciclos para salvar o contexto, mais 2 ciclos para testar se a interrupo era de TMR0, mais 1 ciclo para limpar o bit da interrupo e mais 2 ciclos para efetivamente fazer a carga do contador. No total foram gastos 10 ciclos entre o instante em que a interrupo ocorreu e o instante em que o contador foi carregado com 131. Portanto, o tempo entre interrupes que deveria ser de 125 ciclos passou para 135 ciclos. Isto provoca um erro na contagem de tempo. Para corrigir este problema, deve-se somar o valor ao timer e no carrega-lo com um valor e desprezar o que ele j contou. Ainda admitindo que o prescaler fosse de 1:1, se fosse somado ao timer o valor 131, aps a soma, o resultado final seria 141, sendo que 10 ele prprio j teria contado e 131 que foram somados. Desse instante at a prxima interrupo ocorreriam 115 contagens (256 141 = 115) e o tempo total entre interrupes se manteria conforme o desejado, ou seja, a cada 125 contagens.
Exerccios Propostos
1. Alterar o prescaler para 1:16 e obter a mesma base de tempo de 1 segundo. 2. Alterar o software para obter a mesma base de tempo de 1 segundo, porm sem utilizar o prescaler, ou seja, com prescaler configurado em 1:1. 3. Alterar a base de tempo do timer de 1 segundo para 60 segundos, ou seja, alterar o timer de segundos original para um timer de minutos.
64
Objetivo
O objetivo desta experincia o aprendizado da utilizao da memria de dados no voltil EEPROM interna do microcontrolador.
Descrio
Nesta experincia foram implementadas rotinas para escrita e leitura de dados na memria EEPROM. O exemplo estudado na experincia 4 foi modificado e sempre que o valor da varivel CONTADOR alterado o seu valor salvo na memria EEPROM. Ao inicializar o microcontrolador, a memria lida e ento o valor original pode ser restaurado. Assim, mesmo na queda de energia, o valor do contador preservado.
65
Esquema Eltrico
66
Fluxograma
INCIO
L CONTADOR DA EEPROM 3 RECARREGA FILTRO DE DEBOUNCE 4 BOTO 1 PRESS.? No BOTO 2 PRESS.? No Sim Sim
67
No
No
CONTADOR=MN?
Sim
CONTADOR=MX?
Sim
No DECREMENTA CONTADOR
No INCREMENTA CONTADOR
68
GRAVA EEPROM
L EEPROM
EECON2=0x55 EECON2=0xAA
RETURN
No
ACABOU ESCRITA?
Sim RETURN
69
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 6 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //SOFTWARE QUE UTILIZA DOIS BOTES PARA INCREMENTAR E DECREMENTAR UM //CONTADOR. O VALOR MOSTRADO NO DISPLAY DE 7 SEGMENTOS. //O VALOR GRAVADO NA EEPROM INTERNA E AO LIGAR A PLACA O LTIMO VALOR //MOSTRADO /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1
70
FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char CONTADOR; //ARMAZENA O VALOR DA CONTAGEM unsigned char FILTRO11; //FILTRAGEM 1 PARA O BOTO 1 unsigned char FILTRO12; //FILTRAGEM 2 PARA O BOTO 1 unsigned char FILTRO21; //FILTRAGEM 1 PARA O BOTO 2 unsigned char FILTRO22; //FILTRAGEM 2 PARA O BOTO 2 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define MIN 0 #define MAX 15 #define T_FILTRO 5 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE #define #define ST_BT1 ST_BT2 FLAGSbits.BIT0 FLAGSbits.BIT1 //STATUS DO BOTO 1 //STATUS DO BOTO 2
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void write_EEPROM(unsigned char endereco, unsigned char dado); unsigned char read_EEPROM(unsigned char endereco); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //As entradas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define BT1 PORTBbits.RB0 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO
#define
BT2
PORTBbits.RB1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
71
* SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define LINHA_4 PORTBbits.RB7 //PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
// // // // // // // // // // // // // // // //
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ROTINA DE CONVERSO BINRIO -> DISPLAY * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ESTA ROTINA IR RETORNAR EM W, O SIMBOLO CORRETO QUE DEVE SER MOSTRADO NO DISPLAY PARA CADA VALOR DE INTENSIDADE. O RETORNO J EST FORMATADO PARA AS CONDIES DE LIGAO DO DISPLAY AO PORTD. a ********** * * f * * b * g * ********** * * e * * c * d * ********** *.
const rom unsigned char CONVERTE[16] = {// .GFEDCBA POSIO CORRETA DOS SEGMENTOS 0b00111111, // 00 - RETORNA SMBOLO CORRETO 0b00000110, // 01 - RETORNA SMBOLO CORRETO 0b01011011, // 02 - RETORNA SMBOLO CORRETO 0b01001111, // 03 - RETORNA SMBOLO CORRETO 0b01100110, // 04 - RETORNA SMBOLO CORRETO 0b01101101, // 05 - RETORNA SMBOLO CORRETO 0b01111101, // 06 - RETORNA SMBOLO CORRETO 0b00000111, // 07 - RETORNA SMBOLO CORRETO 0b01111111, // 08 - RETORNA SMBOLO CORRETO 0b01101111, // 09 - RETORNA SMBOLO CORRETO 0b01110111, // 10 - RETORNA SMBOLO CORRETO 0b01111100, // 11 - RETORNA SMBOLO CORRETO 0b00111001, // 12 - RETORNA SMBOLO CORRETO 0b01011110, // 13 - RETORNA SMBOLO CORRETO 0b01111001, // 14 - RETORNA SMBOLO CORRETO 0b01110001}; // 15 - RETORNA SMBOLO CORRETO
0 1 2 3 4 5 6 7 8 9 A b C d E F
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de escrita da EEPROM interna * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void write_EEPROM(unsigned char endereco, unsigned char dado) { EEDATA = dado; //carrega dado EEADR = endereco; //carrega endereo EECON1bits.CFGS = 0; EECON1bits.EEPGD = 0; EECON1bits.WREN = 1; INTCONbits.GIE = 0; EECON2 = 0x55; EECON2 = 0xAA; EECON1bits.WR = 1; INTCONbits.GIE = 1; while(EECON1bits.WR); EECON1bits.WREN = 0; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de leitura da EEPROM interna * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ unsigned char read_EEPROM(unsigned char endereco) //habilita acesso a EEPROM //aponta para memria de dados //habilita escrita //desabilita todas as interrupes //escreve 0x55 em EECON2 (obrigatrio) //escreve 0xAA em EECON2 (obrigatrio) //inicia a escrita //habilita todas as interrupes //aguarda bit WR de EECON1 = 0 //desabilita escrita
72
{ EEADR = endereco; EECON1bits.CFGS = 0; EECON1bits.EEPGD = 0; EECON1bits.RD = 1; return(EEDATA); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE //carrega endereo //habilita acesso a EEPROM //aponta para memria de dados //habilita leitura //retorna dado disponvel em EEDATA
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011001; 0b00000000; 0b00000000;
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LINHA_4 = 1; ST_BT1 = 0; ST_BT2 = 0; CONTADOR = read_EEPROM(0X00) & 0x0F; PORTD = CONVERTE[CONTADOR]; /* * * * * * * * * * * * * * * * * * * while(1) { ClrWdt(); FILTRO11 = FILTRO21 = FILTRO12 = FILTRO22 = //ATUALIZA O DISPLAY INICIALMENTE //ATIVA A LINHA 4 DO TECLADO E DISPLAY DA UNIDADE
* * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0; 0; T_FILTRO; T_FILTRO;
73
CONTADOR--; PORTD = CONVERTE[CONTADOR]; write_EEPROM(0X00, CONTADOR); ST_BT1 = 1; } } } } } ST_BT1 = 0; // BOTO LIBERADO, LIMPA O FLAG while (BT2) { ClrWdt(); if (--FILTRO21 == 0) { FILTRO22--; if(FILTRO22 == 0) { if (CONTADOR != MAX) { if (!ST_BT2) { CONTADOR++; PORTD = CONVERTE[CONTADOR]; write_EEPROM(0X00, CONTADOR); ST_BT2 = 1; } } } } } ST_BT2 = 0; // BOTO LIBERADO, LIMPA O FLAG } } // FIM DO PROGRAMA
74
Dicas e Comentrios
A memria EEPROM do microcontrolador PIC18F4550 pode ser lida a qualquer momento e infinitas vezes, isto , no existe um limite para a quantidade de leituras que so realizadas na memria de dados. Porm, no caso da escrita, a memria EEPROM do PIC18F4550 possui uma vida til limitada. Atualmente o fabricante do componente garante uma vida til de aproximadamente 1.000.000 de ciclos de escrita. Apesar deste nmero parecer extremamente alto, existem casos no qual este limite pode ser atingido com relativa facilidade. Portanto, sempre que se desenvolve um sistema que utilize a memria EEPROM e que necessite realizar um nmero de escritas considervel, deve-se pensar se o limite de 1.000.000 de ciclos ser ou no atingido.
Exerccios Propostos
1. Alterar a posio onde o dado armazenado na memria EEPROM. 2. Alterar o valor inicial do contador. 3. Acrescentar duas teclas, uma para salvar o dado na memria e outra para ler o dado da memria. Neste caso o contador no pode ser salvo sempre que alterado, apenas ser salvo quando a tecla correta for pressionada. Quanto leitura, deve ser realizada tanto na inicializao do software como quando forada pela tecla.
75
Objetivo
O objetivo desta experincia ensinar ao aluno como regular a potncia fornecida a pequenas cargas atravs do microcontrolador. Para isso, proposto um dimmer para uma lmpada incandescente (leia obsevao abaixo) onde a potncia regulada atravs do uso de um PWM criado no software. Obs: O acionamento da lmpada possvel apenas quando trabalhamos com os microcontroladores PIC16F877A e PIC18F4520; o microcontrolador PIC18F4550 reserva esta sada para o mdulo USB interno; neste caso o exemplo acionar um led especial associado ao pino RC0 do microcontrolador.
Descrio
Software que utiliza dois botes para incrementar e decrementar a intensidade do led. A interrupo de tmr0 utilizada para controlar o PWM que aciona a lmpada. A intensidade tambm mostrada no display da unidade. Os botes ativos so os da linha 4. O boto da coluna 1 incrementa a intensidade da lmpada e o da coluna 2 decrementa a intensidade. Foi criado um PWM com 4 bits de resoluo de forma que existem 16 intensidades diferentes para a lmpada. Para sua implementao, utilizou-se a interrupo de TMR0 sendo que a cada interrupo uma varivel incrementada. Esta varivel utilizada para subdividir o PWM em 16 intervalos. Comparando esta varivel com o duty cycle ajustado pelo usurio, o software coloca o pino da lmpada em nvel lgico 1 ou 0, conforme a necessidade. A cada 16 interrupes o ciclo se repete e portanto o perodo do PWM 16 vezes maior do que o perodo de uma interrupo. Este procedimento pode ser facilmente analisado pelo fluxograma da experincia.
76
Esquema Eltrico
77
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURA I/Os PRESCALER TMR0 -> 1:4 HABILITA INTERRUPO DE TMR0 HABILITA DISPLAY DA UNIDADE E LINHA 4 DO TECLADO MATRICIAL
78
No
No
Sim
Sim
79
INT. TMR0 SALVA CONTEXTO LIMPA FLAG DA INTERRUPO RECARREGA TMR0 COM 6d perodo de 1ms INCREMENTA TEMP0
TEMP0 = 16 ?
No
INTENSIDADE = 15 ?
Sim
No
Sim
RECUPERA CONTEXTO
SAI DA INTERRUPO
80
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 7 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //SOFTWARE QUE UTILIZA DOIS BOTES PARA INCREMENTAR E DECREMENTAR A //INTENSIDADE DO LED. A INTERRUPO DE TMR0H UTILIZADA PARA CONTROLAR //O PWM QUE ACIONA O LED ESPECIAL (RC0) (CONFIGURAR O JUMPER "LEDS ESPECIAIS" //NA POSIO ON. A INTENSIDADE TAMBM MOSTRADA NO DISPLAY DA UNIDADE. //OS BOTES ATIVOS SO O DA LINHA 4 /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1
81
USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char INTENSIDADE; //ARMAZENA O VALOR DA CONTAGEM unsigned char FILTRO11; //FILTRAGEM 1 PARA O BOTO 1 unsigned char FILTRO12; //FILTRAGEM 2 PARA O BOTO 1 unsigned char FILTRO21; //FILTRAGEM 1 PARA O BOTO 2 unsigned char FILTRO22; //FILTRAGEM 2 PARA O BOTO 2 unsigned char TEMPO; //INTERVALOS DE 1 MS /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define MIN 0 #define MAX 15 #define T_FILTRO 5 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE #define #define ST_BT1 ST_BT2 FLAGSbits.BIT0 FLAGSbits.BIT1 //STATUS DO BOTO 1 //STATUS DO BOTO 2
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void TRATA_INT_TIMER0 (void); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //As entradas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define BT1 PORTBbits.RB0 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO
#define
BT2
PORTBbits.RB1
82
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4
LATBbits.LATB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA //DEFINE PINO DA LAMPADA //0 -> LMPADA APAGADA //1 -> LMPADA ACESA
#define
LAMPADA
LATCbits.LATC0
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // * ROTINA DE TRATAMENTO DE INT DE TIMER0 * // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #pragma code TIMER0_interrupt = 0x0008 void TIMER0_int (void) { _asm goto TRATA_INT_TIMER0 _endasm } #pragma code #pragma interrupt TRATA_INT_TIMER0 void TRATA_INT_TIMER0 (void) { INTCONbits.TMR0IF = 0; WriteTimer0(256 - 250); TEMPO++; if (TEMPO == 16)TEMPO = 0; if (TEMPO >= INTENSIDADE) LAMPADA = 0; else LAMPADA = 1; } // // // // // // // // // // // // // // // //
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ROTINA DE CONVERSO BINRIO -> DISPLAY * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ESTA ROTINA IR RETORNAR EM W, O SIMBOLO CORRETO QUE DEVE SER MOSTRADO NO DISPLAY PARA CADA VALOR DE INTENSIDADE. O RETORNO J EST FORMATADO PARA AS CONDIES DE LIGAO DO DISPLAY AO PORTD. a ********** * * f * * b * g * ********** * * e * * c * d * ********** *.
const rom unsigned char CONVERTE[16] = {// .GFEDCBA POSIO CORRETA DOS SEGMENTOS 0b00111111, // 00 - RETORNA SMBOLO CORRETO 0b00000110, // 01 - RETORNA SMBOLO CORRETO 0b01011011, // 02 - RETORNA SMBOLO CORRETO 0b01001111, // 03 - RETORNA SMBOLO CORRETO 0b01100110, // 04 - RETORNA SMBOLO CORRETO 0b01101101, // 05 - RETORNA SMBOLO CORRETO 0b01111101, // 06 - RETORNA SMBOLO CORRETO 0b00000111, // 07 - RETORNA SMBOLO CORRETO 0b01111111, // 08 - RETORNA SMBOLO CORRETO 0b01101111, // 09 - RETORNA SMBOLO CORRETO 0b01110111, // 10 - RETORNA SMBOLO CORRETO 0b01111100, // 11 - RETORNA SMBOLO CORRETO 0b00111001, // 12 - RETORNA SMBOLO CORRETO 0b01011110, // 13 - RETORNA SMBOLO CORRETO 0b01111001, // 14 - RETORNA SMBOLO CORRETO 0b01110001}; // 15 - RETORNA SMBOLO CORRETO
0 1 2 3 4 5 6 7 8 9 A b C d E F
83
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011000; 0b00000000; 0b00000000;
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_4); LINHA_4 = 1; //ATIVA A LINHA 4 DO TECLADO E DISPLAY DA UNIDADE
ST_BT1 = 0; ST_BT2 = 0; INTENSIDADE = MIN; WriteTimer0(256 - 250); PORTD = CONVERTE[INTENSIDADE]; RCON = 0x00; INTCONbits.GIEH = 1; /* * * * * * * * * * * * * * * * * * * while(1) { ClrWdt(); FILTRO11 = FILTRO21 = FILTRO12 = FILTRO22 =
//INICIA INTENSIDADE = MIN //REINICIA TMR0H, SETA TIMER P/ 1ms //ATUALIZA O DISPLAY INICIALMENTE
* * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0; 0; T_FILTRO; T_FILTRO;
while (BT1) { ClrWdt(); if (--FILTRO11 == 0) { FILTRO12--; if(FILTRO12 == 0) { if (INTENSIDADE != MIN) { if (!ST_BT1) { INTENSIDADE--; PORTD = CONVERTE[INTENSIDADE]; ST_BT1 = 1; } } }
84
} } ST_BT1 = 0; // BOTO LIBERADO, LIMPA O FLAG while (BT2) { ClrWdt(); if (--FILTRO21 == 0) { FILTRO22--; if(FILTRO22 == 0) { if (INTENSIDADE != MAX) { if (!ST_BT2) { INTENSIDADE++; PORTD = CONVERTE[INTENSIDADE]; ST_BT2 = 1; } } } } } ST_BT2 = 0; // BOTO LIBERADO, LIMPA O FLAG } } // FIM DO PROGRAMA
85
Dicas e Comentrios
A tcnica utilizada nesta experincia para implementar o PWM apresenta como inconveniente resultar em PWMs de baixa freqncia. Por exemplo, no caso desta experincia a interrupo ocorre a cada 1ms e como o PWM tm 4 bits de resoluo, temos um perodo total de 16ms para o PWM. Isto significa que a freqncia de 62,5Hz, ou seja, o PWM implementado via software apresenta baixa freqncia. Alm disso, se ele fosse de por exemplo 8 bits, o perodo passaria para 256ms e, portanto, a freqncia cairia para aproximadamente 4Hz, ou seja, extremamente baixa. Note que quanto maior a resoluo desejada maior o perodo do PWM.
Exerccios Propostos
1. Altere a freqncia do PWM alterando a base de tempo do TMR0 para 100us. 2. Altere o PWM para trabalhar com apenas 2 bits de resoluo. 3. Acrescente as rotinas de leitura e escrita na EEPROM para salvar e recuperar a intensidade da lmpada mesmo na falta de energia.
86
Objetivo
O objetivo desta experincia dar continuidade ao aprendizado das interrupes e em particular interrupo de TMR2 utilizada nesta experincia para excitar o buzzer.
Descrio
O buzzer utilizado no McMaster no do tipo auto-oscilante, ou seja, este tipo de buzzer precisa ser excitado externamente para emitir algum som. Assim, o microcontrolador deve ser responsvel por gerar uma onda quadrada a fim de excitar o piezo-eltrico e fazer com que o buzzer emita algum som. Operar com este tipo de buzzer muito mais trabalhoso do que com um buzzer auto-oscilante, j que no basta ligar-lo, necessrio aplicar uma onda quadrada para que o buzzer funcione. Porm, ele d margem criao de diferentes tons, pois, quem gera a freqncia da onda quadrada e conseqentemente o tom com que o buzzer ir tocar o microcontrolador e se este gerar freqncias adequadas, pode-se implementar at mesmo uma simples melodia. Apesar desta experincia utilizar o TMR2 para excitar o buzzer com freqncia varivel, o objetivo no a implementao de notas musicais, embora isto seja possvel. Diferente dos outros timers do microcontrolador, o TMR2 estoura e pode gerar uma interrupo sempre que o seu valor ultrapassa o valor de um registrador especial, denominado PR2. Ou seja, o TMR2, diferentemente dos outros timers conta desde zero at o valor programado no registrador PR2 e no at 255 (a no ser que o valor do registrador PR2 seja 255). Desta forma, o que o software faz ler o estado das teclas da linha 4 e em funo deste alterar o valor do registrador PR2. Conseqentemente, a interrupo de TMR2 varia de perodo, ou seja, a freqncia com que a interrupo ocorre depende do estado das teclas da linha 4. Como a interrupo a responsvel por gerar a onda quadrada que excita o buzzer e como a freqncia pode ser alterada pelas teclas, dependendo da configurao de teclas pressionadas o buzzer emite som em diferentes tonalidades, criando, embora com freqncia erradas uma espcie de mini-teclado. Os leds ligados ao PORTD so utilizados apenas para repetir o estado das teclas pressionadas a fim de criar um efeito visual para a experincia.
87
Esquema Eltrico
88
Fluxograma
INICIO
RESET WDT ?
No
LIGA AS INTERRUPES
89
INTERRUPES
SALVA CONTEXTO
INT TMR2 ? No
INT TMR0 ? No
FIM INTERRUPO
RECUPERA CONTEXTO
SAI DA INTERRUPO
TRATA TMR2
No
LIGA SADA
FIM INTERRUPO
90
TRATA TMR0
FILTRO TERMINOU ?
No
CHECA BOTO 1
CHECA BOTO 2
CHECA BOTO 3
91
No
INICIALIZA TIMER 2
FIM INTERRUPO
92
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 8 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //ESTE SOFTWARE EST PREPARADO PARA LER QUATRO BOTES E TOCAR O BUZZER //COM DURAO VARIVEL CONFORME TECLA PRESSIONADA. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF
93
VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char filtro1; unsigned char filtro2; unsigned char filtro3; unsigned char filtro4; unsigned char status_leds=0; // atualiza leds conforme o boto pressionado unsigned char tabela[16] = {255,16,32,48,64,80,96,112,128,144,160,176,192,208,224,240}; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define MIN 0 #define MAX 15 #define t_filtro 25 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void TRATA_HIGH_INT(void); void TRATA_INT_TIMER0(void); void TRATA_INT_TIMER2(void); /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes #define botao1 * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO * * */ e
PORTBbits.RB0
#define
botao2
PORTBbits.RB1
#define
botao3
PORTBbits.RB2
#define
botao4
PORTBbits.RB3
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
94
//As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define C_LEDS LATAbits.LATA4 //PINO PARA ATIVAR GRUPO DE 8 LEDS //1 -> LEDS ATIVADOS //0 -> LEDS DESATIVADOS //PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
#define
LINHA_4 LATBbits.LATB7
#define
buzzer
LATEbits.LATE2
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // * ROTINA DE TRATAMENTO DE INT DE ALTA PRIORIDADE * // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #pragma code VETOR_HIGH_PRIORITY = 0x0008 void HIGH_int (void) { _asm goto TRATA_HIGH_INT _endasm } #pragma code #pragma interrupt TRATA_HIGH_INT void TRATA_HIGH_INT(void) { if(PIR1bits.TMR2IF) TRATA_INT_TIMER2(); if(INTCONbits.TMR0IF) TRATA_INT_TIMER0(); } void TRATA_INT_TIMER2(void) { PIR1bits.TMR2IF = 0; if (buzzer != 0) { buzzer = 0; } else { buzzer = 1; } } void TRATA_INT_TIMER0(void) { INTCONbits.TMR0IF = 0;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (botao1) // testa boto 1 { // boto 1 est pressionado ? filtro1--; // Sim, ento decrementa o filtro if (filtro1 == 0) // acabou o filtro do boto 1 ? { status_leds = status_leds | 0b00000001; // marca que o boto est pressionado } } else { // boto 1 liberado filtro1 = t_filtro; // inicia o filtro do boto 1 status_leds = status_leds & 0b11111110; // marca que o boto foi liberado } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
95
* Tratamento do Boto 2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (botao2) // testa boto 2 { // boto 2 est pressionado ? filtro2--; // Sim, ento decrementa o filtro if (filtro2 == 0) // fim do filtro do boto 2 ? { status_leds = status_leds | 0b00000010; // marca que o boto est pressionado } } else { // boto 2 liberado filtro2 = t_filtro; // inicia o filtro do boto 2 status_leds = status_leds & 0b11111101; // marca que o boto foi liberado } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (botao3) // testa boto 3 { // boto 3 est pressionado ? filtro3--; // Sim, ento decrementa o filtro if (filtro3 == 0) // fim do filtro do boto 3 ? { status_leds = status_leds | 0b00000100; // marca que o boto est pressionado } } else { // boto 3 liberado filtro3 = t_filtro; // inicia o filtro do boto 3 status_leds = status_leds & 0b11111011; // marca que o boto foi liberado } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 4 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ if (botao4) // testa boto 4 { // boto 4 est pressionado ? filtro4--; // Sim, ento decrementa o filtro if (filtro4 == 0) // fim do filtro do boto 4 ? { status_leds = status_leds | 0b00001000; // marca que o boto est pressionado } } else { // boto 4 liberado filtro4 = t_filtro; // inicia o filtro do boto 4 status_leds = status_leds & 0b11110111; // marca que o boto foi liberado } PORTD = status_leds;
96
{ PR2 = tabela[status_leds]; // consulta tabela e inicializa timer2. OpenTimer2(TIMER_INT_ON & T2_PS_1_1 & T2_POST_1_3); } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011111; 0b00000000; 0b00000011;
= = = = =
ADCON1 = 0b11111111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_4); PR2 = 0xff; OpenTimer2(TIMER_INT_OFF & T2_PS_1_1 & T2_POST_1_3); RCON = 0x00; C_LEDS = 1; LINHA_4 = 1; status_leds = 0; filtro1 filtro2 filtro3 filtro4 = = = = t_filtro; t_filtro; t_filtro; t_filtro; // // // // inicia inicia inicia inicia filtro filtro filtro filtro do do do do botao1 botao2 botao3 botao4 //ATIVA LEDS LIGADOS AO PORTD //ATIVA LINHA 4 DO TECLADO MATRICIAL
INTCONbits.TMR0IE = 1; // liga chave da int. do timer 0 PIE1bits.TMR2IE = 1; // liga chave da int. do timer 2 INTCONbits.PEIE = 1; // liga chave de perifricos INTCONbits.GIE = 1; // liga chave geral /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { Nop(); } } // FIM DO PROGRAMA
97
Dicas e Comentrios
Notar que nesta experincia foi utilizada uma tabela para retornar em funo do estado das teclas pressionadas o valor que deve ser carregado no registrador PR2. Ou seja, conforme comentado na experincia 4, a utilizao de tabelas no se limita apenas converso de BCD para display de 7 segmentos. Prova disso que nesta experincia a tabela foi til para exercer funo completamente diferente. O software desta experincia apresenta uma particularidade. Veja que no existe nenhuma instruo, a no ser o CLRWDT, no loop principal do programa. Assim, todas as instrues do software e toda a sua lgica est implementada apenas dentro das interrupes, sendo parte na interrupo de TMR0 e parte na interrupo de TMR2.
Exerccios Propostos
1. Alterar a configurao do TMR2 para que o buzzer seja excitado em outra faixa de freqncias. 2. Utilizar a instruo boleana XOR para inverter o estado do pino do buzzer. 3. Inverter a escala de freqncias, trocando a mais alta pela mais baixa.
98
Objetivo
O objetivo desta experincia o aprendizado do sistema de varredura comumente utilizado para varrer displays de 7 segmentos. Alm disso, visto o TMR1 fechando assim o estudo sobre os trs times do PIC18F4550.
Descrio
Cada display formado por um conjunto de 8 leds, sendo 7 para a caracterizao do dgito e 1 para o ponto decimal. Desta forma, precisaremos de um pino do PIC para controlar cada um dos leds e, portanto, sero necessrios 8 pinos para acionar os 7 segmentos e mais o ponto decimal. Porm, o McMaster no possui apenas um display e sim quatro. Seriam necessrios ento 32 pinos do microcontrolador para acionar os quatro displays? No, existe uma sada para isso. O segredo para minimizar a quantidade de pinos utilizados o emprego de um conceito denominado varredura. Para isso, interligam-se todos os displays, juntando todos os pinos de um mesmo segmento numa nica via, de forma a criar um barramento de dados com as vias de A at Dp. Em seguida, utiliza-se um pino para controlar o comum de cada um dos displays (total de 4 pinos). Assim, quando se deseja escrever em um dos displays, bastar informar os segmentos a serem acionados nas vias de dados e ligar o comum do display desejado. Utilizando o hardware desta forma fcil notar que apenas um dos displays poder ser acionado de cada vez. Porm, se acionarmos os displays continuamente, um aps o outro e de forma rpida, nossos olhos no conseguiram perceber que apenas um display est acionado por vez dando a impresso de que todos os displays esto acionados o tempo todo.
A B C D E F G Dp
Display 1
Display 2
Display 3
Display 4
Assim, empregando-se a tcnica de varredura, consegue-se controlar os 4 displays utilizando apenas 12 pinos do microcontrolador. O exemplo desenvolvido para esta experincia faz muito mais que simplesmente implementar a varredura dos displays. Trata-se de um contador regressivo de segundos, ou seja, um temporizador capaz de contar at 9.999 segundos. As teclas habilitadas so as da linha 4 e seguem as funes descritas na tabela.
Vias de Dados
99
Coluna 1 2 3 4
Descrio nenhuma funo Incrementa o valor inicial em 1 segundo Decrementa o valor inicial em 1 segundo Inicia e paralisa o temporizador
Para a contagem do tempo utilizou-se a interrupo de TMR1, configurada conforme a tabela a seguir. Ciclo de Maq. 1 s Prescale 8 Conta TMR1 62500 Auxiliar 2 Perodo 1.000.000 s Freqncia 1 Hz
Configurou-se o prescale do TMR1 em 1:8 e o contador foi inicializado com o valor total menos o desejado para a contagem (65.536 62.500). Desta maneira a interrupo ocorre a cada 0,5 segundo. A fim de criar a base de tempo de 1 segundo foi utilizada uma varivel auxiliar que decrementada a cada ocorrncia da interrupo.
100
Esquema Eltrico
101
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
No
INICIALIZA VARIVEIS
Sim
102
No
INT TMR0 ?
Sim
Sim
LINHA 4 HABILITADA ? No
No
LIMPA TODOS OS SEGMENTOS (BLANK) DECREMENTA TIMER DESLIGA TODOS OS DISPLAYS FIM DO TIMER ? Sim LIMPA FLAG DE TIMER LIGADO (LED) No CONSULTA TABELA E ACIONA DISPLAY CORRETO
RECUPERA CONTEXTO
SAI DA INTERRUPO
103
TRATA BOTO UP
TIMER LIGADO ?
Sim
TIMER LIGADO ?
Sim
No
No
FILTRO TERMINOU ?
No
FILTRO TERMINOU ?
No
Sim
Sim
No
No
INCREMENTA TIMER
DECREMENTA TIMER
104
Sim
No
FILTRO TERMINOU ?
No
Sim
No
TIMER LIGADO ?
TIMER ZERADO ?
Sim
105
INCREMENTA TIMER
DECREMENTA TIMER
INCREMENTA UNIDADE
DECREMENTA UNIDADE
No
UNIDADE = 10 ? Sim
No
No
DEZENA = 10 ? Sim
No
No
CENTENA = 10 ? Sim
No
No
No
RETURN
RETURN
106
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br LABTOOLS - MOSAICO DIDACTIC DIVISION Exemplo de Cdigo para utilizao com a McMaster Exemplo 9 * * * * * *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//ESTE EXEMPLO FOI PREPARADO PARA DEMOSNTRAR O FUNCIONAMENTO DO TIMER DE //16 BITS DO PIC (TMR1) E DA VARREDURA DE DISPLAYS MAIS BARRA DE LEDS. //CONSISTE NUM CONTADOR 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. //UMA BARRA DE LEDS INDICA QUE O TEMPORIZADOR EST OPERANDO. QUANDO O SISTEMA //CHEGA A 0000 A BARRA DE LEDS DESLIGADA AUTOMATICAMENTE.
// BOTES DA LINHA 4 -> COLUNA 1 (INCREMENTA) // // // -> COLUNA 2 (DECREMENTA) -> COLUNA 3 (LIGA CONTAGEM) -> COLUNA 4 (DESLIGA CONTAGEM)
/*
CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2)
*/
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
107
#include <p18F4550.h>
// Register definitions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <pwm.h> #include <adc.h> #include <timers.h> #include <delays.h> #include <i2c.h> #include <stdlib.h> #include <usart.h>
//PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#pragma config FOSC = HS #pragma config CPUDIV = OSC1_PLL2 #pragma config WDT = ON #pragma config WDTPS = 128 #pragma config LVP = OFF #pragma config PWRT = ON #pragma config BOR = OFF #pragma config BORV = 0 #pragma config PBADEN = OFF #pragma config DEBUG = OFF #pragma config PLLDIV = 1 #pragma config USBDIV = 1 #pragma config FCMEN = OFF #pragma config IESO = OFF #pragma config VREGEN = OFF #pragma config MCLRE = ON #pragma config LPT1OSC = OFF #pragma config CCP2MX = ON #pragma config STVREN = OFF #pragma config ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas *
108
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char display = 0; unsigned char contador = 2; unsigned char filtro = t_filtro; unsigned char filtro1 = t_filtro; unsigned char filtro2= t_filtro; unsigned char filtro3 = t_filtro; unsigned char filtro4 = t_filtro; unsigned char turbo = 1; unsigned char unidade = 9; unsigned char dezena = 9; unsigned char centena = 9; unsigned char milhar = 9; unsigned char botoes = 0; // atualiza os displays // contador de interrupes de timer1 // inicia filtro dos botes // inicia filtro dos botes // inicia filtro dos botes // inicia filtro dos botes // 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
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ESTA ROTINA IR RETORNAR EM W, O SIMBOLO CORRETO QUE DEVE SER // MOSTRADO NO DISPLAY PARA CADA VALOR DE INTENSIDADE. O RETORNO J EST // FORMATADO PARA AS CONDIES DE LIGAO DO DISPLAY AO PORTD. // // // // // // // // // // a ********** * f * * g * * b *
********** * e * * d * * c * *.
**********
const rom unsigned char converte[] = {// .GFEDCBA 0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, POSIO CORRETA DOS SEGMENTOS // 00 - RETORNA SMBOLO CORRETO 0 // 01 - RETORNA SMBOLO CORRETO 1 // 02 - RETORNA SMBOLO CORRETO 2 // 03 - RETORNA SMBOLO CORRETO 3 // 04 - RETORNA SMBOLO CORRETO 4 // 05 - RETORNA SMBOLO CORRETO 5 // 06 - RETORNA SMBOLO CORRETO 6 // 07 - RETORNA SMBOLO CORRETO 7
109
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE
#define
estado_timer
FLAGSbits.BIT0
//STATUS DO TIMER 1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void TRATA_HIGH_INT(void); void TRATA_INT_TIMER0(void); void TRATA_INT_TIMER1(void); void decrementa_timer(void); void incrementa_timer(void);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO E //FUTURAS ALTERAES DO HARDWARE.
#define BT_UP
PORTBbits.RB0
//BT_UP
#define BT_DOWN
PORTBbits.RB1
//BT_DOWN
110
#define BT_START
PORTBbits.RB2
//BT_START
#define BT_STOP
PORTBbits.RB3
//BT_STOP
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // AS SADAS DEVEM SER ASSOCIADAS A NOMES PARA FACILITAR A PROGRAMAO E //FUTURAS ALTERAES DO HARDWARE.
#define
ESTADO_TIMER
LATCbits.LATC0
// seleo do display unidade // seleo do display dezena // seleo do display centena // seleo do display milhar
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void decrementa_timer(void) { 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 de incremento do Timer * //MILHAR = 9 //MILHAR = 255? //CENTENA = 9 //DECREMENTA MILHAR //CENTENA = 255? //DEZENA = 9 //DECREMENTA CENTENA //DEZENA = 255? //UNIDADE = 9 //DECREMENTA DEZENA //DECREMENTA UNIDADE //UNIDADE = 255?
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void incrementa_timer(void)
111
{ unidade ++; if (unidade == 10) { unidade = 0; dezena ++; } if (dezena == 10) { dezena = 0; centena ++; } if (centena == 10) { centena = 0; milhar ++; } if (milhar == 10) { milhar = 0; } }
void TRATA_INT_TIMER1(void) { PIR1bits.TMR1IF = 0; WriteTimer1(delta_timer1); contador --; if (contador == 0) { WriteTimer1(delta_timer1); contador = 2; decrementa_timer(); if ((unidade == 0)&&(dezena == 0)&&(centena == 0)&&(milhar == 0)) est zerado? { estado_timer = 0; CloseTimer1(); } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina de Tratamento de interrupo de TMR0 * // sim, apaga o led e // timer // carraga timer1 // carrega contador de int // limpa flag de interrupo // carraga timer1 // decrementa contador de interrupes
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
112
void TRATA_INT_TIMER0(void) { INTCONbits.TMR0IF = 0; switch(display) { case 0: display++; C_LEDS = 0; PORTD = converte[milhar]; disp0 = 1; break; // incrementa a varivel de varredura // liga o display 3 // atualiza o portd // liga o display 0 // sai //LIMPA FLAG DE INTERRUPO // incio da varredura dos displays
case 1: display++; disp0 = 0; PORTD = converte[centena]; disp1 = 1; break; // incrementa a varivel de varredura // desliga o display 0 // atualiza o portd // liga o display 1 // sai
case 2: display++; disp1 = 0; PORTD = converte[dezena]; disp2 = 1; break; // incrementa a varivel de varredura // desliga o display 1 // atualiza o portd // liga o display 2 // sai
case 3: display = 0; disp2 = 0; PORTD = converte[unidade]; disp3 = 1; break; } // inicia em 0 a varivel de varredura // desliga o display 2 // atualiza o portd // liga o display 3 // sai
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; PORTD = 0x00; PORTE = 0x00; //Limpa PORTA //Limpa PORTB //Limpa PORTC //Limpa PORTD //Limpa PORTE
113
LATA = 0x00; LATB = 0x00; LATC = 0x00; LATD = 0x00; LATE = 0x00;
//Limpa PORTA //Limpa PORTB //Limpa PORTC //Limpa PORTD //Limpa PORTE
TRISA = 0b11111111; TRISB = 0b00001111; TRISC = 0b11111000; TRISD = 0b00000000; TRISE = 0b00000111;
//CONFIG DIREO DOS PINOS PORTA //CONFIG DIREO DOS PINOS PORTB //CONFIG DIREO DOS PINOS PORTC //CONFIG DIREO DOS PINOS PORTD //CONFIG DIREO DOS PINOS PORTE
ADCON1 = 0b00001111;
OpenTimer0(TIMER_INT_ON & T0_8BIT & T0_SOURCE_INT & T0_PS_1_2); // //CONFIGURAO DO TIMER0 & TIMER_INT_OFF & T1_SOURCE_INT & T1_8BIT_RW &
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
ESTADO_TIMER = 0;
//LIMPA ESTADO_TIMER
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Loop principal *
114
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 2 *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tratamento do Boto 3 *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
if(filtro3 == 0) {
115
if est zerado? {
((unidade!=0)||(dezena!=0)||(centena!=0)||(milhar!=0))
//
timer
ESTADO_TIMER = 1; contador = 2;
// no, indica que o timer est contando // carrega contador auxiliar // carraga timer1 // limpa flag de int tmr1 &
WriteTimer1(delta_timer1); PIR1bits.TMR1IF = 0;
OpenTimer1(T1_OSC1EN_OFF & TIMER_INT_ON & T1_SOURCE_INT T1_8BIT_RW & T1_PS_1_8); // liga o tratamento de interrupo de timer1
} } continue; } }
// testa boto 4
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
#pragma code VETOR_HIGH_PRIORITY = 0x0008 void HIGH_int (void) { _asm goto TRATA_HIGH_INT _endasm } #pragma code
116
Dicas e Comentrios
Observar que nesta experincia, ao entrar no tratamento das interrupes, a operao de salvar contexto maior que nas experincias anteriores. Isto por que agora salva-se tambm os valores de FSR e PCLATH pois os mesmos podem ser alterados dentro da interrupo.
Exerccios Propostos
1. Implemente o quarto boto, para resetar o temporizador (voltar a zero). 2. Implemente uma segunda velocidade para os botes de incremento e decremento, de forma que facilite o ajuste de valores maiores. 3. Em vez de fazer um timer somente de segundos, utilize os dois dgitos da esquerda para mostrar o tempo em minutos e os da direita para mostrar o tempo em segundos. O ponto do display da centena pode ser usado para marcar a separao. No se esquea que agora os displays da direita devem contar somente de 0 a 59 e no mais de 0 a 99.
117
Objetivo
O objetivo desta experincia o aprendizado da utilizao de display de cristal lquido.
Descrio
Esta experincia foi elaborada para explicar o funcionamento do display LCD e o exemplo de software proposto bastante reduzido. Simplesmente utilizou-se o LCD para informar ao usurio qual tecla est pressionada. Para isso elaborou-se uma rotina chamada ESCREVE que envia a informao passada pelo Work ao display. Esta rotina pode ser utilizada tanto para enviar comandos quanto dados. Foi criada tambm, a rotina de inicializao do LCD. Esta rotina configura o sistema para comunicao com 8 vias, 2 linhas, sem cursor visvel e com movimento automtico do cursor para a direita. Alm disso, ela j limpa a tela e posiciona o cursor na primeira linha, primeiro caractere da esquerda. Para cada boto pressionado, posicionou-se o cursor em um local diferente da tela e escreveu-se o nmero do boto em questo. Aps a liberao, uma tela padro visualizada.
118
Esquema Eltrico
119
Fluxograma
INICIO
VETOR DE RESET PULA P/ INICIO DO PROGRAMA CONFIGURAES INICIAS PORTAS, TIMERS, INTERRUPES, OPTION, ADS.
No
DELAY DE 4ms INICIALIZAO COM 4 VIAS DE DADOS ENVIA COMANDO 0x30 P/ DISPLAY
120
LIMPA WDT
HABILITA LINHA 4
BOTO 0 PRESS.? No BOTO 1 PRESS.? No BOTO 2 PRESS.? No BOTO 3 PRESS.? No DESABILITA LINHA 4
RECARREGA FILTRO
No
121
TRATA BOTO 0
TRATA BOTO 1
Sim
Sim
No
No
FILTRO TERMINOU ?
No
FILTRO TERMINOU ?
No
122
TRATA BOTO 2
TRATA BOTO 3
Sim
Sim
No
No
FILTRO TERMINOU ?
No
FILTRO TERMINOU ?
No
123
ESCREVE
DELAY DE 1ms
RETURN ESCREVE Sistema Didatico DELAY_MS SELECIONA DISPLAY PARA COMANDOS CARREGA ARGUMENTO PASSADO PELO Work EM TEMPO1
INICIALIZA TEMPO0 COM 250d SELECIONA DISPLAY PARA DADOS NOP [1us] ESCREVE MCMASTER No [3us] LIMPA BARRAMENTO DE DADOS Sim No FIM DO TEMPO1 ? FIM DO TEMPO0 ? 1ms
RETURN
Sim RETURN
124
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 10 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //ESTE EXEMPLO FOI ELABORADO PARA EXPLICAR O FUNCIONAMENTO DO MDULO DE LCD. //FOI CRIADA UMA ROTINA PARA ESCREVER COMANDOS OU CARACTERES NO LCD. EXISTE //TAMBM UMA ROTINA DE INICIALIZAO NECESSRIA PARA A CORRETA CONFIGURAO //DO LCD. OS BOTES CONTINUAM SENDO MONITORADOS. UMA MENSAGEM ESCRITA //NO LCD PARA CADA UM DOS BOTES, QUANDO O MESMO PRESSIONADO. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1
125
FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char FILTRO11; //FILTRAGEM 1 PARA O BOTO 1 unsigned char FILTRO12; //FILTRAGEM 2 PARA O BOTO 1 unsigned char FILTRO21; //FILTRAGEM 1 PARA O BOTO 2 unsigned char FILTRO22; //FILTRAGEM 2 PARA O BOTO 2 unsigned char FILTRO31; //FILTRAGEM 1 PARA O BOTO 3 unsigned char FILTRO32; //FILTRAGEM 2 PARA O BOTO 3 unsigned char FILTRO41; //FILTRAGEM 1 PARA O BOTO 4 unsigned char FILTRO42; //FILTRAGEM 2 PARA O BOTO 4 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define T_FILTRO 25 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned }FLAGSbits; #define #define #define #define #define
BIT0:1; BIT1:1; BIT2:1; BIT3:1; BIT4:1; BIT5:1; BIT6:1; BIT7:1; //ARMAZENA OS FLAGS DE CONTROLE FLAGSbits.BIT0 FLAGSbits.BIT1 FLAGSbits.BIT2 FLAGSbits.BIT3 FLAGSbits.BIT4 //STATUS //STATUS //STATUS //STATUS //STATUS DO BOTO 1 DO BOTO 2 DO BOTO 3 DO BOTO 4 DOS BOTES LIBERADOS
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void void void void void comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); tela_principal(void); * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. //PORTA DO BOTO * * */ e
BT1 PORTBbits.RB0
126
//1 -> PRESSIONADO //0 -> LIBERADO #define BT2 PORTBbits.RB1 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e
#define
BT3 PORTBbits.RB2
#define
BT4 PORTBbits.RB3
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4
PORTBbits.RB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA // via do lcd que sinaliza recepo de // enable do lcd
PORTEbits.RE0 PORTEbits.RE1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 3 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
127
void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); 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
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { limpa_lcd(); comando_lcd(0x80); escreve_lcd ('S'); escreve_lcd ('i'); escreve_lcd ('s'); escreve_lcd ('t'); escreve_lcd ('e'); escreve_lcd ('m'); escreve_lcd ('a'); escreve_lcd (' '); escreve_lcd ('D'); escreve_lcd ('i'); escreve_lcd ('d'); escreve_lcd ('a'); escreve_lcd ('t'); escreve_lcd ('i'); escreve_lcd ('c'); escreve_lcd ('o'); comando_lcd(0xC4); escreve_lcd ('M'); escreve_lcd ('C'); escreve_lcd ('M'); escreve_lcd ('A'); escreve_lcd ('S'); escreve_lcd ('T'); escreve_lcd ('E'); escreve_lcd ('R'); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_tecla_1(void) { limpa_lcd(); comando_lcd(0x80); escreve_lcd ('T'); escreve_lcd ('E'); escreve_lcd ('C'); escreve_lcd ('L'); escreve_lcd ('A'); escreve_lcd (' '); escreve_lcd ('1'); }
128
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_tecla_2(void) { limpa_lcd(); comando_lcd(0x89); escreve_lcd ('T'); escreve_lcd ('E'); escreve_lcd ('C'); escreve_lcd ('L'); escreve_lcd ('A'); escreve_lcd (' '); escreve_lcd ('2'); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_tecla_3(void) { limpa_lcd(); comando_lcd(0xC0); escreve_lcd ('T'); escreve_lcd ('E'); escreve_lcd ('C'); escreve_lcd ('L'); escreve_lcd ('A'); escreve_lcd (' '); escreve_lcd ('3'); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 4 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_tecla_4(void) { limpa_lcd(); comando_lcd(0xC9); escreve_lcd ('T'); escreve_lcd ('E'); escreve_lcd ('C'); escreve_lcd ('L'); escreve_lcd ('A'); escreve_lcd (' '); escreve_lcd ('4'); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
//CONFIG DIREO DOS PINOS PORTA //CONFIG DIREO DOS PINOS PORTB
129
//CONFIG DIREO DOS PINOS PORTC //CONFIG DIREO DOS PINOS PORTD //CONFIG DIREO DOS PINOS PORTE //DESLIGA CONVERSORES A/D
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ RCON = 0x00; LINHA_4 = 1; inicializa_lcd(); tela_principal(); //ATIVA LINHA 4 DO TECLADO MATRICIAL // configura o lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { ClrWdt(); FILTRO11 = 0; FILTRO12 = T_FILTRO; FILTRO21 = 0; FILTRO22 = T_FILTRO; FILTRO31 = 0; FILTRO32 = T_FILTRO; FILTRO41 = 0; FILTRO42 = T_FILTRO; if(!ST_NO_BOTS) { tela_principal(); ST_NO_BOTS = 1; } while(BT1) { ClrWdt(); if (--FILTRO11 == 0) { FILTRO12--; if (FILTRO12 == 0) { if (!ST_BT1) { tela_tecla_1(); ST_BT1 = 1; ST_NO_BOTS = 0; } } } } ST_BT1 = 0; // BOTO LIBERADO, LIMPA O FLAG while(BT2) { ClrWdt(); if (--FILTRO21 == 0) { FILTRO22--; if (FILTRO22 == 0) { if (!ST_BT2) { tela_tecla_2(); //BT1 //BT1 //BT2 //BT2 //BT3 //BT3 //BT4 //BT4
130
while(BT3) { ClrWdt(); if (--FILTRO31 == 0) { FILTRO32--; if (FILTRO32 == 0) { if (!ST_BT3) { tela_tecla_3(); ST_BT3 = 1; ST_NO_BOTS = 0; } } } } ST_BT3 = 0; // BOTO LIBERADO, LIMPA O FLAG
while(BT4) { ClrWdt(); if (--FILTRO41 == 0) { FILTRO42--; if (FILTRO42 == 0) { if (!ST_BT4) { tela_tecla_4(); ST_BT4 = 1; ST_NO_BOTS = 0; } } } } ST_BT4 = 0; // BOTO LIBERADO, LIMPA O FLAG } }
131
Dicas e Comentrios
Apesar da estrutura do sistema ficar muito simples com a implementao da rotina ESCREVE, nunca se deve esquecer de confirmar o estado da sada RS (define comando ou dado) antes de utiliz-la. Notar que para enviar um caractere ao LCD deve-se utilizar o cdigo ASCII do caractere. Apesar do sistema McMaster possuir ligao com o mdulo de LCD atravs de 8 vias de dados possvel utiliz-lo para testar e implementar a comunicao com 4 vias. Basta modificar a rotina de inicializao e a de escrita de um byte.
Exerccios Propostos
1. Altere a comunicao para 4 vias. 2. Mantenha a tela principal disponvel somente quando o sistema ligado. Aps alguns segundos, mostre uma tela com o nome das quatro teclas e indique a tecla pressionada atravs de um caractere de seta () ou outro qualquer.
132
Objetivo
Nesta experincia ser estudado o mdulo de converso A/D interno do PIC18F4550
Descrio
Este exemplo foi elaborado para explicar o funcionamento do mdulo de converso analgico digital interno do PIC18F4550. convertido o valor analgico presente no pino RA0 do microcontrolador, sendo que este valor pode ser alterado atravs do potencimetro presente na placa do sistema McMaster. A converso feita diretamente no loop principal, sem a utilizao de nenhuma interrupo, nem para checar o trmino da converso nem para definir uma freqncia de amostragem. Desta forma, a converso ser feita uma aps a outra, na freqncia definida pelo perodo do loop principal. Uma vez terminada a converso, descarta-se os 2 bits menos significativos e considera-se somente o resultado armazenado em ADRESH. Com isso j se est executando uma espcie de filtragem, evitando assim que o valor final fique oscilando. Aplica-se ento uma regra de 3 para converter o valor do A/D para a unidade desejada: Volts. Considerando-se que quando o A/D resulta em 0 (zero) a entrada possui 0,0V, e quando o A/D resulta em 255 a entrada equivalente a 5,0V, aplica-se a regra de 3 mostrase o valor da tenso, j em Volts, no LCD. Para a execuo da regra de 3 foram utilizadas rotinas de multiplicao de 8x8 e diviso de 16x16 retiradas de Aplication Notes da prpria Microchip.
133
Esquema Eltrico
+5V
10K
4,7K
LM358
7 8 9 10 11 12 13 14
DB0 VDD VO DB1 VSS DB2 DB3 DB4 RS DB5 DB6 EN DB7 R/W LCD
2 3 1 4 6 5
10K
RS EN
+5V
RESET
10K MC1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 23 24
+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
RS +5V EN
MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 PIC18F4550
134
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION.
CONFIGURA REGISTRADOR ADCON1 RA0, RA1 e RA3 COMO ENTRADAS ANALGICAS RA2, RA4 E RA5 COMO I/Os DIGITAIS PORTE COMO I/O DIGITAL 8 BITS EM ADRESH E 2 BITS EM ADRESL Vref+ = VDD (+5V) Vref- = GND ( 0V)
CONFIGURA REGISTRADOR ADCON0 MDULO A/D LIGADO FREQNCIA - Fosc/8 MUX SELECIONADO P/ CANAL1 (RA1)
No
INICIALIZA DISPLAY
135
LIMPA WDT
No
FIM CONVERSO?
Sim FUNDO DE ESCALA = 5,0V ESTO SENDO CONSIDERADOS APENAS OS 8 BITS MAIS SIGNIFICATIVOS DA CONVERSO A/D (ADRESH)
AJUSTE DECIMAL
ENVIA , AO DISPLAY
136
AJUSTE DECIMAL
AUX = 0 ?
Sim
No INCREMENTA UNIDADE
No
DECREMENTA AUXILIAR
AUX = 0?
Sim
RETURN
137
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 11 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 RA0 do microcontrolador, sendo que este valor pode ser //alterado atravs do potencimetro P2 da placa McMaster. O valor da //converso A/D ajustado numa escala de 0 5V e mostrado no LCD. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1
138
USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void void void void void comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); tela_principal(void);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. unsigned unsigned unsigned unsigned unsigned int char char char char conversao = 0; conversao1 = 0; unidade; dezena; centena; // armazena o resultado da converso AD // armazena o resultado da converso AD
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e
139
PORTEbits.RE0 PORTEbits.RE1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 3 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { comando_lcd(0x83); // posiciona o cursor na linha 0, coluna 0
// 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
140
escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd }
('V'); ('o'); ('l'); ('t'); ('i'); ('m'); ('e'); ('t'); ('r'); ('o');
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Converte BCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void converte_bcd(unsigned char aux) { unidade = 0; dezena = 0; centena = 0; if (aux == 0)return; while(aux--) { unidade++; if(unidade != 10)continue; unidade = 0; dezena++; if (dezena != 10)continue; dezena = 0; centena++; if (centena != 10)continue; centena = 0; } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
TRISA=(0b11101111); TRISB=(0b11111111); TRISC=(0b11111111); TRISD=(0b00000000); TRISE=(0b00000100); //CONFIGURAO DO AD ADCON0 = 0x01; ADCON1 = 0x0E; inicializa_lcd(); tela_principal();
141
{ ClrWdt(); ConvertADC(); //Inicia converso AD while (BusyADC()); //Aguarda Fim da converso AD conversao = ADRESH; //l resultado da converso AD conversao = (conversao * 50); //faz regra de 3 para converter o valor, conversao = (conversao / 255); //das unidades de AD em Volts. conversao1 = conversao; converte_bcd(conversao1); comando_lcd(0xC5); //posiciona o cursor na linha 1, coluna 2 escreve_lcd (dezena + 0x30); //escreve no display de LCD escreve_lcd (','); escreve_lcd (unidade + 0x30); //escreve no display de LCD escreve_lcd ('V'); } } // FIM DO PROGRAMA
142
Dicas e Comentrios
Inicialmente notar que toda a estrutura e rotinas utilizadas para a escrita no LCD so as mesmas j aplicadas na experincia anterior. Observar tambm que no foi utilizada nenhuma interrupo neste programa. Por isso, o programa permanece parado em um pequeno loop enquanto a converso no termina. Isto checado atravs do bit ADCON0<GO/DONE>. Outra rotina bem interessante que aparece neste sistema a de converso de um nmero qualquer (limitado entre 0 e 99) em dois dgitos separados, facilitando assim a escrita no LCD. Esta rotina devolve os dgitos nas variveis UNIDADE e DEZENA. No esquecer que antes de transmitir um valor decimal ao LCD, deve-se converte-lo em um caractere ASCII. Para facilitar as contas e no utilizarmos nmeros fracionrios, a converso para Volts feita considerando-se 50 no lugar de 5,0 de forma que ao enviar o valor final ao LCD simplesmente colocada uma vrgula entre os dois dgitos.
Exerccios Propostos
1. Simule que a entrada analgica um sensor de temperatura linear que deve marcar de 10 a 80C; 2. Altere o exemplo para indicar a tenso entre 0 e 2,50V, utilizando 10 bits de resoluo. Para isso, faa uso da tenso de referncia externa existente na placa de perifricos (pino RA3).
143
Objetivo
Nesta experincia ser vista uma forma de converso A/D fundamentada no tempo de carga de um capacitor. A vantagem desta tcnica que o microcontrolador no necessita possuir um conversor A/D interno para estimar o valor de uma varivel analgica.
Descrio
A tcnica descrita nesta experincia baseia-se na carga e descarga de um capacitor. A idia consiste em medir, atravs do microcontrolador, o tempo de carga de um capacitor num circuito RC. Veja o exemplo de hardware colocado a seguir:
Vin RA RB
PIC
Admitindo-se que o pino do PIC est configurado como entrada, o tempo de carga do capacitor C est relacionado com o valor de entrada (Vin), do resistor RA e do prprio capacitor C. O resistor RB no interfere no tempo de carga, pois o pino do PIC est em alta impedncia (entrada). J se o pino do PIC estiver configurado como sada em nvel lgico 0 o capacitor tende a se descarregar pelo resistor RB e carregar pelo resistor RA. Porm, vamos admitir que o valor do resistor RB seja muito menor do que o de RA e, portanto, nesta configurao, podemos desprezar a carga proveniente do resistor RA e admitir que o capacitor C apenas se descarrega atravs de RB. Em resumo, o capacitor se carrega atravs de RA (pino como entrada) e se descarrega atravs de RB (pino como sada em 0) sendo que o tempo de carga/descarga depende do prprio valor do capacitor, da tenso de entrada (Vin) e do resistor em questo. Como funciona ento a converso A/D? 1. O software deve configurar o pino do PIC como sada em 0; 2. Esperar o tempo de descarrega do capacitor C. Este tempo deve ser garantido por software conforme os valores dos componentes utilizados; 3. Configurar o pino como entrada, ou seja, permitir a carga do capacitor; 4. Contar o tempo que o capacitor leva para que o PIC entenda nvel lgico 1, ou seja, contar o tempo de carga do capacitor; 5. Repetir o processo para uma nova converso.
144
O tempo de carga do capacitor ser inversamente proporcional tenso de entrada. Admitindo-se que a tenso de entrada no varie durante a converso A/D, o modelo matemtico aproximado para a curva de carga do capacitor
t Vcap (t ) = Vin 1 e R A C . Assim, conhecidos os valores do resistor, do capacitor e do tempo de carga, pode-se estimar a tenso de entrada. O exemplo de software da experincia calcula o tempo de carga do capacitor e mostra este tempo no display LCD. O software no calcula a tenso de entrada, apenas o tempo de carga do capacitor. O tempo de carga pode ser alterado atravs do potencimetro do McMaster.
145
Esquema Eltrico
+5V
10K
4,7K
LM358
7 8 9 10 11 12 13 14
DB0 VDD VO DB1 VSS DB2 DB3 DB4 RS DB5 DB6 EN DB7 R/W LCD
2 3 1 4 6 5
10K
RS EN
+5V
RESET
10K MC1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 23 24
+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
RS +5V EN
MCLR RA0 RA1 RA2 RA3 RA4 RA5 RE0 RE1 RE2 VDD VSS OSC1 OSC2 RC0 RC1 RC2 RC3 RC4 RC5 PIC18F4550
146
Fluxograma
INICIO
No
INICIALIZA DISPLAY
147
ZERA CONTADOR AD
DELAY DE 3ms
DELAY DE 44us
INCREMENTA CONTADOR_AD
Sim
[3us]
No
SATURA CONTADOR_AD
No [3us]
CAPACITOR CARREGOU?
148
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 12 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ESTE EXEMPLO FOI ELABORADO PARA EXPLICAR O FUNCIONAMENTO DE UM TIPO DE CONVERSOR A/D FUNDAMENTADO NO TEMPO DE CARGA DE UM CAPACITOR. O TEMPO DE CARGA DO CAPACITOR MOSTRADO NO LCD E INVERSAMENTE PROPORCIONAL TENSO APLICADA ATRVS DO POTENCIMETRO P2. UTILIZE OS JUMPERS (RA5) E DIVISOR (RESISTOR/ CAPACITOR) */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0
149
#pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma
config config config config config config config config config config config config
PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char contador_ad; unsigned char aux; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * void void void void void void * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); escreve_frase(const rom char *frase); tela_principal(void); * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programao e do hardware. TRISAbits.TRISA5 //PINO P/ LEITURA DO RC //0 -> FORA A DESCARGA DO CAPACITOR //1 -> LIBERA A CARGA DO CAPACITOR //PINO P/ LEITURA DO CONV. A/D //0 -> CAPACITOR DESCARREGADO //1 -> CAPACITOR CARREGADO
#define
CAD
PORTAbits.RA5
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define rs comando #define enable PORTEbits.RE0 PORTEbits.RE1
150
void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { Delay1KTCYx(15); comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para escrever uma frase no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_frase(const rom char *frase) { do { escreve_lcd(*frase); }while(*++frase); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal *
// espera 15 milisengundos // 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
151
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { comando_lcd(0x80); // posiciona o cursor na linha 0, coluna 0 escreve_frase("A/D por RC (RA5)"); comando_lcd(0xC0); // posiciona o cursor na linha 1, coluna 0 escreve_frase("T.CARGA: x50us"); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { PORTA = PORTB = PORTC = PORTD = PORTE = LATA LATB LATC LATD LATE = = = = =
//Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa
PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ inicializa_lcd(); tela_principal(); // configura o lcd // imprime a tela principal no LCD
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { ClrWdt(); //LIMPA O WDT contador_ad = 0; PINO_AD = 0; CAD = 0; Delay1KTCYx(3); CAPACITOR PINO_AD = 1; //REINICIA CONTADOR AD //CONFIGURA PINO DO AD COMO SADA //FORA PINO NO AD EM 0 PARA DECARGA DO CAPACITOR //DELAY DE 3ms PARA GARANTIR A DESCARGA DO //CONFIGURA PINO DO AD COMO ENTRADA
while(1) { Delay10TCYx(5); //DELAY DE 50us contador_ad++; //INCREMENTA CONTADOR DO AD if(!contador_ad) //CONTADOR = 0? { contador_ad = 255; //CONTADOR = 255 (SATURA AD) break; //SAI DO LAO } if(CAD) break; //SE PINO CAD = 1, SAI DO LAO } comando_lcd(0xC9); //POSICIONA CURSOS NA LINHA 1, COLUNA 9
152
aux = contador_ad >> 4; //CONVERTE CONTADOR EM HEXADECIMAL if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); aux = contador_ad & 0b00001111; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); } }
153
Dicas e Comentrios
Este tipo de conversor A/D no apresenta uma boa preciso, alm de apresentar uma srie de inconvenientes: Note que a tenso sobre o capacitor no varia linearmente no tempo e, portanto, este tipo de conversor A/D no linear; O valor da converso, ou seja, o tempo de carga do capacitor est sujeito s variaes dos componentes envolvidos. Normalmente o capacitor muito suscetvel a variaes trmicas; A tenso de entrada deve ser suficientemente alta para que o PIC entenda nvel lgico 1, por isso este conversor no funciona no range completo de 0 a 5V; O valor de tenso necessrio para que o PIC entenda nvel lgico 1 pode variar em funo da pastilha, da tenso da fonte (alimentao do PIC) e do tipo de pino (TTL/ST).
Como dica, podemos sugerir: Utilizar RB pelo menos 10 vezes menor que RA; No utilizar capacitores maiores do que 1F; Dar preferncia ao uso de capacitores de tntalo ou cermico; No discretizar mais do que oito nveis.
Exerccios Propostos
1. Admitindo que a tenso de entrada varia entre 0 e 5V, estimar atravs do tempo de carga do capacitor se a tenso de entrada encontra-se abaixo de 1,25V, entre 1,25V e 2,5V, entre 2,5V e 3,75V ou acima de 3,75V.
154
Objetivo
O objetivo desta experincia aplicar a tcnica apresentada na aula anterior para viabilizar a leitura de jumpers atravs de um nico pino do microcontrolador.
Descrio
Assim como na experincia anterior, este exemplo foi elaborado utilizando a tcnica de converso A/D atravs de um circuito RC. Diferente do caso anterior, a tenso de entrada nesta experincia fixa e o que varia o valor do resistor que fornece a carga do capacitor. Utilizando os jumpers A, B e C do McMaster pode-se alterar o valor do resistor de carga e conseqentemente o tempo de carga do capacitor. Como so 3 jumpers, existem at 8 combinaes possveis que alteram o tempo de carga do capacitor. O quarto jumper deve estar selecionado na posio resistor/capacitor para que o exemplo possa ser utilizado. O software calcula o tempo de carga do capacitor e mostra o valor no display LCD. O interessante desta tcnica que ao invs de utilizar 3 pinos do microcontrolador, um para cada jumper, ela utiliza apenas um.
155
Esquema Eltrico
JP2
JP3 +5V
JP4
7 8 9 10 11 12 13 14 VDD DB0 VO DB1 VSS DB2 DB3 DB4 RS DB5 DB6 EN DB7 R/W 2 3 1 4 6 5
10K
Divisor Capacitivo
Divisor Resistivo
100nF
10K
RS EN
LCD
+5V
RESET
10K MC1
1 2 3 4 5 6 7 MCLR RA0 RA1 RA2 RA3 RA4 VDD 32 VSS 31 40 RB7 RB6 39 38 RB5 RB4 37 RB3 36 RB2 35 RB1 34 33 RB0 30 RD7 RD6 29 RD5 28 RD4 27 RD3 22 21 RD2 20 RD1 RD0 19 RC7 26 RC6 25
+5V
RS +5V EN
RA5 8 RE0 9 RE1 10 RE2 11 VDD 12 VSS 13 OSC1 14 OSC2 15 RC0 16 RC1 17 RC2 18 RC3 23 RC4 24 RC5
PIC18F4550
156
Fluxograma
INICIO
No
INICIALIZA DISPLAY
157
ZERA CONTADOR AD
DELAY DE 3ms
INCREMENTA CONTADOR_AD
Sim
[3us]
No
SATURA CONTADOR_AD
No [3us]
CAPACITOR CARREGOU?
158
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 13 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ESTE EXEMPLO FOI ELABORADO PARA EXPLICAR O FUNCIONAMENTO DE UM TIPO DE CONVERSOR A/D FUNDAMENTADO NO TEMPO DE CARGA DE UM CAPACITOR. O TEMPO DE CARGA PODE SER ALTERADO UTILIZANDO OS JUMPERS LIGADOS AO PINO RA5. COM SO TRS JUMPERS EXISTEM 8 COMBINAES POSSVEIS QUE ALTERAM O TEMPO DE CARGA DO CAPACITOR. O QUARTO JUMPER DEVE ESTAR SELECIONADO NA POSIO RESISTOR/CAPACITOR PARA QUE O EXEMPLO POSSA SER UTILIZADO. */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
159
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char contador_ad; unsigned char aux; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * void void void void void void * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); escreve_frase(const rom char *frase); tela_principal(void); * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ser associadas a nomes para facilitar a programao e do hardware. TRISAbits.TRISA5 //PINO P/ LEITURA DO RC //0 -> FORA A DESCARGA DO CAPACITOR //1 -> LIBERA A CARGA DO CAPACITOR //PINO P/ LEITURA DO CONV. A/D //0 -> CAPACITOR DESCARREGADO //1 -> CAPACITOR CARREGADO
#define
CAD
PORTAbits.RA5
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define rs comando #define enable PORTEbits.RE0 PORTEbits.RE1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
160
void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { Delay1KTCYx(15); comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para escrever uma frase no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_frase(const rom char *frase) { do { escreve_lcd(*frase); }while(*++frase); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { comando_lcd(0x81); // posiciona o cursor na linha 0, coluna 1 escreve_frase("JUMPER (RA5)"); comando_lcd(0xC0); // posiciona o cursor na linha 1, coluna 0 escreve_frase("T.CARGA: x50us"); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// espera 15 milisengundos // 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
161
void main() { PORTA = PORTB = PORTC = PORTD = PORTE = LATA LATB LATC LATD LATE = = = = =
//Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa
PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ inicializa_lcd(); tela_principal(); // configura o lcd // imprime a tela principal no LCD
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { ClrWdt(); //LIMPA O WDT contador_ad = 0; PINO_AD = 0; CAD = 0; Delay1KTCYx(3); CAPACITOR PINO_AD = 1; //REINICIA CONTADOR AD //CONFIGURA PINO DO AD COMO SADA //FORA PINO NO AD EM 0 PARA DECARGA DO CAPACITOR //DELAY DE 3ms PARA GARANTIR A DESCARGA DO //CONFIGURA PINO DO AD COMO ENTRADA
while(1) { Delay10TCYx(5); //DELAY DE 50us contador_ad++; //INCREMENTA CONTADOR DO AD if(!contador_ad) //CONTADOR = 0? { contador_ad = 255; //CONTADOR = 255 (SATURA AD) break; //SAI DO LAO } if(CAD) break; //SE PINO CAD = 1, SAI DO LAO } comando_lcd(0xC9); //POSICIONA CURSOS NA LINHA 1, COLUNA 9 aux = contador_ad >> 4; //CONVERTE CONTADOR EM HEXADECIMAL if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); aux = contador_ad & 0b00001111; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); } }
162
Dicas e Comentrios
As dicas e comentrios desta experincia so os mesmos da experincia anterior.
Exerccios Propostos
1. Atravs do conhecimento do tempo de carga do capacitor, estime a real posio dos jumpers A, B e C do sistema.
163
Objetivo
O objetivo desta experincia ensinar ao aluno como utilizar o mdulo PWM do microcontrolador PIC18F4550
Descrio
Este PIC possui 2 canais de PWMs (CCP1 e CCP2), cada um com resoluo mxima de 10 bits. Isto significa que o duty cycle poder ser regulado de 0 a 100% com uma resoluo mxima de 1024 pontos. No entanto, dependendo da configurao adotada, esta resoluo no ser atingida. O perodo do PWM controlado diretamente pelo TMR2, atravs do registrador PR2. Como j foi visto, sempre que TMR2 = PR2, o timer zerado e neste momento, um novo perodo do PWM iniciado. Desta forma, pode-se definir o perodo e a freqncia do PWM pelas seguintes frmulas: T = [(PR2) + 1] x 4 x Tosc x (Prescale do TMR2) PWMFreq = 1 / T O duty cycle normalmente definido em porcentagem, porm, o PIC no define o valor do duty cycle e sim o tempo do pulso em nvel alto. Desta forma, o tempo do pulso pode ser calculado por: tp = CCPRxL:CCPxCON<CCPxX:CCPxY> x Tosc x (Prescale do TMR2) Repare que a largura do pulso ajustada em dois registradores: CCPRxL que armazena os 8 bits mais significativos e CCPxCON que armazena os dois bits menos significativos. Assim, obtm-se os 10 bits que controlam o duty cycle do PWM. Apesar do PIC no definir o duty cycle, ele pode ser calculado dividindo o tempo do pulso em nvel alto pelo perodo total do PWM.
tp = T tp = T [(PR2) + 1] X 4 [(PR2) + 1] x 4 x TOSC x (Prescale do TMR2) CCPRxL:CCPxCON<DCxB1:DCxB0> CCPRxL:CCPxCON<DCxB1:DCxB0> x TOSC x (Prescale do TMR2)
Verifica-se ento que apesar do perodo e o do tempo de pulso dependerem do cristal (Tosc) e do ajuste do prescale do TMR2, o duty cycle depende nica e exclusivamente dos valores ajustados nos registradores PR2, CCPRxL e CCPxCON (bits 5 e 4). Veja que o registrador PR2 (8 bits) que controla o perodo do PWM multiplicado por 4 para poder igualar-se aos 10 bits que controlam o duty cycle. justamente este o problema da resoluo mxima atingida. Se o registrador PR2 for ajustado com um valor menor que 8 bits,
164
ou seja, menor do que 255, sero necessrios menos do que 10 bits para atingir um PWM com 100% de duty cycle. Portanto, o nmero de pontos para ajuste do duty cycle 4 vezes maior do que o valor ajustado em (PR2+1). Em termos de bits, podemos dizer que a resoluo do duty cycle 2 bits maior do que o nmero de bits que formam o valor ajustado em PR2. Repare tambm que caso PR2 seja ajustado com 255 nunca ser atingido um duty cycle de 100%, pois o perodo atingir o valor mximo de 1024 ([PR2+1]x4) enquanto o tempo do pulso em nvel alto (<DCxB9:DCxB0>) ser no mximo 1023. No software da experincia ativou-se a sada do mdulo CCP2 para controlar a rotao do ventilador que est ligado ao pino RC1. O registrador PR2 foi ajustado com valor mximo, ou seja, 255 e o prescale do timer foi configurado para 1:16. Com isso a freqncia do PWM ficou em 244,14Hz (PWMPerodo = 4,096ms), considerando-se que o microcontrolador do sistema McMaster est trabalhando a 4MHz. As teclas da linha 4 foram habilitadas e receberam as seguintes funes: Coluna 1 2 3 4 Duty Cycle 0% 50% 75% 100%
A fim de deixar o sistema mais interativo, utilizou-se o LCD para mostrar o valor atual ajustado para o PWM.
165
Esquema Eltrico
166
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
CONFIGURA REGISTRADOR PR2 (PERIODO DO PWM) T=((PR2)+1)*4*Tosc*TMR2 Prescale T=((255)+1)*4*250ns*16 T=4,096ms -> 244,14Hz
CONFIGURA REGISTRADOR T2CON TIMER 2 LIGADO PRESCALER -> 1:16 POSTSCALE -> 1:1
No
INICIALIZA DISPLAY
167
LIMPA WDT
BOTO 0 PRESS.? No BOTO 1 PRESS.? No BOTO 2 PRESS.? No BOTO 3 PRESS.? No RECARREGA FILTRO
168
TRATA BOTO 0
TRATA BOTO 1
Sim
Sim
No
No
CCPR2L = 0x00 LIMPA BITS 4 E 5 DE CCP2CON tp = CCPR2L:CCPR2CON<5,4>* *Tosc*TMR2 Prescale tp = 0*250ns*16 tp = 0ms PWM -> Duty Cycle = 0% -> OFF
CCPR2L = 0x80 LIMPA BITS 4 E 5 DE CCP2CON tp = CCPR2L:CCPR2CON<5,4>* *Tosc*TMR2 Prescale tp = 512*250ns*16 tp = 2,048ms PWM -> Duty Cycle = 50%
TRATA BOTO 2
TRATA BOTO 3
Sim
Sim
No
No
CCPR2L = 0XC0 LIMPA BITS 4 E 5 DE CCP2CON tp = CCPR2L:CCPR2CON<5,4>* *Tosc*TMR2 Prescale tp = 768*250ns*16 tp = 3,072ms PWM -> Duty Cycle = 75%
CCPR2L = 0xFF SETA BITS 4 E 5 DE CCP2CON tp = CCPR2L:CCPR2CON<5,4>* *Tosc*TMR2 Prescale tp = 1023*250ns*16 tp = 4,092ms PWM -> Duty Cycle = 99,90%
169
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 14 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //ESTE EXEMPLO FOI ELABORADO PARA EXPLICAR O FUNCIONAMENTO DO MDULO PWM //DO PIC18F4550. ELE MONITORA OS QUATRO BOTES E CONFORME O BOTO SELECIONADO //APLICA UM VALOR DIFERENTE NO PWM, FAZENDO ASSIM UM CONTROLE SOBRE A //VELOCIDADE DO VENTILADOR. NO LCD MOSTRADO O VALOR ATUAL DO DUTY CYCLE. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF
170
= = = = = = =
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char FILTRO11; //FILTRAGEM 1 PARA O BOTO 1 unsigned char FILTRO12; //FILTRAGEM 2 PARA O BOTO 1 unsigned char FILTRO21; //FILTRAGEM 1 PARA O BOTO 2 unsigned char FILTRO22; //FILTRAGEM 2 PARA O BOTO 2 unsigned char FILTRO31; //FILTRAGEM 1 PARA O BOTO 3 unsigned char FILTRO32; //FILTRAGEM 2 PARA O BOTO 3 unsigned char FILTRO41; //FILTRAGEM 1 PARA O BOTO 4 unsigned char FILTRO42; //FILTRAGEM 2 PARA O BOTO 4 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define T_FILTRO 25 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT7:1; unsigned BIT6:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE #define #define #define #define ST_BT1 ST_BT2 ST_BT3 ST_BT4 FLAGSbits.BIT0 FLAGSbits.BIT1 FLAGSbits.BIT2 FLAGSbits.BIT3 //STATUS //STATUS //STATUS //STATUS DO DO DO DO BOTO BOTO BOTO BOTO 1 2 3 4
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * void void void void void * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); tela_principal(void);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //As entradas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define BT1 PORTBbits.RB0 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO
#define
BT2
PORTBbits.RB1
171
//1 -> PRESSIONADO //0 -> LIBERADO #define BT3 PORTBbits.RB2 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e
#define
BT4
PORTBbits.RB3
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4
PORTBbits.RB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
#define rs PORTEbits.RE0 // via do lcd que sinaliza recepo de dados ou comando #define enable PORTEbits.RE1 // enable do lcd /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 3 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
172
// 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
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { limpa_lcd(); comando_lcd(0x83); escreve_lcd ('M'); escreve_lcd ('C'); escreve_lcd ('M'); escreve_lcd ('A'); escreve_lcd ('S'); escreve_lcd ('T'); escreve_lcd ('E'); escreve_lcd ('R'); comando_lcd(0xC4); escreve_lcd ('P'); escreve_lcd ('W'); escreve_lcd ('M'); escreve_lcd (':'); escreve_lcd (' '); escreve_lcd ('O'); escreve_lcd ('F'); escreve_lcd ('F'); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 1 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_tecla_1(void) { comando_lcd(0xC9); escreve_lcd ('O'); escreve_lcd ('F'); escreve_lcd ('F'); escreve_lcd (' '); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_tecla_2(void) { comando_lcd(0xC9); escreve_lcd ('5'); escreve_lcd ('0'); escreve_lcd ('%'); escreve_lcd (' '); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 3 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
173
void tela_tecla_3(void) { comando_lcd(0xC9); escreve_lcd ('7'); escreve_lcd ('5'); escreve_lcd ('%'); escreve_lcd (' '); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Tecla 4 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_tecla_4(void) { comando_lcd(0xC9); escreve_lcd ('1'); escreve_lcd ('0'); escreve_lcd ('0'); escreve_lcd ('%'); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA0 PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011001; 0b00000000; 0b00000000;
= = = = =
ADCON1 = 0b00001111;
SetDCPWM2(0); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ RCON = 0X7F; LINHA_4 = 1; inicializa_lcd(); tela_principal(); //ATIVA LINHA 4 DO TECLADO MATRICIAL // configura o lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
174
while(1) { ClrWdt(); FILTRO11 = 0; FILTRO12 = T_FILTRO; FILTRO21 = 0; FILTRO22 = T_FILTRO; FILTRO31 = 0; FILTRO32 = T_FILTRO; FILTRO41 = 0; FILTRO42 = T_FILTRO; //BT1 //BT1 //BT2 //BT2 //BT3 //BT3 //BT4 //BT4
while(BT1) { ClrWdt(); if (--FILTRO11 == 0) { FILTRO12--; if (FILTRO12 == 0) { if (!ST_BT1) { tela_tecla_1(); SetDCPWM2(0); ST_BT1 = 1; } } } } ST_BT1 = 0; // BOTO LIBERADO, LIMPA O FLAG while(BT2) { ClrWdt(); if (--FILTRO21 == 0) { FILTRO22--; if (FILTRO22 == 0) { if (!ST_BT2) { tela_tecla_2(); SetDCPWM2(512); ST_BT2 = 1; } } } } ST_BT2 = 0; // BOTO LIBERADO, LIMPA O FLAG
175
while(BT4) { ClrWdt(); if (--FILTRO41 == 0) { FILTRO42--; if (FILTRO42 == 0) { if (!ST_BT4) { tela_tecla_4(); SetDCPWM2(1023); ST_BT4 = 1; } } } } ST_BT4 = 0; // BOTO LIBERADO, LIMPA O FLAG }// FIM LAO PRINCIPAL }
176
Dicas e Comentrios
Para calcular o valor que deve ser carregado nos registradores que controlam o tempo do pulso em nvel alto (duty cycle) a partir de um determinado valor de duty cycle expresso em porcentagem pode-se utilizar a formula a seguir:
CCPRx = [(PR2)+1] x 4 x Porcentagem desejada
Vejamos como exemplo o valor de 50% adotado nesta experincia. A porcentagem desejada de 50% e o valor de PR2 255, assim, CCPRx = 256 * 4 * 0,5 CCPRx = 512 Ou seja, se carregarmos os registradores que controlam o tempo do pulso em nvel alto com 512, obteremos um duty cycle de 50%
Exerccios Propostos
1. Corrija o problema encontrado no nvel 100%, evitando que a sada seja colocada em zero, mesmo que por um perodo de tempo muito curto. 2. Em vez de trabalhar com somente 4 nveis de PWM, altere o sistema para que um boto ligue e desligue a sada e outros dois botes incremente e decremente o PWM, de 50 a 100% com passos de 5%. 3. Ative as duas sadas PWMs ao mesmo tempo, uma para o ventilador e outra para a resistncia. Utilize dois botes para controlar o ajuste de cada uma delas.
177
Objetivo
O acesso memria de dados EEPROM j foi visto na experincia 6, portanto, a novidade desta experincia o acesso memria de programa do microcontrolador.
Descrio
Nesta experincia o LCD est dividido em duas partes. Do lado esquerdo temos um valor relativo memria de dados, varivel de 0 a FFh (8-bits), com incremento e decremento rotativo atravs dos botes das colunas 2 e 3. Do lado direito o valor ser para a memria de programa, tambm com incremento e decremento rotativo atravs dos botes das colunas 2 e 3, podendo ir de 0 a 3FFFh (14-bits). Para alterar o controle dos botes entre o lado esquerdo e o lado direito deve ser usado o boto da coluna 1., sendo que o lado ativo no momento indicado entre os sinais > e <. Depois de ajustados os valores desejados, basta pressionar o boto da coluna 4 para que ambos valores sejam gravados, cada um na memria correspondente. Para checar a gravao, altere os valores e reset o sistema (boto de reset). Os valores gravados sero recuperados na inicializao e mostrados no LCD.
178
Esquema Eltrico
179
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
No
INICIALIZA DISPLAY
180
LIMPA WDT
TRATA BOTO 0
ATUALIZA LCD
181
TRATA BOTO 1
TRATA BOTO 2
No
No
ATUALIZA LCD
ATUALIZA LCD
ATUALIZA LCD
ATUALIZA LCD
1 TRATA BOTO 3
CARREGA ENDEREO ONDE O DADO SER SALVO NA MEM. DE PROGRAMA (HIGH E LOW)
182
EECON2=0x55 EECON2=0xAA
RETURN
NOP NOP
INCREMENTA ENDEREO
No
183
EECON2=0x55 EECON2=0xAA
RETURN
No
ACABOU ESCRITA?
RETURN
184
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 15 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * /* ESTE EXEMPLO FOI TANTO NA MEMRIA OS BOTES PARA A COLUNA1 COLUNA2 COLUNA3 COLUNA4 -> -> -> -> * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ELABORADO PARA EXPLICAR O FUNCIONAMENTO DA LEITURA/ESCRITA DE DADOS QUANTO NA MEMRIA DE PROGRAMA. UTILIZAO DO EXEMPLO ESTO NA LINHA 4 COMO SEGUE:
ALTERNA O TIPO DE MEMRIA INCREMENTA O VALOR QUE SER SALVO NA MEMRIA DECREMENTA O VALOR QUE SER SALVO NA MEMRIA SALVA O VALOR INDICADO NA MEMRIA SELECIONADA
REINICIE O EQUIPAMENTO E OBSERVANDO O RESULTADO NO LCD. */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128
185
#pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma
config config config config config config config config config config config config config config config config
LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char char mem[8]; unsigned unsigned unsigned unsigned char char short char tempo_turbo = 30; cont_mem_dados; cont_mem_prog; x; FILTRO; //FILTRO BOTO
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE #define TIPO_MEM FLAGSbits.BIT0
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter); void escreve_lcd(unsigned char caracter); void limpa_lcd(void); void inicializa_lcd(void); void escreve_frase(const rom char *frase); void atualiza_linha_1(void); void atualiza_linha_2(void); void write_EEPROM(unsigned char endereco, unsigned char dado); unsigned char read_EEPROM(unsigned char endereco); void write_FLASH(unsigned addr, char *buffer);
186
unsigned short read_FLASH(unsigned endereco); /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. //BOTO 1 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 2 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 3 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 4 //0 -> PRESSIONADO //1 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e * * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4
PORTBbits.RB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
PORTEbits.RE0 PORTEbits.RE1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
187
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para escrever uma frase no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_frase(const rom char *frase) { do { escreve_lcd(*frase); }while(*++frase); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * FUNO PARA ATUALIZAR A LINHA 1 DO LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void atualiza_linha_1(void) { limpa_lcd(); comando_lcd(0x80); escreve_frase("M.DADOS } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * FUNO PARA ATUALIZAR A LINHA 2 DO LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void atualiza_linha_2(void) { union { struct { unsigned short low:8; unsigned short high:8; } ; struct { unsigned short all; } ; }dado;
// 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
// limpa lcd // posiciona o cursor na linha 0, coluna 0 // imprime mensagem no lcd M.PROG.");
188
unsigned char aux; comando_lcd(0xC1); if (TIPO_MEM) escreve_lcd('>'); else escreve_lcd(' '); aux = cont_mem_dados >> 4; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); aux = cont_mem_dados & 0b00001111; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); if (TIPO_MEM) escreve_lcd('<'); else escreve_lcd(' '); dado.all = cont_mem_prog; escreve_lcd(' '); escreve_lcd(' '); escreve_lcd(' '); if (!TIPO_MEM) escreve_lcd('>'); else escreve_lcd(' '); aux = dado.high >> 4; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); aux = dado.high & 0b00001111; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); aux = dado.low >> 4; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); aux = dado.low & 0b00001111; if(aux < 10) aux = aux + 0x30; else aux = aux + 0x37; escreve_lcd(aux); if (!TIPO_MEM) escreve_lcd('<'); else escreve_lcd(' '); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de escrita da EEPROM interna * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void write_EEPROM(unsigned char endereco, unsigned char dado) { EEDATA = dado; //carrega dado EEADR = endereco; //carrega endereo EECON1bits.CFGS = 0; EECON1bits.EEPGD = 0; EECON1bits.WREN = 1; INTCONbits.GIE = 0; EECON2 = 0x55; EECON2 = 0xAA; EECON1bits.WR = 1; INTCONbits.GIE = 1; while(EECON1bits.WR); EECON1bits.WREN = 0; //habilita acesso a EEPROM //aponta para memria de dados //habilita escrita //desabilita todas as interrupes //escreve 0x55 em EECON2 (obrigatrio) //escreve 0xAA em EECON2 (obrigatrio) //inicia a escrita //habilita todas as interrupes //aguarda bit WR de EECON1 = 0 //desabilita escrita //SE TIPO DE MEMRIA = 0, IMPRIME '<' //SE TIPO DE MEMRIA = 1, IMPRIME ' ' //SE TIPO DE MEMRIA = 0, IMPRIME '>' //SE TIPO DE MEMRIA = 1, IMPRIME ' ' //CONVERTE cont_mem_prog EM HEXADECIMAL //SE TIPO DE MEMRIA = 1, IMPRIME '<' //SE TIPO DE MEMRIA = 0, IMPRIME ' ' //POSICIONA CURSOR NA LINHA 1, COLUNA 1 //SE TIPO DE MEMRIA = 1, IMPRIME '>' //SE TIPO DE MEMRIA = 0, IMPRIME ' ' //CONVERTE cont_mem_dados EM HEXADECIMAL
189
} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de leitura da EEPROM interna * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ unsigned char read_EEPROM(unsigned char endereco) { EEADR = endereco; //carrega endereo EECON1bits.CFGS = 0; EECON1bits.EEPGD = 0; EECON1bits.RD = 1; return(EEDATA); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de escrita da FLASH interna * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // OBS: ESTA FUNO, O ENDEREO DEVE TER FINAL 0 OU 8 // EX.: 0x500, 0x508, 0x60, 0x68 ... void write_FLASH(unsigned addr, char *buffer) { unsigned char i; TBLPTR = addr; EECON1bits.EEPGD = 1; EECON1bits.CFGS = 0; EECON1bits.WREN = 1; EECON1bits.FREE = 1; TBLPTR INTCONbits.GIE = 0; EECON2 = 0x55; EECON2 = 0xAA; EECON1bits.WR = 1; INTCONbits.GIE = 1; while(EECON1bits.WR); EECON1bits.WREN = 0; for(i = 0;i < 8;i++) { TABLAT = buffer[i]; _asm TBLWTPOSTINC TBLPTR _endasm if(((i + 1) % 8) == 0) escrita { TBLPTR -= 8; EECON1bits.EEPGD = 1; EECON1bits.CFGS = 0; EECON1bits.WREN = 1; EECON1bits.FREE = 0; INTCONbits.GIE = 0; EECON2 = 0x55; EECON2 = 0xAA; EECON1bits.WR = 1; INTCONbits.GIE = 1; while(EECON1bits.WR); EECON1bits.WREN = 0; TBLPTR += 8; } } //retorna 8 posies em TBLPTR //aponta para memria FLASH //habilita acesso a FLASH //habilita escrita //somente escrita da FLASH //desabilita todas as interrupes //escreve 0x55 em EECON2 (obrigatrio) //escreve 0xAA em EECON2 (obrigatrio) //inicializa escrita da FLASH //habilita todas as interrupes //desabilita escrita //retorna posio original em TBLPTR //identifica os grupos de 8 bytes e habilita a //carrega endereo //aponta para memria FLASH //habilita acesso a FLASH //habilita escrita //apaga FLASH a partir do endereo apontado no //desabilita todas as interrupes //escreve 0x55 em EECON2 (obrigatrio) //escreve 0xAA em EECON2 (obrigatrio) //inicializa escrita da FLASH //habilita todas as interrupes //desabilita escrita //habilita acesso a EEPROM //aponta para memria de dados //habilita leitura //retorna dado disponvel em EEDATA
190
} /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de leitura da FLASH interna * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ unsigned short read_FLASH(unsigned endereco) { union { struct { unsigned short low:8; unsigned short high:8; } ; struct { unsigned short all; } ; }dado; TBLPTR = endereco; _asm TBLRDPOSTINC _endasm dado.low = TABLAT; _asm TBLRDPOSTINC _endasm dado.high = TABLAT; return(dado.all); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE //CONFIG //CONFIG //CONFIG //CONFIG //CONFIG DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE //carrega endereo //l posio apontada pelo TBLPTR, envia //dado para TABLAT e incremanta TBLPTR
//salva dado em dado.low //l posio apontada pelo TBLPTR, envia //dado para TABLAT e incremanta TBLPTR
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b11111111; 0b00001111; 0b11111111; 0b00000000; 0b00000100;
= = = = =
ADCON1 = 0b00001111;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LINHA_4 = 1; inicializa_lcd(); //ATIVA LINHA 4 DO TECLADO MATRICIAL // configura o lcd
191
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ cont_mem_dados = read_EEPROM(0x10); cont_mem_prog = read_FLASH(0x800); for(x=0;x<8;x++) mem[x]=0; //L MEMRIA EEPROM //L MEMRIA FLASH //INICIA BUFFER PARA GRAVAO //DA MEMRIA FLASH //ATUALIZA LINHA 1 //ATUALIZA LINHA 2
//LIMPA O WDT
if(BT1) //SE BOTO 1 PRESSIONADO { if (FILTRO) //AO DO BOTO FOI EXECUTADA? { FILTRO--; //DECREMENTA FILTRO if(!FILTRO) //TERMINOU FILTRO? { if(TIPO_MEM) TIPO_MEM = 0; //SE TIPO DE MEM = 1, TIPO DE MEM = 0 else TIPO_MEM = 1; atualiza_linha_2(); } } continue; } if(BT2) //SE BOTO 2 PRESSIONADO { FILTRO--; //DECREMENTA FILTRO if (!FILTRO) //TERMINOU FILTRO? { tempo_turbo--; if (!tempo_turbo) { if (TIPO_MEM) cont_mem_dados++; //SE TIPO DE MEM = 1, INCREMENTA cont_mem_dados else cont_mem_prog++; //SE NO, INCREMENTA cont_mem_prog atualiza_linha_2(); //ATUALIZA LINHA 2 DO LCD tempo_turbo = 30; //REINICIA TURBO DE TECLA } } continue; } if(BT3) //SE BOTO 3 PRESSIONADO { FILTRO--; //DECREMENTA FILTRO if (!FILTRO) //TERMINOU FILTRO? { tempo_turbo--; if (!tempo_turbo) { if (TIPO_MEM) cont_mem_dados--; //SE TIPO DE MEM = 1, DECREMENTA cont_mem_dados else cont_mem_prog--; //SE NO, DECREMENTA cont_mem_prog atualiza_linha_2(); //ATUALIZA LINHA 2 DO LCD tempo_turbo = 30; //REINICIA TURBO DE TECLA } } continue; } //SE NO, TIPO DE MEM = 1 //ATUALIZA LINHA 2 DO LCD
192
//SE BOTO 4 PRESSIONADO //AO DO BOTO FOI EXECUTADA? //DECREMENTA FILTRO //TERMINOU FILTRO? cont_mem_dados); //GRAVA NA EEPROM E
mem[0] = cont_mem_prog; mem[1] = cont_mem_prog >> 8; write_FLASH(0x800, &mem); } } continue; } FILTRO = 255; }// FIM LAO PRINCIPAL } //RECARREGA FILTRO DE BOTES
193
Dicas e Comentrios
Note que a rotina que grava o dado na memria de programa, na realidade, grava o valor de 4 words. Porm, o software da experincia altera o valor de apenas uma dessas words. O problema que a gravao de informaes na memria de programa, no caso do PIC18F4550, sempre deve ser realizada de 4 em 4 words. Desta forma, no possvel gravar apenas um valor ou uma word. Sempre a gravao ser de 4 words no mnimo. Portanto, sempre que se desejar gravar menos do que 4 words mantendo as outras intactas. Deve-se inicialmente realizar uma leitura de todas as 4 words, alterar as que se desejarem e regravas todas de uma nica vez.
Exerccios Propostos
1. Crie um novo sistema onde do lado esquerdo voc continua informando o dado para a E2PROM, no centro voc escolhe a posio, de 0 a 255 e do lado direito informada o tipo de operao: E para escrita e L para leitura. O boto da coluna 1 continua alterando entre os parmetros a serem ajustados e os botes das colunas 2 e 3 alteram o parmetro atual. O boto da coluna 4 efetua a operao de escrita ou leitura dependendo da seleo ajustada no LCD. 2. Repita o exerccio anterior para a memria de programa FLASH; 3. Crie um programa que copie internamente todo o cdigo de programa para outra posio. Por exemplo, copie todas a pgina 0 da memria de programa para a pgina 1. Depois, utilize o gravador e o Mplab para ler a memria de programa e verificar se a operao foi executada com sucesso.
194
Objetivo
O objetivo desta experincia mostrar ao aluno como acessar a memria de dados EEPROM externa (24LC256) utilizando os recursos de hardware do PIC para implementar o protocolo de comunicao I2C.
Descrio
Conforme comentado na descrio do hardware, est memria est mapeada no endereo 7h (111b) da rede de comunicao I2C a fim de evitar conflitos com o relgio de tempo real. Alm disso, como a memria utilizada no McMaster de 256Kbits, ou seja, 32Kbytes, so necessrios 15 bits, ou seja, 2 bytes, para o correto endereamento. Levando-se isso em considerao, para a escrita de dados na memria o microcontrolador dever enviar a seguinte seqncia de informaes: Envia o byte de controle que deve incorporar o endereo de hardware da memria na rede I2C alm do bit de R/W, que neste caso deve ser enviado em 0 a fim de sinalizar uma operao de escrita. Assim, o byte de controle completo considerando o mapeamento adotado no McMaster 10101110b; Envia um start bit; Recebe o bit de acknowledge (ACK); Envia a parte mais significativa do endereo onde o dado ser gravado; Recebe o bit de acknowledge (ACK); Envia a parte menos significativa do endereo onde o dado ser gravado; Recebe o bit de acknowledge (ACK); Envia o dado a ser gravado; Recebe o bit de acknowledge (ACK); Envia um stop bit.
J para uma operao de leitura a seqncia dever ser: Envia um start bit; Envia o byte de controle que deve incorporar o endereo de hardware da memria na rede I2C alm do bit de R/W, que neste caso deve ser enviado em 0 a fim de sinalizar uma operao de escrita. Note que inicialmente o endereo que se deseja ler deve ser escrito na memria. Assim, o byte de controle completo considerando o mapeamento adotado no McMaster 10101110b; Recebe o bit de acknowledge (ACK); Envia a parte mais significativa do endereo de o dado ser lido; Recebe o bit de acknowledge (ACK); Envia a parte menos significativa do endereo de onde o dado ser lido;
195
Recebe o bit de acknowledge (ACK); Envia outro start bit; Envia novamente o byte de controle, porm agora alterando o bit R/W para sinalizar a operao de leitura. Assim, o byte de controle completo fica 10101111b; Recebe o bit de acknowledge (ACK); Recebe o byte lido da memria; Envia um bit em 1 sinalizando que deseja encerrar leitura (sinal de NACK); Envia um stop bit.
O exemplo da experincia foi elaborado utilizando os procedimentos descritos acima. So utilizados os botes da linha 4 para manipular um valor de 8 bits mostrado no display LCD. Este valor pode ser salvo e lido na memria EEPROM. Os botes das colunas 1 e 2 so utilizados para incrementar e decrementar o valor mostrado no display. O boto da coluna 3 salva o valor do display na memria serial enquanto o boto da coluna 4 utilizado para ler o valor salvo na memria serial.
196
Esquema Eltrico
197
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
No
INICIALIZA DISPLAY
198
LIMPA WDT
TRATA BOTO 3
TRATA BOTO 2
ERRO DE LEITURA?
Sim
199
TRATA BOTO 0
TRATA BOTO 1
INCREMENTA VALOR_DADOS
DECREMENTA VALOR_DADOS
ATUALIZA LCD
ATUALIZA LCD
TESTA ACK
Sim
No
No
No
RETURN
RETURN
ACK OUT
NACK OUT
RETURN
RETURN
200
AGUARDA I2C LIVRE AGUARDA I2C LIVRE TESTA ACK TESTA ACK OCORREU ERRO? No ENVIA ENDEREO HIGH (xxxxxxxxb->SSPBUF) Sim 2 OCORREU ERRO? No RECEBE BYTE (SSPCON2,RCEN=1 Sim 2
AGUARDA I2C LIVRE TESTA ACK NACK OUT OCORREU ERRO? No ENVIA ENDEREO LOW (xxxxxxxxb->SSPBUF) Sim 2
201
I2C EEPROM WRITE ENVIA ENDEREO LOW ENVIA START BIT (SSPCON2,SEN=1)
AGUARDA I C LIVRE TESTA ACK ENVIA CONTROLE+END.COMP.+WRITE (10101110b -> SSPBUF) OCORREU ERRO? AGUARDA I2C LIVRE No TESTA ACK ENVIA DADO A SER GRAVADO (xxxxxxxxb -> SSPBUF)
Sim
OCORREU ERRO? No
Sim
Sim
OCORREU ERRO? No
Sim
RETURN
202
DELAY DE 1s
RETURN
203
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 16 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //ESTE EXEMPLO FOI ELABORADO PARA EXPLICAR O FUNCIONAMENTO DA LEITURA/ESCRITA //NA MEMRIA E2PROM SERIAL EXTERNA, UTILIZANDO O MASTER I2C. //AS FUNES DOS BOTES NA MATRIZ SO: // COLUNA 3 COLUNA4 // LINHA4 -> DECREMENTA VALOR INCREMENTA VALOR // LINHA3 -> ESCRITA DO VALOR LEITURA DO VALOR /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) -> -> -> -> -> -> -> ON ON ON OFF OFF ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = ON WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1
204
FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char FILTRO11; //FILTRAGEM 1 PARA O BOTO 1 unsigned char FILTRO12; //FILTRAGEM 2 PARA O BOTO 1 unsigned char FILTRO21; //FILTRAGEM 1 PARA O BOTO 2 unsigned char FILTRO22; //FILTRAGEM 2 PARA O BOTO 2 unsigned char FILTRO31; //FILTRAGEM 1 PARA O BOTO 3 unsigned char FILTRO32; //FILTRAGEM 2 PARA O BOTO 3 unsigned char FILTRO41; //FILTRAGEM 1 PARA O BOTO 4 unsigned char FILTRO42; //FILTRAGEM 2 PARA O BOTO 4 unsigned char valor_dados = 0;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. #define T_FILTRO 25 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }FLAGSbits; //ARMAZENA OS FLAGS DE CONTROLE #define #define #define #define #define ST_BT1 ST_BT2 ST_BT3 ST_BT4 ST_I2C FLAGSbits.BIT0 FLAGSbits.BIT1 FLAGSbits.BIT2 FLAGSbits.BIT3 FLAGSbits.BIT4 //STATUS //STATUS //STATUS //STATUS //STATUS DO DO DO DO DO BOTO BOTO BOTO BOTO I2C 1 2 3 4
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter); void escreve_lcd(unsigned char caracter); void limpa_lcd(void); void inicializa_lcd(void); void tela_principal(void); void I2C_EEPROM_WRITE(unsigned int endereco, unsigned char dado); unsigned char I2C_EEPROM_READ(unsigned int endereco); void atualiza_linha_1(void); void atualiza_linha_2(unsigned char aux); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
205
//As entradas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define BT1 PORTBbits.RB2 //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO //PORTA DO BOTO //1 -> PRESSIONADO //0 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e
#define
BT2
PORTBbits.RB3
#define
BT3
PORTBbits.RB2
#define
BT4
PORTBbits.RB3
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4
LATBbits.LATB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA //PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA // via do lcd que sinaliza recepo de // enable do lcd
#define
LINHA_3
LATBbits.LATB6
LATEbits.LATE0 LATEbits.LATE1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 3 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void)
206
{ comando_lcd(0x01); Delay1KTCYx(2); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void atualiza_linha_1(void) { comando_lcd(0x83); // posiciona o cursor na linha 0, coluna 0 escreve_lcd ('M'); // imprime mensagem no lcd escreve_lcd ('A'); escreve_lcd ('S'); escreve_lcd ('T'); escreve_lcd ('E'); escreve_lcd ('R'); escreve_lcd (' '); escreve_lcd ('I'); escreve_lcd ('2'); escreve_lcd ('C'); } // limpa 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
void atualiza_linha_2(unsigned char aux) { unsigned char hexa_high; unsigned char hexa_low; hexa_low = aux & 0b00001111; hexa_high = (aux >> 4) & 0b00001111; comando_lcd(0xC6); if(hexa_high <= 9) lcd else escreve_lcd(hexa_high + 0x37); if(hexa_low <= 9) lcd else escreve_lcd(hexa_low + 0x37); escreve_lcd ('h'); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ESCRITA DA EEPROM * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // imprime mensagem no lcd escreve_lcd (hexa_low + 0x30); // imprime mensagem no // posiciona o cursor na linha 0, coluna 0 escreve_lcd (hexa_high + 0x30); // imprime mensagem no
207
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para escrita na EEPROM externa I2C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void I2C_EEPROM_WRITE(unsigned int endereco, unsigned char dado) { unsigned char endereco_high; unsigned char endereco_low; endereco_high = endereco >> 8; endereco_low = endereco; StartI2C(); while(SSPCON2bits.SEN); WriteI2C(0b10101110); IdleI2C(); WriteI2C(endereco_high); IdleI2C(); WriteI2C(endereco_low); IdleI2C(); WriteI2C(dado); StopI2C(); while(SSPCON2bits.PEN); ClrWdt(); Delay100TCYx(100); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para leitura na EEPROM externa I2C * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ unsigned char I2C_EEPROM_READ(unsigned int endereco) { unsigned char endereco_high; unsigned char endereco_low; unsigned char dado; endereco_high = endereco >> 8; endereco_low = endereco; StartI2C(); while(SSPCON2bits.SEN); WriteI2C(0b10101110); IdleI2C(); WriteI2C(endereco_high); IdleI2C(); WriteI2C(endereco_low); IdleI2C(); RestartI2C(); while(SSPCON2bits.SEN); WriteI2C(0b10101111); IdleI2C(); SSPCON2bits.RCEN = 1; while(SSPCON2bits.RCEN); NotAckI2C(); while(SSPCON2bits.ACKEN); StopI2C(); while(SSPCON2bits.PEN);
// controle de escrita // espera fim do evento I2C // espera fim do evento I2C // espera fim do evento I2C // controle de leitura // fim de comunicao
// controle de escrita // espera fim do evento I2C // espera fim do evento I2C // espera fim do evento I2C
// fim de comunicao
return((unsigned char) SSPBUF); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () { PORTA = 0x00; PORTB = 0x00; PORTC = 0x00; //Limpa PORTA //Limpa PORTB //Limpa PORTC
208
PORTD = 0x00; PORTE = 0x00; LATA LATB LATC LATD LATE = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10010000; 0b00000000; 0b00000000;
//Limpa PORTD //Limpa PORTE //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
atualiza_linha_1(); valor_dados = I2C_EEPROM_READ(0x0100); atualiza_linha_2(valor_dados); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { ClrWdt(); FILTRO11 = 0; FILTRO12 = T_FILTRO; FILTRO21 = 0; FILTRO22 = T_FILTRO; FILTRO31 = 0; FILTRO32 = T_FILTRO; FILTRO41 = 0; FILTRO42 = T_FILTRO; LINHA_4 = 1; LINHA_3 = 0; //BT1 //BT1 //BT2 //BT2 //BT3 //BT3 //BT4 //BT4 //ATIVA LINHA 4 DO TECLADO MATRICIAL //DESATIVA LINHA 3 DO TECLADO MATRICIAL
while(BT1) { ClrWdt(); if (--FILTRO11 == 0) { FILTRO12--; if (FILTRO12 == 0) { if (!ST_BT1) { //funo valor_dados++; atualiza_linha_2(valor_dados); ST_BT1 = 1;
209
} } } } ST_BT1 = 0; // BOTO LIBERADO, LIMPA O FLAG while(BT2) { ClrWdt(); if (--FILTRO21 == 0) { FILTRO22--; if (FILTRO22 == 0) { if (!ST_BT2) { //funo valor_dados--; atualiza_linha_2(valor_dados); ST_BT2 = 1; } } } } ST_BT2 = 0; // BOTO LIBERADO, LIMPA O FLAG LINHA_4 = 0; LINHA_3 = 1; //DESATIVA LINHA 4 DO TECLADO MATRICIAL //ATIVA LINHA 3 DO TECLADO MATRICIAL
while(BT3) { ClrWdt(); if (--FILTRO31 == 0) { FILTRO32--; if (FILTRO32 == 0) { if (!ST_BT3) { //funo I2C_EEPROM_WRITE(0x0100,valor_dados); atualiza_linha_2(valor_dados); ST_BT3 = 1; } } } } ST_BT3 = 0; // BOTO LIBERADO, LIMPA O FLAG
while(BT4) { ClrWdt(); if (--FILTRO41 == 0) { FILTRO42--; if (FILTRO42 == 0) { if (!ST_BT4) { //funo valor_dados = I2C_EEPROM_READ(0x0100); atualiza_linha_2(valor_dados); ST_BT4 = 1; } } } } ST_BT4 = 0; // BOTO LIBERADO, LIMPA O FLAG } }// FIM LAO PRINCIPAL
210
Dicas e Comentrios
As constantes END_EEPROM_H e END_EEPROM_L representam a posio a ser gravada/lida da memria externa. Note que este programa no utiliza as interrupes de leitura e escrita relacionadas ao protocolo I2C. Desta forma, ele possui uma rotina (AGUARDA_I2C_LIVRE) para saber se o sistema est liberado para a prxima ao. Ele tambm testa o ACK e gera uma mensagem de erro caso alguma coisa saia fora do padro.
Exerccios Propostos
1. Faa trs modificaes no primeiro exerccio proposto da experincia 15. Utilize a memria externa; Limite os dados mostrados no display entre 0x41 e 0x5A; Mostre os dados em ASCII, ou seja, entre A (0x41) e Z (0x5A); 2. Utilizando o exerccio anterior grave na memria uma mensagem de at 16 caracteres. Depois, crie um programa que ao ser inicializado leia os 16 caracteres da memria e mostre a mensagem lida no LCD;
211
Objetivo
O objetivo desta experincia o aprendizado do mdulo USART do microcontrolador PIC18F4550 utilizado para implementar a comunicao padro RS232, geralmente utilizada para estabelecer um canal de comunicao entre um microcontrolador e um computador.
Descrio
Para tornar o sistema verstil e simples, criou-se um programa capaz de testar a transmisso e recepo de dados de modo isolado, ou seja, apenas com o McMaster sem necessariamente conecta-lo ao computador. Embora nada impea que a comunicao com o PC seja efetivamente realizada. Para atender esta necessidade, o software da experincia implementa uma comunicao assncrona Full duplex, isto , com a transmisso e a recepo ativadas simultaneamente. O valor transmitido obtido a partir da leitura da tenso do potencimetro atravs do conversor A/D limitando este valor entre 0 e 255 (8-bits). O valor do A/D ento enviado para a porta serial e para o LCD. Desta forma possvel visualizar o dado transmitido. Para facilitar ainda mais o usurio, mostra-se o valor em decimal (d) e em hexadecimal (h). A comunicao realizada no padro 8N1 com uma velocidade de 9.600bps. Quanto recepo, o valor obtido pela porta serial diretamente impresso no display de LCD, atravs do cdigo ASCII. Para que o sistema funcione sem o PC, basta interligar os pinos 2 e 3 do conector DB9. Isto far com que tudo que seja transmitido por TX seja imediatamente recebido em RX. Tanto a transmisso quanto a recepo so contnuas. No se deve esquecer de habilitar a porta RS232 para o microcontrolador atravs do boto de modo de operao aps. Para testar a comunicao com o computador (PC) pode-se utilizar o software SDCom disponvel no CD.
212
Esquema Eltrico
213
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
CONFIGURA REGISTRADOR TXSTA HABILITA TRANSMISSO MODO ASSNCRONO TRANSMISSO DE 8 BITS HIGH SPEED BAUD RATE
CONFIGURA REGISTRADOR RCSTA HABILITA RECEPO RECEPO DE 8 BITS RECEPO CONTNUA DESABILITA ADDRESS DETECT
No
INICIALIZA DISPLAY
214
FIM CONVERSO?
Sim
Sim
No
215
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 17 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ESTE EXEMPLO FOI ELABORADO PARA EXPLICAR O FUNCIONAMENTO DA USART DO PIC. O SOFTWARE CONVERTE O CANAL 1 DO CONVERSOR A/D (POTENCIMETRO P2) E MOSTRA NO DISPLAY O VALOR CONVERTIDO EM DECIMAL E HEXADECIMAL. ALM DE MOSTRAR O VALOR NO DISPLAY, O SOFTWARE TRANSMITE PELA USART O VALOR DA CONVERSO. OS VALORES RECEBIDOS PELA USART TAMBM SO MOSTRADOS NO LCD COMO CARACTERES ASCII. */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0
216
#pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma
config config config config config config config config config config config config
PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned unsigned unsigned unsigned unsigned char char char char char unidade; dezena; centena; hexa_low; hexa_high;
unsigned char converte; char usart_rx; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void void void void void void void comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); tela_principal(void); converte_bcd(unsigned char aux); converte_hexadecimal(unsigned char aux); * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. * * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define ou comando #define rs enable PORTEbits.RE0 PORTEbits.RE1
217
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 3 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { comando_lcd(0x80); // posiciona o cursor na linha 0, coluna 0 escreve_lcd ('U'); // imprime mensagem no lcd escreve_lcd ('S'); escreve_lcd ('A'); escreve_lcd ('R'); escreve_lcd ('T'); escreve_lcd (':');
// envia comando para inicializar display // espera 4 milisengundos // envia comando para inicializar display // espera 100 microsengundos // envia comando para inicializar display // liga o display, sem cursor e sem blink // limpa lcd // display sem cursor // desloca cursor para a direita
218
escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd escreve_lcd
('9'); ('6'); ('0'); ('0'); (','); ('8'); (','); ('n'); (','); ('1'); // posiciona o cursor na linha 1, coluna 4 // imprime mensagem no lcd
comando_lcd(0xC0); escreve_lcd ('T'); escreve_lcd ('X'); escreve_lcd (':'); escreve_lcd (' '); escreve_lcd (' '); escreve_lcd (' '); escreve_lcd ('d'); escreve_lcd (' '); escreve_lcd (' '); escreve_lcd (' '); escreve_lcd ('h'); escreve_lcd (' '); escreve_lcd ('R'); escreve_lcd ('X'); escreve_lcd (':'); escreve_lcd (' '); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Converte BCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void converte_bcd(unsigned char aux) { unidade = 0; dezena = 0; centena = 0; if (aux == 0)return; while(aux--) { unidade++; if(unidade != 10)continue; unidade = 0; dezena++; if (dezena != 10)continue; dezena = 0; centena++; if (centena != 10)continue; centena = 0; } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Converte hexadecimal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void converte_hexadecimal(unsigned char aux) { hexa_low = aux & 0b00001111; hexa_high = (aux >> 4) & 0b00001111; } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () {
219
PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE
= = = = =
//Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa
PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b00101111; 0b00001111; 0b10011111; 0b00000000; 0b00000000;
= = = = =
OpenADC(ADC_FOSC_8 & ADC_LEFT_JUST & ADC_0_TAD, ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS,12); //CONFIGURAO DO AD OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,25); //CONFIGURAO DA USART /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ RCON = 0x00; inicializa_lcd(); tela_principal(); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ ConvertADC(); //Inicia converso AD while(1) { if(BusyADC()) { converte = ADRESH; converte_bcd(converte); comando_lcd(0xC3); coluna 4 escreve_lcd (centena + 0x30); escreve_lcd (dezena + 0x30); escreve_lcd (unidade + 0x30); converte_hexadecimal(ADRESH); comando_lcd(0xC8); coluna 4 if(hexa_high <= 9) escreve_lcd (hexa_high + 0x30); mensagem no lcd else escreve_lcd(hexa_high + 0x37); if(hexa_low <= 9) escreve_lcd (hexa_low + 0x30); mensagem no lcd else escreve_lcd(hexa_low + 0x37); while(BusyUSART()); TRANSMISSO FICAR VAZIO WriteUSART(converte); ConvertADC(); } if(DataRdyUSART()) { // imprime // configura o lcd
// imprime
//AGUARDA O BUFFER DE
//Inicia converso AD
220
usart_rx = ReadUSART(); comando_lcd(0xCF); coluna 4 escreve_lcd(usart_rx); ConvertADC(); } }// FIM LAO PRINCIPAL
//Inicia converso AD
221
Dicas e Comentrios
A rotina de converso Hex >>> Decimal deste exemplo mais completa do que nos casos anteriores, pois trabalha com 3 dgitos (CENTENA, DEZENA e UNIDADE). Desta forma, ela pode converter todo o range do argumento de entrada (W) que vai de 0 a 255. O sistema de converso A/D o mesmo apresentado na experincia 11, onde utilizou-se o conversor interno considerando apenas os 8 bits mais significativos. Com isso o valor a ser transmitido j fica limitado a um byte. Devido a simplicidade do sistema no foi necessrio o uso das interrupes, deixando-as desabilitadas. Para o caso da recepo o bit RCIF testando toda vez dentro do loop principal. Quanto a transmisso, sempre que um novo valor foi convertido, checa-se se o buffer de sada est vazio para poder escrever o novo valor.
Exerccios Propostos
1. Ative o uso da interrupo de recebimento. Quanto transmisso, em vez de deix-la contnua, crie uma interrupo de timer como base de tempo. Por exemplo, transmita o valor atual convertido a cada 1 segundo; 2. Crie um programa no PC que receba o valor convertido, efetue alguma operao e devolva outro valor. Por exemplo, divida o valor por 25, pegue a parte inteira e some 30h para imprimir no LCD um valor de 0 a 9; 3. Mude a rotina de recepo e escrita no LCD para poder receber um nmero de 0 a 50 e mostr-lo como 0.0 a 5.0. Altere o programa do PC para efetuar a regra de 3 necessria para converter um valor de 0 a 255 para 0 a 50. Com isso voc voltou ao multmetro da experincia 11, s que com as contas de multiplicao e diviso no mais sendo feitas no PIC.
222
Objetivo
O objetivo desta experincia mostrar ao aluno um mtodo simples para implementao de um teclado matricial.
Descrio
O teclado matricial do McMaster composto por 4 linhas e 4 colunas formando assim uma matriz de 16 teclas. Desta forma, utilizam-se 8 pinos do microcontrolador para realizar a leitura do teclado. Os conceitos adotados na experincia de varredura de displays de leds no so muito diferentes dos adotados para varrer os estados de um teclado matricial. Analisando o esquema eltrico nota-se que todas as teclas de uma mesma coluna esto interligadas. Alm disso, nota-se um resistor de pull-down em cada uma das vias. Veja tambm que todas as teclas de uma mesma linha tambm encontram-se interligadas. A idia de varredura aplicada aqui habilitar uma linha de cada vez e analisar se alguma tecla da linha habilitada est pressionada. Para isso, deve-se configurar o microcontrolador com os pinos das linhas como sada e os pinos das colunas como entrada. Note que se todas as linhas estiverem em nvel lgico 0, ou seja, se nenhuma linha estiver habilitada, ao ler o estado das colunas sempre ser lido o valor 0, estando as teclas pressionadas ou no. Na verdade o microcontrolador estar lendo o estado dos resistores que no caso so de pull-down, ou seja, leitura em 0. Porm, se habilitarmos uma das linhas (e apenas uma) colocando-a em nvel lgico 1 e pressionarmos uma tecla dessa linha, ao lermos o estado das colunas encontraremos um bit em 1, sendo que a posio do bit em 1 sinalizar a coluna na qual a tecla foi pressionada. Como foi o prprio microcontrolador que habilitou a linha, o nmero da linha conhecido e como a posio do bit em 1 define a coluna da tecla fcil determinar a linha e coluna da tecla pressionada. O conceito de varredura continua vlido, pois apenas uma linha deve ser habilitada de cada vez e o microcontrolador deve ficar o tempo todo alterando (varrendo) a linha habilitada e lendo o estado das colunas. Enquanto nenhum bit das colunas valer 1, a varredura das linhas continua sendo executada. Ao encontrar uma coluna com tecla pressionada o software deve executar o filtro de debounce mantendo a linha atual habilitada at que o filtro de debounce seja finalizado. No fluxograma apresentado fica fcil de entender o conceito da varredura do teclado matricial. O exemplo da experincia analisa o teclado e caso alguma tecla seja pressionada, mostra a linha e coluna da mesma mostrado no display LCD.
223
Esquema Eltrico
224
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
No
INICIALIZA DISPLAY
225
LIMPA WDT
Sim
Sim
Sim
Sim
226
Sim
Sim
Sim
Sim
227
FIM DEBOUNCE DA TECLA ? Sim ATUALIZA O NMERO DA LINHA E DA COLUNA NO DISPLAY LCD
No
228
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 18 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* Este exemplo foi elaborado para explicar o funcionamento do teclado matricial4x4. O nmero da linha e coluna da tecla pressionada e mostrado no LCD.*/ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF
229
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * void void void void void void * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); tela_principal(void); trata_coluna(void);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. unsigned char filtro; unsigned char num_linha; unsigned char num_coluna; // unsigned char linha; teclado 4x4 // // // // Filtro para teclas Armazena o nmero da linha ativada Armazena o nmero da coluna Registrador auxiliar para ativar as linhas do
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. union Linhas_teclado{ struct{ unsigned BIT0:1; unsigned BIT1:1; unsigned BIT2:1; unsigned BIT3:1; unsigned BIT4:1; unsigned BIT5:1; unsigned BIT6:1; unsigned BIT7:1; }; //ARMAZENA OS FLAGS DE CONTROLE unsigned char linha_teclado; }linha_ativa; #define linha1 LINHA_ATIVA linha_ativa.BIT4 /* LINHA_ATIVA,4, BIT 4 DO REGISTRADOR REPRESENTA A LINHA 1 DO TECLADO 4x4
230
1 -> LINHA EST ATIVADA 0 -> LINHA EST DESATIVADA */ #define linha2 LINHA_ATIVA linha_ativa.BIT5 /* LINHA_ATIVA,5, BIT 5 DO REGISTRADOR REPRESENTA A LINHA 2 DO TECLADO 4x4 1 -> LINHA EST ATIVADA 0 -> LINHA EST DESATIVADA */ #define linha3 LINHA_ATIVA linha_ativa.BIT6 /* LINHA_ATIVA,6, BIT 6 DO REGISTRADOR REPRESENTA A LINHA 3 DO TECLADO 4x4 1 -> LINHA EST ATIVADA 0 -> LINHA EST DESATIVADA */ #define linha4 LINHA_ATIVA linha_ativa.BIT7 /* LINHA_ATIVA,7, BIT 7 DO REGISTRADOR REPRESENTA A LINHA 4 DO TECLADO 4x4 1 -> LINHA EST ATIVADA 0 -> LINHA EST DESATIVADA */ #define fim linha_ativa.BIT3 /* REPRESENTA O FINAL DA VARREDURA 1 -> LINHA EST ATIVADA 0 -> LINHA EST DESATIVADA */
#define
linha
linha_ativa.linha_teclado * * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao e do hardware. PORTBbits.0 /* PINO DE ENTRADA DA COLUNA 1 1 -> ALGUMA TECLA DESTA COLUNA * * */
EST
0 -> NENHUMA TECLA DESTA COLUNA EST PRESSIONADA */ #define PRESSIONADA 0 -> NENHUMA TECLA DESTA COLUNA EST PRESSIONADA */ #define PRESSIONADA 0 -> NENHUMA TECLA DESTA COLUNA EST PRESSIONADA */ #define PRESSIONADA 0 -> NENHUMA TECLA DESTA COLUNA EST PRESSIONADA */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define rs dados ou comando #define enable PORTEbits.RE0 PORTEbits.RE1 // via do lcd que sinaliza recepo de // enable do lcd coluna4 PORTBbits.3 /* PINO DE ENTRADA DA COLUNA 4 1 -> ALGUMA TECLA DESTA COLUNA EST coluna3 PORTBbits.2 /* PINO DE ENTRADA DA COLUNA 3 1 -> ALGUMA TECLA DESTA COLUNA EST coluna2 PORTBbits.1 /* PINO DE ENTRADA DA COLUNA 2 1 -> ALGUMA TECLA DESTA COLUNA EST
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) {
231
// // // // // //
seleciona o envio de um comando carrega o PORTD com o caracter gera pulso no enable espera 3 microsegundos desce o pino de enable espera mnimo 40 microsegundos
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { comando_lcd(0x82); // posiciona o cursor na linha 0, coluna 0 escreve_lcd ('T'); // imprime mensagem no lcd escreve_lcd ('e'); escreve_lcd ('c'); escreve_lcd ('l'); escreve_lcd ('a'); escreve_lcd ('d'); escreve_lcd ('o'); escreve_lcd (' '); escreve_lcd ('4'); escreve_lcd ('X');
// 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
232
escreve_lcd ('4'); comando_lcd(0xC0); escreve_lcd ('L'); escreve_lcd ('i'); escreve_lcd ('n'); escreve_lcd ('h'); escreve_lcd ('a'); escreve_lcd (':'); escreve_lcd (' '); escreve_lcd (' '); escreve_lcd ('C'); escreve_lcd ('o'); escreve_lcd ('l'); escreve_lcd ('u'); escreve_lcd ('n'); escreve_lcd ('a'); escreve_lcd (':'); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina para tratamento das colunas do Teclado 4X4 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void trata_coluna(void) { if(filtro) { filtro--; if (filtro)return; } PORTB = 0; comando_lcd(0xC6); // posiciona o cursor na linha 1, coluna 6 escreve_lcd (0x30 + num_linha); // comando_lcd(0xCF); // posiciona o cursor na linha 1, coluna 15 escreve_lcd (0x30 + num_coluna);// PORTD = 0; PORTB = linha; } // posiciona o cursor na linha 1, coluna 0 // imprime mensagem no lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
233
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ linha = 0b00010000; while(1) { ClrWdt(); // rotina principal //Inicia o watch-dog timer
ativa_proxima_linha: if (filtro == 100) { linha = linha >> 1; if (fim) linha = 0b10000000; PORTB = linha; } if (linha4) num_linha = 4; // verifica qual a linha ativa if (linha3) num_linha = 3; if (linha2) num_linha = 2; if (linha1) num_linha = 1; switch(PORTB & 0b00001111) { case 1: num_coluna = 1; trata_coluna(); break; case 2: num_coluna = 2; trata_coluna(); break; case 4: num_coluna = 3; trata_coluna(); break; case 8: num_coluna = 4; trata_coluna(); break; default: filtro = 100; PORTB = 0; segmentos comando_lcd(0xC6); escreve_lcd (' '); comando_lcd(0xCF); escreve_lcd (' '); PORTD = 0; PORTB = linha; } } } // posiciona o cursor na linha 1, coluna 6 // // posiciona o cursor na linha 1, coluna 15 //
234
Dicas e Comentrios
Notar que ao habilitar uma linha do teclado matricial tambm se habilita um dos displays de 7 segmentos, ou seja, foram utilizados os mesmos pinos do microcontrolador para habilitar as linhas e os displays. Esta uma forma econmica de varrer os displays e ao mesmo tempo varrer o teclado. Veja que com apenas 16 I/Os do microcontrolador foi possvel ligar 4 displays de 7 segmentos e 16 teclas. Foram utilizados 8 I/Os para segmentos mais o ponto decimal, 4 I/Os de seleo (linhas e displays) e 4 I/Os de colunas.
Exerccios Propostos
1. Alterar o mapeamento do software invertendo a numerao das linhas e colunas. 2. Mostrar no display LCD o nmero da tecla pressionada e no o nmero da linha e da coluna. 3. Sem utilizar o display LCD, fazer um software que utilize a varredura do teclado e dos displays ao mesmo tempo, mostrando o nmero da tecla pressionada nos displays.
235
Objetivo
O objetivo desta experincia mostrar como utilizar o relgio de tempo real (RTC).
Descrio
No McMaster optou-se pela utilizao do relgio de tempo real (RTC) modelo PCF8583P da Philips. O protocolo de comunicao do tipo I2C e para maiores informaes a respeito do componente deve-se consultar o data sheet disponvel no CD. As rotinas de acesso ao relgio seguem o padro adotado na experincia 16 (Master I2C) com apenas algumas modificaes. Na realidade as alteraes so que o relgio est mapeado no endereo 0h (000b) para evitar conflitos com a memria e ao invs de serem utilizados dois bytes para compor o endereo foi utilizado apenas um o que j suficiente. O software da experincia apenas l a hora atual do relgio e mostra o resultado no LCD. Vale lembrar que o relgio completo, ou seja, dispe de hora, minuto, segundo, dia, ms e ano, inclusive bissexto.
236
Esquema Eltrico
237
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION, ADs.
No
INICIALIZA DISPLAY
238
LIMPA WDT
I2C_READ_RTC
I2C_READ_RTC
I2C_READ_RTC
239
Sim
No
No
No
RETURN
RETURN
ACK OUT
NACK OUT
RETURN
RETURN
240
TESTA ACK
AGUARDA I C LIVRE
Sim
TESTA ACK
OCORREU ERRO? No
Sim
NACK OUT
RETURN
RETURN
241
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 19 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Exemplo de utilizao do relgio de tempo real PCF8583 atravs da interface //I2C. Para maiores informaes a respeito do integrado consultar o datasheet //do componente. /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ -> -> -> -> -> -> -> ON ON ON OFF OFF ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF
242
VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao dos port's * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * void void void void void void void * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); tela_principal(void); LE_RELOGIO(unsigned char endereco); ESCREVE_RELOGIO(unsigned char endereco); * * * * * * * * * * * * * * * * * * * * * * * * * * */ e a manuteno. HORA NO RELOGIO RTC
/* * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * //A definio de constantes facilita a programao #define END_HORA 4 // ENDEREO DA #define #define END_MINUTO END_SEGUNDO 3 2
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char dez_hora; unsigned char uni_hora; unsigned char dez_min; unsigned char uni_min; unsigned char dez_seg; unsigned char uni_seg; unsigned char buffer; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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 *
243
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ // As sadas devem ser associadas a nomes para facilitar a programao e //futuras alteraes do hardware. #define rs dados ou comando #define enable PORTEbits.RE0 PORTEbits.RE1 // via do lcd que sinaliza recepo de // enable do lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 3 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * LEITURA DO RELGIO * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
// 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
244
void LE_RELOGIO(unsigned char endereco) { StartI2C(); IdleI2C(); // espera fim do evento I2C WriteI2C(0b10100000); // controle de escrita IdleI2C(); // espera fim do evento I2C WriteI2C(endereco); // l o relgio IdleI2C(); // espera fim do evento I2C RestartI2C(); // restart IdleI2C(); // espera fim do evento I2C WriteI2C(0b10100001); // controle de leitura IdleI2C(); // espera fim do evento I2C buffer = ReadI2C(); // recebe dado do relgio IdleI2C(); // espera fim do evento I2C StopI2C(); // fim de comunicao IdleI2C(); // espera fim do evento I2C } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ESCRITA NO RELGIO * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void ESCREVE_RELOGIO(unsigned char endereco) { StartI2C(); IdleI2C(); // espera fim do evento I2C WriteI2C(0b10100000); // controle de escrita IdleI2C(); // espera fim do evento I2C WriteI2C(endereco); // escreve dado no relgio IdleI2C(); // espera fim do evento I2C WriteI2C(buffer); // escreve dado no relgio IdleI2C(); // espera fim do evento I2C StopI2C(); IdleI2C(); // espera fim do evento I2C } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Tela Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void tela_principal(void) { comando_lcd(0x83); // posiciona o cursor na linha 0, coluna 0 escreve_lcd ('R'); escreve_lcd ('e'); escreve_lcd ('l'); escreve_lcd ('o'); escreve_lcd ('g'); escreve_lcd ('i'); escreve_lcd ('o'); // imprime mensagem no lcd } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes do Pic * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main() { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
TRISA=(0b11111111); TRISB=(0b11111111);
245
TRISC=(0b11110111); TRISD=(0b00000000); TRISE=(0b00000100); ADCON1=0b00001111; OpenI2C(MASTER,SLEW_OFF); SSPADD = 9; buffer = 0x23; // acerta hora ESCREVE_RELOGIO(END_HORA); buffer = 0x40; // acerta minuto ESCREVE_RELOGIO(END_MINUTO); buffer = 0x00; // acerta segundos ESCREVE_RELOGIO(END_SEGUNDO); inicializa_lcd(); tela_principal(); // configura o lcd // imprime a tela principal no LCD
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) // rotina principal { ClrWdt(); //Inicia o watch-dog timer LE_RELOGIO(END_HORA); dez_hora = buffer >> 4; dez_hora = (dez_hora & 0b00000011) + 0x30; uni_hora = buffer; uni_hora = (uni_hora & 0b00001111) + 0x30; LE_RELOGIO(END_MINUTO); dez_min = buffer >> 4; dez_min = (dez_min & 0b00001111) + 0x30; uni_min = buffer; uni_min = (uni_min & 0b00001111) + 0x30; LE_RELOGIO(END_SEGUNDO); dez_seg = buffer >> 4; dez_seg = (dez_seg & 0b00001111) + 0x30; uni_seg = buffer; uni_seg = (uni_seg & 0b00001111) + 0x30; comando_lcd(0xC3); escreve_lcd (dez_hora); escreve_lcd (uni_hora); escreve_lcd (':'); escreve_lcd (dez_min); escreve_lcd (uni_min); escreve_lcd (':'); escreve_lcd (dez_seg); escreve_lcd (uni_seg); } } // // // // // // // // // posiciona o cursor na linha 0, coluna 3 DEZ. HORA UNID. HORA DEZ. MINUTO UNID. MINUTO DEZ. SEGUNDO UNID. SEGUNDO
246
Dicas e Comentrios
Alm do relgio RTC o componente PCF8583 da Philips apresenta tambm uma regio da memria que pode ser utilizada com uma RAM convencional, porm com acesso via I2C. Como geralmente o relgio sempre utilizado junto com uma bateria, como no McMaster, este recurso da RAM pode ser til para armazenar informaes enquanto o microcontrolador no est energizado.
Exerccios Propostos
1. Altere o software para mostrar a data e a hora no display LCD. 2. Crie um software para ajustar a data e hora do relgio utilizando o teclado matricial.
247
Objetivo
O objetivo desta experincia mostrar a maioria os recursos disponveis na placa de experincias EXP01.
Descrio
O monitoramento da temperatura um dos problemas mais clssicos enfrentado pela maioria dos projetistas. Como o McMaster possui um sensor de temperatura (diodo) e dois atuadores: aquecimento (resistncia) e resfriamento (ventilador), nada melhor que implementar um sistema capaz de obter a temperatura atual para mostr-la no LCD.
O sensor de temperatura
Para obter a temperatura ambiente, fez-se uso de um diodo. Como o diodo um componente que apresenta uma queda de tenso sobre ele proporcional a temperatura do mesmo, basta monitorar a tenso para encontrar a temperatura. Para isso, o circuito eletrnico faz uso de um diodo de sinal convencional (1N4148) ligado a um amplificador e a uma porta analgica do PIC. Tambm est ligado ao amplificador um potencimetro a fim de alterar o off-set da curva, ajustando assim a temperatura com uma referncia externa. Internamente, o sistema trabalha com uma converso A/D de 8 bits, gerando 256 possveis valores de tenso para o diodo. Para cada valor obtido, tem-se uma temperatura relacionada. A rotina TABELA_TEMP, que se encontra no final do cdigo apresentado neste captulo, efetua a converso entre a tenso lida (unidades de A/D) e a temperatura real. Nada mais que uma tabela de converso/linearizao. Esta tabela foi construda com base na curva de resposta do diodo utilizado em funo da temperatura. Caso seja construdo um sensor de temperatura com outro tipo de componente que gere uma tenso varivel, basta refazer a tabela de converso. Uma vez convertida, a temperatura ento mostrada no LCD, na unidade de Celsius [C] (lado direito).
O aquecimento
O software possibilita que o usurio aumente a temperatura sobre o diodo atravs do controle manual da resistncia existente na placa. Isso feito por intermdio de um dos PWMs do PIC, que se encontra ligado ao resistor. Atravs dos botes das colunas 1 e 2 pode-se aumentar e diminuir o duty cycle do PWM, variando de 0 a 100%. Mantendo-se os botes pressionados o incremento/decremento automtico. O valor atual para o aquecimento mostrado no LCD (lado esquerdo).
248
O resfriamento
Inversamente ao aquecimento, o software possibilita tambm o resfriamento do sistema atravs do ventilador, que controlado pelo outro canal de PWM do PIC. Obviamente o sistema s capaz de obter temperaturas levemente abaixo do valor ambiente, mas a inteno poder criar variveis diferentes de aquecimento e resfriamento. Controla-se o ventilador pelo duty cycle do PWM, mas para o sistema ficar um pouco mais completo, mostra-se no LCD (centro) o valor da rotao do motor, em RPS (rotaes por segundo). Isto feito atravs do sensor ptico que se encontra instalado na base das hlices do ventilador. Os botes das colunas 3 e 4 so usados para aumentar e diminuir o duty cycle do PWM, variando de 0 a 100%. Mantendo-se os botes pressionados o incremento/decremento automtico. Cada vez que uma das ps da hlice passa em frente ao sensor ptico, um pulso transmitido ao PIC. Como este sinal est ligado ao pino RC1, utilizou-se o TMR1 com incremento externo para contabilizar a quantidade de pulsos gerados. A cada segundo (base de tempo gerada pela interrupo de TMR2), o total de pulsos transferido para a varivel CONT_VENT. Antes de mostrar o valor correto no LCD, deve-se dividir o total de pulsos durante 1 segundo (CONT_VENT) pelo nmero de paletas (pulsos por volta). Neste caso CONT_VENT dividido por 7.
Comunicao serial
O sistema possibilita ainda que maiores implementaes sejam feitas com o tratamento externo da temperatura, pois os valores obtidos so enviados automaticamente pela porta serial, a cada segundo. Com isso, possvel criar um pequeno programa de computador capaz de plotar esta temperatura no decorrer do tempo. Os dados tambm podem ser armazenados para clculos ou consultas futuras. Os dados so transmitidos pela USART atravs do conector DB-9, respeitando-se o padro RS-232 com 8N1 e baud rate de 9.600bps. A cada 1 segundo transmitido um byte com o valor da temperatura j convertido para Celsius [C].
Consideraes gerais
Ambos os PWMs so controlados pelo TMR2, que est regulado para 1ms. Por isso, o perodo dos 2 PWMs de 1ms, ou seja, eles operam a 1kHz. O postscale do TMR2 foi regulado em 1:10, gerando uma interrupo a cada 10ms. Utilizou-se um contador auxiliar (TEMPO_1S) para contabilizar 100 interrupes, gerando a base de tempo de 1 segundo. Esta base utilizada para capturar a rotao do ventilador, efetuar uma converso de temperatura e transmitir dados pela USART.
249
Esquema Eltrico
250
Fluxograma
INCIO
VETOR DE RESET PULA P/ INCIO DO PROGRAMA CONFIGURAES INICIAIS PORTAS, TIMERS, INTERRUPES, OPTION.
CONFIGURA REGISTRADORES ADCON0 E ADCON1 PARA CONVERTER O CANAL 0 DO CONVERSOR A/D SENSOR DE TEMPERATURA
CONFIGURA INTERRUPO DE TMR2 A CADA 10ms UTILIZANDO A BASE DE TEMPO DOS PWMs
No
INICIALIZA DISPLAY E PREPARA TELA PRINCIPAL AQUEC. RPS TEMP. 000% 000 000C
251
LIMPA WDT
ATUALIZAR RPS? No ATUALIZAR TEMP.? No BOTO 0 PRESS.? No BOTO 1 PRESS.? No BOTO 2 PRESS.? No BOTO 3 PRESS.? No
Sim MOSTRA_RPS_LCD
Sim MOSTRA_TEMP_LCD
252
TRATA BOTO 0
TRATA BOTO 1
No
No
TRATA BOTO 2
TRATA BOTO 3
No
No
253
MOSTRA_RPS_LCD
INTERRUPO
SALVA CONTEXTO
CALCULA AS ROTAES POR SEGUNDO DO VENTILADOR (DIVIDE O CONTADOR PELO NMERO DE PALHETAS)
No
RETURN
MOSTRA_TEMP_LCD
RECUPERA CONTEXTO
RETFIE
RETURN
254
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * Exemplo 20 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ESTE EXEMPLO FOI ELABORADO PARA EXPLICAR O FUNCIONAMENTO DO TMR1 COMO CONTADOR, UTILIZADO NA PLACA MCLAB2 PARA CONTAR AS ROTAES DO VENTILADOR. O SOFTWARE CONVERTE O CANAL 0 DO CONVERSOR A/D (SENSOR DE TEMPERATURA). DOIS PWMs FORAM UTILIZADOS, UM PARA MODULAR A RESISTNCIA DE AQUECIMENTO E OUTRO PARA A VELOCIDADE DO VENTILADOR. COM AS TECLAS S1 E S2 PODE-SE VARIAR O PWM DO AQUECEDOR E COM AS TECLAS S3 E S4 O PWM DO VENTILADOR. NO LCD SO MOSTRADOS OS VALORES DO PWM DO AQUECEDOR, O NMERO DE ROTAES POR SEGUNDO DO VENTILADOR E A TEMPERATURA DO DIODO J CONVERTIDA EM GRAUS CELSIUS. ALM DISSO, O VALOR ATUAL DA TEMPERATURA DO DIODO TRANSMITIDO PERIODICAMENTE ATRAVS DA USART. */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) */ -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON
255
#pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma
config config config config config config config config config config config config config config
BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned unsigned char char char char char char char short char char FILTRO; tempo_turbo = 30; unidade; dezena; centena; tempo = 100; temperatura = 0; cont_vent = 0; intensidade_vent = 0; intensidade_aquec = 0;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * TABELA DE LINEARIZAO DO SENSOR DE TEMPERATURA * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * rom const unsigned char tabela_temp[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, 2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9, 10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17, 18,18,19,19,20,20,21,21,22,22,23,23,23,24,24,25, 25,26,26,27,27,28,28,29,29,30,30,31,31,32,32,33, 33,34,34,35,35,36,36,37,37,38,38,39,39,40,40,41, 41,42,42,43,43,44,44,45,45,46,46,47,47,48,48,49, 49,50,50,51,51,52,52,53,53,54,54,55,55,56,56,57, 57,58,58,59,59,60,60,61,61,62,62,63,63,64,64,65, 65,66,66,67,67,68,68,69,69,70,70,71,71,72,72,73, 73,74,74,75,75,76,76,77,77,78,78,79,79,80,80,81, 81,82,82,83,83,84,84,85,85,86,86,87,87,88,88,089, 89,90,90,91,91,92,92,93,93,94,94,95,95,96,96,097, 97,98,98,99,99,100,100,101,101,102,102,103,103,104,104,104, 105,105,106,106,107,107,108,108,109,109,110,110,111,111,112,112 }; * * * * * * * * * * */ //15 //31 //47 //63 //79 //95 //111 //127 //143 //159 //175 //191 //207 //223 //239 //255
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM. struct { unsigned unsigned unsigned unsigned unsigned unsigned unsigned
256
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void void void void void void void void comando_lcd(unsigned char caracter); escreve_lcd(unsigned char caracter); limpa_lcd(void); inicializa_lcd(void); escreve_frase(const rom char *frase); tela_principal(void); TRATA_INT_TIMER2(void); TRATA_HIGH_INT(void); * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. //BOTO 1 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 2 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 3 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 4 //0 -> PRESSIONADO //1 -> LIBERADO * * * * * * * * * * * * * * * * * * * SADAS * * * * * * * * * * * * * * * * * * * */ nomes para facilitar a programao e * * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4
PORTBbits.RB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA
PORTEbits.RE0 PORTEbits.RE1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable
257
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01); Delay1KTCYx(2); }
// limpa lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para escrever uma frase no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_frase(const rom char *frase) { do { escreve_lcd(*frase); }while(*++frase); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * FUNO PARA SEPARAR DGITOS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void converte_bcd(unsigned char aux) { unidade = 0; dezena = 0;
// 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
258
centena = 0; if (aux == 0)return; //SE AUX. FOR IGUAL A ZERO, SAI while(aux--) { unidade++; if(unidade != 10)continue; unidade = 0; dezena++; if (dezena != 10)continue; dezena = 0; centena++; if (centena != 10)continue; centena = 0; } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo de tratamento de interrupo de Timer2 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void TRATA_INT_TIMER2(void) { PIR1bits.TMR2IF = 0; // limpa flag de interrupo tempo--; // DECREMENTA TEMPO if(!tempo) // TEMPO = 0? { tempo = 100; // REINICIA TEMPO cont_vent = ReadTimer1(); //LER O VALOR DO TIMER1 WriteTimer1(0); //carraga timer1 com 0 MOSTRA_RPS = 1; // SETA FLAG MOSTRA_RPS } temperatura = ADRESH; // LER O RESULTADO DA CONVERSO AD ConvertADC(); // INICIA UMA NOVA CONVERSO MOSTRA_TEMPERATURA = 1; // SETA FLAG MOSTRA_TEMPERATURA } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE //CONFIG //CONFIG //CONFIG //CONFIG //CONFIG DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA0 PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b11101111; 0b00001111; 0b10111001; 0b00000000; 0b00000100;
= = = = =
OpenADC(ADC_FOSC_8 & ADC_LEFT_JUST & ADC_0_TAD, ADC_CH1 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,12); //CONFIGURAO DO AD OpenUSART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_HIGH,25); //CONFIGURAO DA USART OpenTimer1(TIMER_INT_OFF & T1_SOURCE_EXT & T1_16BIT_RW & T1_PS_1_1 & T1_OSC1EN_OFF & T1_SYNC_EXT_ON); //CONFIGURAO DO TIMER1
259
OpenTimer2(TIMER_INT_ON & T2_PS_1_4 & T2_POST_1_10); //CINFIGURAO DO TIMER2 // OpenPWM1(249); //CONFIGURAO DO MDULO CCP1 -> PWM CCP1CON = 0B00001100; PR2 = 249; OpenPWM2(249); //CONFIGURAO DO MDULO CCP2 -> PWM CCP2CON = 0B00001111;
//
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ LINHA_4 = 1; SetDCPWM1(0); SetDCPWM2(0); //ATIVA LINHA 4 DO TECLADO MATRICIAL //DUTY CYCLE DO PWM1 EM 0 //DUTY CYCLE DO PWM2 EM 0 //LIGA AS INTERRUPES
//INICIALIZA O LCD
MOSTRA_RPS = 0; //LIMPA OS FLAGS MOSTRA_TEMPERATURA = 0; comando_lcd(0x80); //IMPRIME A TELA PRINCIPAL escreve_frase("Aquec. RPS TEMP"); comando_lcd(0xC0); escreve_frase(" 000% 000 000 C"); comando_lcd(0xCE); escreve_lcd(0xDF); /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { ClrWdt(); if(MOSTRA_RPS) //DEVE MOSTRAR O VALOR DO RPS? { MOSTRA_RPS = 0; //LIMPA FLAG cont_vent = cont_vent / 7; //DIVIDE A LEITURA DO TIMER1 POR 7 converte_bcd((unsigned char)cont_vent);//EFETUA A CONVERSO EM BCD comando_lcd(0xC7); // posiciona o cursor na linha 1, coluna 7 escreve_lcd (centena + 0x30); // imprime mensagem no lcd escreve_lcd (dezena + 0x30); escreve_lcd (unidade + 0x30); } if(MOSTRA_TEMPERATURA) //DEVE MOSTRAR A TEMPERATURA? { MOSTRA_TEMPERATURA = 0; //LIMPA FLAG converte_bcd(tabela_temp[temperatura]);//BUSCA O VALOR CORRETO DA TEMP. comando_lcd(0xCB); 11 escreve_lcd (centena + 0x30); // imprime mensagem no lcd escreve_lcd (dezena + 0x30); escreve_lcd (unidade + 0x30); while(BusyUSART()); VAZIO WriteUSART(temperatura); //ENVIA TEMPERATURA USART //AGUARDA BUFFER DE TRANSMISSO FICAR //E EFETUA A CONVERSO EM BCD // posiciona o cursor na linha 1, coluna
260
} if(BT1) { FILTRO--; if (!FILTRO) { tempo_turbo--; if (!tempo_turbo) { if(intensidade_aquec { //BOTO 1 PRESSIONADO? //DECREMENTA FILTRO DE BOTO //FILTRO = 0? //DECREMENTA TURBO //TURBO =0? < 100)
intensidade_aquec++; //SE INTENSIDADE_AQUEC < 100, INCREMENTA converte_bcd(intensidade_aquec); //CONVERTE INTENSIDADE_AQUE EM BCD comando_lcd(0xC1); // posiciona o cursor na linha 1, coluna 1 escreve_lcd (centena + 0x30); // imprime mensagem no lcd escreve_lcd (dezena + 0x30); escreve_lcd (unidade + 0x30); SetDCPWM1((unsigned short)intensidade_aquec*10);//ATUALIZA PWM1 tempo_turbo = 30; //REINICIA TURBO DE TECLA } } } continue; } if(BT2) //BOTO 2 PRESSIONADO? { FILTRO--; //DECREMENTA FILTRO DE BOTO if (!FILTRO) //FILTRO = 0? { tempo_turbo--; //DECREMENTA TURBO if (!tempo_turbo) //TURBO =0? { if(intensidade_aquec > 0) { intensidade_aquec--; //SE INTENSIDADE_AQUEC > 0, DECREMENTA converte_bcd(intensidade_aquec); //CONVERTE INTENSIDADE_AQUE EM BCD comando_lcd(0xC1); // posiciona o cursor na linha 1, coluna 1 escreve_lcd (centena + 0x30); // imprime mensagem no lcd escreve_lcd (dezena + 0x30); escreve_lcd (unidade + 0x30); SetDCPWM1((unsigned short)intensidade_aquec*10);//ATUALIZA PWM1 tempo_turbo = 30; //REINICIA TURBO DE TECLA } } } continue; } if(BT3) //BOTO 3 PRESSIONADO? { FILTRO--; //DECREMENTA FILTRO DE BOTO if (!FILTRO) //FILTRO = 0? { tempo_turbo--; //DECREMENTA TURBO if (!tempo_turbo) //TURBO =0? { if(intensidade_vent < 100) intensidade_vent++; //SE INTENSIDADE_VENT < 100, INCREMENTA SetDCPWM2((unsigned short)intensidade_vent*10);//ATUALIZA PWM2 tempo_turbo = 30; //REINICIA TURBO DE TECLA } }
261
continue; } if(BT4) //BOTO 4 PRESSIONADO? { FILTRO--; //DECREMENTA FILTRO DE BOTO if (!FILTRO) //FILTRO = 0? { tempo_turbo--; //DECREMENTA TURBO if (!tempo_turbo) //TURBO =0? { if(intensidade_vent > 0) intensidade_vent--; //SE INTENSIDADE_VENT > 0, DECREMENTA SetDCPWM2((unsigned short)intensidade_vent*10);//ATUALIZA PWM2 tempo_turbo = 30; //REINICIA TURBO DE TECLA } } continue; } FILTRO = 255;//REINICIA FILTRO DE BOTO } } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // * ROTINA DE TRATAMENTO DE INT DE ALTA PRIORIDADE * // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * #pragma code VETOR_HIGH_PRIORITY = 0x0008 void HIGH_int(void) { _asm goto TRATA_HIGH_INT _endasm } #pragma code #pragma interrupt TRATA_HIGH_INT void TRATA_HIGH_INT(void) { if(PIR1bits.TMR2IF) TRATA_INT_TIMER2(); }
262
Dicas e Comentrios
Para converter a temperatura do diodo lida pelo conversor A/D na temperatura ambiente em graus Celsius utilizou-se uma tabela de converso, do mesmo tipo da utilizada para converter um nmero BCD numa representao grfica para displays de 7 segmentos. Porm, como a tabela relativamente extensa (possui 256 posies, relativos aos 8 bits da converso A/D), para economizar espao na listagem do software utilizou-se a diretriz DT. O compilador interpreta a diretriz substituindo cada valor que a sucede por uma instruo RETLW. Assim, o cdigo fonte exatamente o mesmo que se fosse utilizada a instruo RETLW, porm, ao invs de escrever 256 vezes a instruo RETLW e o valor de retorno, utilizou-se a diretriz. Em cada linha foram passados 16 argumentos, desta forma, no exemplo da experincia 20, o compilador substitui cada linha com a instruo DT por 16 instrues RETLW. Este recurso no altera em nada o cdigo fonte e o funcionamento do programa.
Exerccios Propostos
1. Fazer um software para controlar a temperatura do diodo. Este software deve medir a temperatura e alterar o valor do PWM da resistncia para manter a temperatura do diodo em constante em 50C. 2. Fazer um software para controlar a velocidade de rotao do ventilador. Este software deve medir rotao e alterar o valor do PWM a fim de manter a rotao constante.
263
Objetivo
O objetivo desta experincia validar a placa de experincia EXP01.
Descrio
Esta placa de experincia possui um sistema taco-gerador, um ventilador e um sistema de aquecimento resistivo. Para trabalhar com esses recursos carregue o exemplo 20 desenvolvido para o respectivo microcontrolador. Obs: (1) O acionamento da lmpada possvel apenas quando trabalhamos com os microcontroladores PIC16F877A e PIC18F4520; o microcontrolador PIC18F4550 reserva esta sada para o mdulo USB interno.
264
Objetivo
O objetivo desta experincia validar a placa de experincia EXP02.
Descrio
Este PIC possui 2 canais de PWMs (CCP1 e CCP2), cada um com resoluo mxima de 10 bits. Cada sada est ligada a um integrador cuja sada diretamente proporcional ao ciclo ativo do PWM. A variao do ciclo ativo do PWM ser feita pelo potencimetro de 10k que se encontra na placa principal via conversor A/D. O valor da sada do conversor D/A mostrado em percentual (de 0% a 100%). Alem disso testado os rels. Pressionando o boto 0 o rel 1 atraca at liberar o mesmo boto. Pressionando o boto 1 o rel 2 atraca at liberar o mesmo boto. Obs: (1) O acionamento do rel 2 possvel apenas quando trabalhamos com os microcontroladores PIC16F877A e PIC18F4520; o microcontrolador PIC18F4550 reserva esta sada para o mdulo USB interno.
265
Esquema Eltrico
Placa principal
266
Placa de experincias
267
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * EXP02 * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /* ESTE EXEMPLO FOI ELABORADO PARA TRABALHAR COM A PLACA DE EXPERIMENTOS */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON * * */ 2
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF
268
#pragma config CCP2MX = ON #pragma config STVREN = OFF #pragma config ICPRT = OFF /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned int buffer = 0; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constantes internas * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de constantes facilita a programao e a manuteno. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * TABELA DE LINEARIZAO DO SENSOR DE TEMPERATURA * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Declarao dos flags de software * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //A definio de flags ajuda na programao e economiza memria RAM.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. //BOTO 1 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 2 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 3 //0 -> PRESSIONADO //1 -> LIBERADO //BOTO 4 //0 -> PRESSIONADO //1 -> LIBERADO
* * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define LINHA_4
LATBbits.LATB7
//PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA //0 -> LINHA DESATIVADA //PINO PARA ATIVAR LINHA 4 DO TECLADO //MATRICIAL //1 -> LINHA ATIVADA
#define
RELE1
LATCbits.LATC0
269
//0 -> LINHA DESATIVADA /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE //CONFIG //CONFIG //CONFIG //CONFIG //CONFIG DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA0 PORTB PORTC PORTD PORTE
= = = = =
0x00; 0x00; 0x00; 0x00; 0x00; 0b11101111; 0b00001111; 0b10110000; 0b11111111; 0b00000100;
= = = = =
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ OpenADC(ADC_FOSC_8 & ADC_RIGHT_JUST & ADC_0_TAD, ADC_CH0 & ADC_INT_OFF & ADC_REF_VDD_VSS,12); //CONFIGURAO DO AD OpenTimer2(TIMER_INT_OFF & T2_PS_1_4 & T2_POST_1_10); //CONFIGURAO DO TIMER2 PR2 = 249; //CONFIGURAO DO MDULO CCP1 -> PWM CCP1CON = 0B00001100; //CONFIGURAO DO MDULO CCP2 -> PWM CCP2CON = 0B00001111; LINHA_4 = 1; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { if (BT1) RELE1 = 1; else RELE1 = 0; ConvertADC(); if(BusyADC()) { SetDCPWM1(ReadADC()); SetDCPWM2(ReadADC()); } } } // Atualiza canais PWM com valor da // converso
// Verifica pressionamento do boto1 // Aciona rele1 // Desaciona rele1 // Realiza uma converso // Verifica se o conversor finalizou converso
270
Objetivo
O objetivo desta experincia validar a placa de experincia EXP03.
Descrio
A placa de experincia EXP03 oferece como periferia ao microcontrolador uma chave DIPSWITCH de 8 posies, um potencimetro digital e um conector USB(1). Seus exemplos esto divididos da seguinte forma: Exemplo 3a - leitura das chaves e acendimento dos leds Exemplo 3b - leitura das chaves para comando de potencimetro digital com leitura da tenso de referncia gerada atravs do mdulo A/D exibindo resultado no LCD Exemplo 3c - conjunto formado por dois experimentos envolvendo a comunicao USB. (1)Obs: Vlidos somente para o microcontrolador PIC18F4550 Os descritivos funcionais dos exemplos USB seguem abaixo: Exemplo USB Device - CDC - Basic Demo Trata-se de uma demonstrao do uso das funes da classe CDC RS232. Depois de gravado, conecte na porta USB e durante a instalao aponte para a pasta Drive USB PIC18F4550.Usando o Hiperterminal do Windows, configure para a porta COM instalada. Pressionando o boto S3 aparecer a mensagem Button Pressed --. Digitando um caractere, retornar ao terminal o caractere seguinte (por exemplo, se voc digitou o 'a', aparecer 'b'). Exemplo USB Device - HID Mouse Este exemplo uma demonstrao do uso das funes da classe HID. Este exemplo emula um mouse. Ao pressionar o boto S4 o cursor do mouse ficar "em crculo". Pressionando novamente o boto S4, o cursor voltar ao normal. Os dois exemplos esto includos na pasta de exemplos do microcontrolador PIC18F4550.
271
Esquema Eltrico
Placa principal
272
Placa de experincias
Placa de experincia
273
274
Cdigo
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * EXP03a * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ESTE EXEMPLO FOI ELABORADO PARA DEMONSTRAR O FUNCIONAMENTO DO CONJUNTO DE CHAVES DIP-SWITCH PRESENTES NA PLACA EXP03. CADA CHAVE ACIONADA COMANDA O ESTADO DE UM LED ASSOCIADO AO PORTD DO MICROCONTROLADOR. */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) -> -> -> -> -> -> -> ON OFF OFF ON ON ON ON
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1 USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF
275
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned char leds_temp = 0; unsigned char chaves_temp = 0; unsigned char i = 0; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
* * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define C_LEDS LATAbits.LATA4
//PINO PARA ATIVAR BARRA DE LEDS //1 -> BARRA ATIVADA //0 -> BARRA DESATIVADA
#define CHAVES
PORTD
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main { PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE () = = = = = 0x00; 0x00; 0x00; 0x00; 0x00; //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa //Limpa PORTA PORTB PORTC PORTD PORTE PORTA PORTB PORTC PORTD PORTE
= = = = =
276
= = = = =
// Desabilita a a barra de leds associada ao // aos pinos do PORTD // Configura PORTD do microcontrolador como // entrada // Atraso para acomodao do PORT // Realiza leitura de todas as chaves // e armazena na varivel auxiliar // Atraso para acomodao do PORT // Configura PORTD do microcontrolador como // sada // Atraso para acomodao do PORT // Realiza escrita no PORTD do valor // correspondente as chaves acionadas // Desabilita a a barra de leds associada ao // aos pinos do PORTD // Atraso para exibio dos valores das chaves // atravs da barra de leds
TRISD = 0xFF;
C_LEDS = 1;
Delay1KTCYx(1); } }
277
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Exemplo de Cdigo para utilizao com a McMaster * * EXP03b * * * * LABTOOLS - MOSAICO DIDACTIC DIVISION * * * * TEL: (0XX11) 4992-8775 SITE: www.labtools.com.br * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * VERSO : 1.0 * * DATA : 18/01/2010 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Descrio geral * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* ESTE EXEMPLO FOI ELABORADO PARA DEMONSTRAR O FUNCIONAMENTO DO POTENCIOMETRO DIGITAL PRESENTE NA PLACA EXP03. CADA CHAVE ACIONADA DETERMINA UM VALOR DE RESISTNCIA DO POTENCIOMETRO DIGITAL ALTERANDO A TENSO DE REFERNCIA MEDIDA CONTINUAMENTE PELO CONVERSOR A/D EXIBIDA NO LCD. */ /* CONFIGURAO DOS JUMPERS DA PLACA: CAP USB(RC3) DATA I2C CLOCK I2C COLUNA 2(RB1) COLUNA 1(RB0) LINHA 1 / DISPLAY MILHAR(RB4) LEDS ESPECIAS (RC0,RC1,RC2) /* CONFIGURAO DOS JUMPERS DA EXP03: J1 J2 J3 J4 */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * DEFINIO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include <p18F4550.h> // Register definitions -> -> -> -> POSIO POSIO POSIO POSIO 1,2 2,3 1,2 1,2 -> -> -> -> -> -> -> ON OFF OFF ON ON ON OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * INCLUDES DAS FUNES DE PERIFRICOS DO PIC * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #include #include #include #include #include #include #include <pwm.h> <adc.h> <timers.h> <delays.h> <i2c.h> <stdlib.h> <usart.h> //PWM library functions //ADC library functions //Timer library functions //Delay library functions //I2C library functions //Library functions //USART library functions
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Configuraes para gravao * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma #pragma config config config config config config config config config config config FOSC = HS CPUDIV = OSC1_PLL2 WDT = OFF WDTPS = 128 LVP = OFF PWRT = ON BOR = OFF BORV = 0 PBADEN = OFF DEBUG = OFF PLLDIV = 1
278
USBDIV = 1 FCMEN = OFF IESO = OFF VREGEN = OFF MCLRE = ON LPT1OSC = OFF CCP2MX = ON STVREN = OFF ICPRT = OFF
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Definio e inicializao das variveis Globais * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ //Neste bloco esto definidas as variveis globais do programa. unsigned unsigned unsigned unsigned unsigned unsigned unsigned char leds_temp = 0; char chaves_temp = 0; int i = 0; char unidade; char dezena; char centena; char milhar;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 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.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTIPAGEM DE FUNES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter); void escreve_lcd(unsigned char caracter); void limpa_lcd(void); void inicializa_lcd(void); void escreve_frase(const rom char *frase); void escreve_pot( unsigned char dado ); unsigned char le_pot(void); /* * * * * * * * * * * * * * * * * * * * * // As entradas devem //futuras alteraes * * * * * * * * * * * * * * * * * * * * * * * * * * ENTRADAS * * * * * * * * * * * * * * * * * * * * * * * * * * ser associadas a nomes para facilitar a programao do hardware. * * */ e
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //As sadas devem ser associadas a //futuras alteraes do hardware. #define C_LEDS LATAbits.LATA4
//PINO PARA ATIVAR BARRA DE LEDS //1 -> BARRA ATIVADA //0 -> BARRA DESATIVADA
PORTD LATCbits.LATC0 LATAbits.LATA2 //PINO CS DO POTENCIOMETRO DIGITAL //PINO SCK DO POTENCIOMETRO DIGITAL
279
LATAbits.LATA5 PORTEbits.RE0
//PINO SDI DO POTENCIOMETRO DIGITAL // via do lcd que sinaliza recepo // de dados ou
PORTEbits.RE1
// enable do lcd
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina para escrita de dado serial (SPI por software) * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_pot( unsigned char dado ) { unsigned char mascara; mascara = 0x80; SCK_POT = 1; do { SCK_POT = 0; if( dado & mascara ) SDO_POT = 1; else SDO_POT = 0; SCK_POT = 1; mascara >>= 1; } while( mascara ); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um COMANDO para o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void comando_lcd(unsigned char caracter) { rs = 0; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1 ; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina que envia um DADO a ser escrito no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_lcd(unsigned char caracter) { rs = 1; // seleciona o envio de um comando PORTD = caracter; // carrega o PORTD com o caracter enable = 1; // gera pulso no enable Delay10TCYx(1); // espera 10 microsegundos enable = 0; // desce o pino de enable Delay10TCYx(4); // espera mnimo 40 microsegundos } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para limpar o LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void limpa_lcd(void) { comando_lcd(0x01);
// limpa lcd
280
Delay1KTCYx(2); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Display de LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void inicializa_lcd(void) { comando_lcd(0x30); Delay1KTCYx(4); comando_lcd(0x30); Delay10TCYx(10); comando_lcd(0x30); comando_lcd(0x38); limpa_lcd(); comando_lcd(0x0c); comando_lcd(0x06); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo para escrever uma frase no LCD * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void escreve_frase(const rom char *frase) { do { escreve_lcd(*frase); }while(*++frase); } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * FUNO PARA SEPARAR DGITOS * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void converte_bcd(unsigned char aux) { unidade = 0; dezena = 0; centena = 0; milhar = 0; if (aux == 0)return; //SE AUX. FOR IGUAL A ZERO, SAI while(aux--) { unidade++; if(unidade != 10)continue; unidade = 0; dezena++; if (dezena != 10)continue; dezena = 0; centena++; if (centena != 10)continue; centena = 0; milhar++; if (milhar != 10)continue; milhar = 0; } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Funo Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void main () {
// 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
281
PORTA PORTB PORTC PORTD PORTE LATA LATB LATC LATD LATE
= = = = =
= = = = =
0x00; 0x00; 0x06; 0x00; 0x00; 0b11001011; 0b00001111; 0b10111000; 0b00000000; 0b00000100;
//Limpa PORTA //Limpa PORTB //Liga as sadas para tenso de referncia //Limpa PORTD //Limpa PORTE //CONFIG //CONFIG //CONFIG //CONFIG //CONFIG DIREO DIREO DIREO DIREO DIREO DOS DOS DOS DOS DOS PINOS PINOS PINOS PINOS PINOS PORTA PORTB PORTC PORTD PORTE
= = = = =
ADCON1 = 0b00001100; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Inicializao do Sistema * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ Delay10KTCYx(10); OpenADC(ADC_FOSC_8 & ADC_LEFT_JUST & ADC_0_TAD, ADC_CH1 & ADC_INT_OFF & ADC_VREFPLUS_VDD & ADC_VREFMINUS_VSS,12); inicializa_lcd(); // Inicializao do potenciometro digital SCK_POT = 1; CS_POT = 1; Delay10KTCYx(10); CS_POT = 0; // Escrita em TCON, D8 = 1 escreve_pot(0b01000001); // R1HW = 1, R1A = 1, R1W = 1, R1B = 1, R0HW = 1, R0A = 0, R0W = 1, R0B = 1 escreve_pot(0b11111011); // Escrita em Wiper 0 escreve_pot(0b00000000); // P0W = P0B (curto) -> U3A torna-se seguidor de tenso escreve_pot(0b00000000); // Escrita em Wiper 1 escreve_pot(0b00010000); // P1W = P1B (curto) -> Terminal + de U3A igual 2,5 Volts escreve_pot(0b00000000); CS_POT = 1; /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Rotina Principal * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ while(1) { C_LEDS = 0;
// Desabilita a a barra de leds associada ao // aos pinos do PORTD // Configura PORTD do microcontrolador como // entrada // Atraso para acomodao do PORT // Realiza leitura de todas as chaves
TRISD = 0xFF;
282
// e armazena na varivel auxiliar CS_POT = 0; // Escrita em Wiper 1 escreve_pot(0b00010000); // P0W = valor binrio das chaves (Rs = chaves/256), divisor entre 5 2,5 Volts escreve_pot(leds_temp); CS_POT = 1; Delay1KTCYx(1); TRISD = 0x00; // Atraso para acomodao do PORT // Configura PORTD do microcontrolador como // sada // Atraso para acomodao do PORT // Realiza escrita no PORTD do valor // correspondente as chaves acionadas // Desabilita a a barra de leds associada ao // aos pinos do PORTD // Atraso para exibio dos valores das chaves // atravs da barra de leds
C_LEDS = 1;
Delay1KTCYx(1);
ConvertADC(); //Inicia converso AD if(BusyADC()) { converte_bcd((((unsigned int)ADRESH*50)/256)); c omando_lcd(0xC6); // posiciona o cursor na linha 2, coluna 7 escreve_lcd escreve_lcd escreve_lcd escreve_lcd } } }Exemplo placa de experincia EXP04 (dezena + 0x30); (','); (unidade + 0x30); ('V');
283
Para a utilizao dos exemplos USB, a disposio dos jumpers da McMaster deve ser a seguinte: CAP USB DATA I2C CLOCK I2C COLUNA 2 RB0 COLUNA 1 RB0 LINHA 1 LEDS ESPECIAIS -> -> -> -> -> -> -> Posio OFF Posio ABERTO Posio ABERTO Posio ON Posio ON Posio ON Posio ON
284
Descrio
Esta placa de experincia no possui um cdigo exemplo especfico pois uma placa de prototipagem que permite acesso a todos os pinos do microcontrolador conectado ao McMaster. Obs: (1) O usurio deve levar em considerao as caractersticas eltricas dos pinos do microcontrolador utilizado visando obter uma interface segura entre o seu prottipo e o McMaster. Consulte sempre o datasheet do dispositivo antes de efetuar qualquer tipo de interligao.
285
286
287
288
289
290
291
292
293
294
295
296
297
Pino 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
Funo Funo 30F2012 30F3013 30F3010 30F4012 especial MCLR MCLR MCLR MCLR MCLR RB0 RB0 RB0 RB0 RB1 RB1 RB1 RB1 RB2 RB2 RB2 RB2 RB3 RB3 RB3 RB3 RB4 RB4 RB4 RB4 RB5 RB5 RB5 RB5 Vss Vss Vss Vss GND OSC1 OSC1 OSC1 OSC1 OSC1 RC15 RC15 RC15 RC15 OSC2 RC13 RC13 RC13 RC13 RC14 RC14 RC14 RC14 Vdd Vdd Vdd Vdd VCC RD9 RD9 RD1 RD1 RD8 RD8 RD0 RD0 RF6 RF6 RE8 RE8 RF3 RF3 RF3 RF3 PGD RF2 RF2 RF2 RF2 PGC Vss Vss Vss Vss GND Vdd Vdd Vdd Vdd VCC RF5 RF5 RE5 RE5 RF4 RF4 RE4 RE4 RB9 RB9 RE3 RE3 RB8 RB8 RE2 RE2 RB7 RB7 RE1 RE1 RB6 RB6 RE0 RE0 AVss AVss AVss AVss GND AVdd AVdd AVdd AVdd VCC
DsPICs 18 pinos
Pino 1 2 3 4 5 6 7 8 9 10 11 12 13 14 298
Funo Funo 30F2011 30F3012 especial MCLR MCLR MCLR RB0 RB0 RB1 RB1 RB2 RB2 RB3 RB3 OSC1 OSC1 OSC1 RC15 RC15 OSC2 RC13 RC13 RC14 RC14 RD0 RD0 RB4 RB4 PGD RB5 RB5 PGC Vss Vss GND Vdd Vdd VCC
15 16 17 18 Sugesto do adaptador:
GND VCC
Pinagem do RJ12: Conector RJ12 Pino 6 5 4 3 2 1 Vista do componente: Funo No usado GND Vdd PGC PGD MCLR
Frontal
Lado da solda
299
A LabTools garante contra defeitos de fabricao durante 4 meses para mo de obra de conserto. O prazo de garantia comea a ser contado a partir da emisso do pedido de venda.
2. Condies de Garantia
Durante o prazo coberto pela garantia, LabTools far o reparo do defeito apresentado, ou substituir o produto, se isso for necessrio. Os produtos devero ser encaminhados LabTools, devidamente embalados por conta e risco do comprador, e acompanhados deste Certificado de Garantia sem emendas ou rasuras e da respectiva Nota Fiscal de aquisio. O atendimento para reparos dos defeitos nos produtos cobertos por este Certificado de Garantia ser feito somente na LabTools, ficando, portanto, excludo o atendimento domiciliar.
3. Excluses de Garantia
Esto excludos da garantia os defeitos provenientes de: Alteraes do produto ou dos equipamentos. Utilizao incorreta do produto ou dos equipamentos. Queda, raio, incndio ou descarga eltrica. Manuteno efetuada por pessoal no credenciado pela LabTools. Obs.: Todas as caractersticas de funcionamento dos produtos LabTools esto em seus respectivos manuais.
4. Limitao de Responsabilidade
A presente garantia limita-se apenas ao reparo do defeito apresentado, a substituio do produto ou equipamento defeituoso.Nenhuma outra garantia, implcita ou explcita, dada ao comprador.
300
A LabTools no se responsabiliza por qualquer dano, perda, inconvenincia ou prejuzo direto ou indireto que possa advir de uso ou inabilidade de se usarem os produtos cobertos por esta garantia. A LabTools estabelece o prazo de 30 dias ( a ser contado a partir da data da nota Fiscal de Venda) para que seja reclamado qualquer eventual falta de componentes. Importante: Todas as despesas de frete e seguro so de responsabilidade do usurio, ou seja, em caso de necessidade o Cliente responsvel pelo encaminhamento do equipamento at a Labtools.
301