O código fonte :
/* * Lendo temperatura com o CI LM35 * * Compilador : MPlabXC8 * Microcontrolador: 16F877A * Autor: aguivone * Versão: 1 * Data : 29 de dezembro de 2014 */ #include <stdio.h> #include <string.h> //para usar funçoes de string deve se adicionar este header #include <stdlib.h> #define _XTAL_FREQ 20000000 // cristal de 20 Mhz #include <xc.h> #include "16F_lcd.h" /////////////////////////////////////////////////////////configuraçôes////////////////////////////////////////////////// #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) ////////////////////////////////////////////////variaveis globais/////////////////////////////////////////////////////////// char caracter; bit flag_interrupcao = 0; ///////////////////////////////////////////////////interrupção////////////////////////////////////////////////////////////// void interrupt interrupcoes(void)//vetor de interrupção { if(ADIF) {//se interrupção do modulo analogico! ADIF = 0;//limpa flag } } ///////////////////////////////////////funçoes usadas pelo conversor AD////////////////////////////////////////// void inicializa_ADC() { ADCON0 = 0X01;//Modulo ADC configurado para cristal de 20mhz(Fosc/2) e inicialmente lê a porta AN0/liga modulo de conversão ADCON1 = 0X82;//justificado a direita/habilita as portas de RA0 A RA4 } unsigned long ler_adc(int iPorta_analogica)//aqui se coloca qual porta analogica se quer usar { unsigned long ulTensao; //familia 18F e 16F ADCON0 = ((iPorta_analogica<<3) | (ADCON0& 0XC7)); ADCON0bits.GO = 1;//limpa conversão while(ADCON0bits.GO_DONE == 1); //espera finalizar leitura ulTensao = (ADRESH << 8) | ADRESL; if(ulTensao <= 1) { ulTensao = 0; } else { ulTensao = ulTensao/2 ; //agora é só corrigir a não linearidade do sensor if(ulTensao>24) { ulTensao--; } if(ulTensao>64) { ulTensao--; } if(ulTensao>103) { ulTensao = 100;//valor maximo aceitavel } } return(ulTensao); } void tela_inicial() { escolhe_pos_do_cursor(1,1);//linha 1 posiçao 1 imprime_LCD("Usando sensor de"); escolhe_pos_do_cursor(2,1);//linha 2 posiçao 1 imprime_LCD("temperatura LM35"); } void tela_principal() { escolhe_pos_do_cursor(1,1);//linha 1 posiçao 1 imprime_LCD(" Temperatura "); escolhe_pos_do_cursor(2,1);//linha 2 posiçao 1 imprime_LCD(" C "); } //////////////////////////////////////////////////////Rotina principal/////////////////////////////////////////////////////////////// void main(void) { TRISA = 0XFF;//o portA será entrada TRISB = 0X00;//configura portB como saida TRISD = 0X00;//todas são saidas TRISC = 0X80;//todas são saidas exceto C7(pino RX) TRISE = 0X00;//todas são saidas PORTB = 0; // limpar as portas que estão configuradas como saidas PORTC = 0; PORTD = 0; PORTE = 0; inicializa_ADC(); inicializar_LCD();//biblioteca lcd tela_inicial(); __delay_ms(5000); limpar_LCD(); tela_principal(); PEIE = 1;//habilita interrupção de perifericos do pic GIE = 1; //GIE: Global Interrupt Enable bit for(;;) { long_to_char_LCD(ler_adc(0),2,5);//lê porta AN0, e escreve na linha2 e posição 5 __delay_ms(1000);//espera 1 segundo para fazer nova atualização }//loop infinito }
O código fonte da biblioteca 16F_lcd.h:
//Biblioteca para fazer a comunicação com o display de LCD 16X2 //usando o modo 4 bits //testada com a familia PIC16F mas pode facilmente ser usada para outras familias de pic //configuracao dos pinos usado para comunicar com o display, onde os defines são os nomes dos pinos do display. #define RS RD2 #define EN RD3 //pinos de dados #define D4 RD4 #define D5 RD5 #define D6 RD6 #define D7 RD7 // //funçoes desta biblioteca // void Saida_LCD(char a) { if(a & 1) {D4 = 1;} else {D4 = 0;} if(a & 2) {D5 = 1;} else {D5 = 0;} if(a & 4) {D6 = 1;} else {D6 = 0;} if(a & 8) {D7 = 1;} else {D7 = 0;} } void comando_LCD(char a) { RS = 0; // => RS = 0 Saida_LCD(a); EN = 1; // => E = 1 __delay_ms(4); //tempo necessario para display reconhecer EN = 0; // => E = 0 } limpar_LCD() { comando_LCD(0); comando_LCD(1); } void escolhe_pos_do_cursor(char a, char b) { char temp,z,y; if(a == 1) { temp = 0x80 + b - 1; z = temp>>4; y = temp & 0x0F; comando_LCD(z); comando_LCD(y); } else if(a == 2) { temp = 0xC0 + b - 1; z = temp>>4; y = temp & 0x0F; comando_LCD(z); comando_LCD(y); } } void inicializar_LCD() { Saida_LCD(0x00); __delay_ms(20); comando_LCD(0x03); __delay_ms(5); comando_LCD(0x03); __delay_ms(11); comando_LCD(0x03); ///////////////////////////////////////////////////// comando_LCD(0x02); comando_LCD(0x02); comando_LCD(0x08); comando_LCD(0x00); comando_LCD(0x0C); comando_LCD(0x00); comando_LCD(0x06); } void escreve_caracter(char a) { char temp,y; temp = a&0x0F;//pega a parte baixa do byte y = a&0xF0;//pega parte alta do byte RS = 1; // => RS = 1 Saida_LCD(y>>4); //Envia a parte alta mas antes rotaciona 4 vezes EN = 1; __delay_us(40); EN = 0; Saida_LCD(temp);// envia a parte baixa EN = 1; __delay_us(40); EN = 0; } void imprime_LCD(char *a) { int i; for(i=0;a[i]!='\0';i++) escreve_caracter(a[i]); } void rotaciona_LCD_direita() { comando_LCD(0x01); comando_LCD(0x0C); } void rotaciona_LCD_esquerda() { comando_LCD(0x01); comando_LCD(0x08); } void long_to_char_LCD(unsigned long quant,int linha,int posicao)//valor, posicão inicial,linha a ser usada { char convert_char2='0'; char convert_char3='0'; char convert_char4='0'; escolhe_pos_do_cursor(linha,posicao);//linha 1 posiçao 1 if(quant <10) { convert_char2=' '; convert_char3=' '; } else { if(quant <100) { convert_char2=' '; } } while(quant>=100) { quant=quant-100; convert_char2++; } while(quant>=10) { quant=quant-10; convert_char3++; } while(quant>=1) { quant=quant-1; convert_char4++; } escolhe_pos_do_cursor(linha,posicao);//linha , posiçao escreve_caracter(convert_char2); escolhe_pos_do_cursor(linha,posicao+1);//linha , posiçao escreve_caracter(convert_char3); escolhe_pos_do_cursor(linha,posicao+2);//linha , posiçao escreve_caracter(convert_char4); }
A simulação do código:
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!