Há momentos em que precisamos ler vários canais analógicos (quase)ao mesmo tempo dai uma maneira de se fazer isso é chaveando as entradas analógicas, veja que os valores são lidos em milivolts.
O código fonte:
/*
* lendo 4 valores de tensão usando RS-232 no MPlab XC8
*
* Compilador : MPlabXC8
* Microcontrolador: 16F877A
* Autor: aguivone
* Versão: 1
* Data : 06 de outubro 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>
/////////////////////////////////////////////////////////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(RCIF)
{//se interrupção de recepção da serial
//aqui não será usado essa funcão
caracter = RCREG;
flag_interrupcao = 1;
RCIF = 0;// limpa flag de interrupção de recepção
}
if(ADIF)
{//se interrupção do modulo analogico!
ADIF = 0;//limpa flag
}
}
/////////////////////////////////funçoes usadas pela uart //////////////////////////////////////////////////////
void inicializa_RS232(long velocidade,int modo)
{////por padrão é usado o modo 8 bits e sem paridade, mas se necessario ajuste aqui a configuração desejada.
//verifique datasheet para ver a porcentagem de erro e se a velocidade é possivel para o cristal utilizado.
RCSTA = 0X90;//habilita porta serial,recepção de 8 bit em modo continuo,assincrono.
int valor;
if(modo == 1)
{//modo = 1 ,modo alta velocidade
TXSTA = 0X24;//modo assincrono,trasmissao 8 bits.
valor =(int)(((_XTAL_FREQ/velocidade)-16)/16);//calculo do valor do gerador de baud rate
}
else
{//modo = 0 ,modo baixa velocidade
TXSTA = 0X20;//modo assincrono,trasmissao 8 bits.
valor =(int)(((_XTAL_FREQ/velocidade)-64)/64);//calculo do valor do gerador de baud rate
}
SPBRG = valor;
RCIE = 1;//habilita interrupção de recepção
TXIE = 0;//deixa interrupção de transmissão desligado(pois corre se o risco de ter uma interrupção escrita e leitura ao mesmo tempo)
}
void escreve(char valor)
{
TXIF = 0;//limpa flag que sinaliza envio completo.
TXREG = valor;
while(TXIF ==0);//espera enviar caracter
}
void imprime(const char frase[])
{
char indice = 0;
char tamanho = strlen(frase);
while(indice < tamanho ) ///veja que o programa pode travar se aqui não tiver as duas aspas
{
escreve(frase[indice]);
indice++;
}
}
void long_to_char(unsigned long quant)
{
char convert_char1='0';
char convert_char2='0';
char convert_char3='0';
char convert_char4='0';
while(quant>=1000)
{
quant=quant-1000;
convert_char1++;
}
while(quant>=100)
{
quant=quant-100;
convert_char2++;
}
while(quant>=10)
{
quant=quant-10;
convert_char3++;
}
while(quant>=1)
{
quant=quant-1;
convert_char4++;
}
escreve(convert_char1);
escreve(convert_char2);
escreve(convert_char3);
escreve(convert_char4);
}
///////////////////////////////////////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_mv(int iPorta_analogica)//aqui se coloca qual porta analogica se quer usar
{
/*
* se for usar a familia 12F e este
*
unsigned long ultensao;
ADCON0 = (int iPorta_analogica<<2) | (ADCON0& 0XF3));
PIR1bits.ADIF = 0;//limpa flag
ADCON0bits.ADON = 1;//liga modulo de conversão
ADCON0bits.GO = 1; //inicia conversão
while (PIR1bits.ADIF == 0); //espera finalizar leitura
ultensao = (ADRESH << 8) | ADRESL;
ADCON0bits.ADON = 0;//desliga modulo de conversão
return(ultensao);
*/
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;
ulTensao =((ulTensao * 5000)/1023); //Vref está em milliVolts
return(ulTensao);
}
//////////////////////////////////////////////////////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_RS232(9600,1);//modo de alta velocidade
inicializa_ADC();
PEIE = 1;//habilita interrupção de perifericos do pic
GIE = 1; //GIE: Global Interrupt Enable bit
imprime("Voltimetro multiplo usando a serial! \n\r");
imprime("AN0 - AN1 - AN2 - AN3 \n\r");
for(;;)
{
long_to_char(ler_adc_mv(0));//lê porta AN0
escreve('-');//separador de leituras
long_to_char(ler_adc_mv(1));//lê porta AN1
escreve('-');//separador de leituras
long_to_char(ler_adc_mv(2));//lê porta AN2
escreve('-');//separador de leituras
long_to_char(ler_adc_mv(3));//lê porta AN3
escreve('\r');//retorna pro inicio da linha
escreve('\n');//pula linha
__delay_ms(1000);//espera 1 segundo
}//loop infinito
}
A simulação :
Curta a fan page do blog e tenha acesso as últimas postagem assim que publicadas!
Nenhum comentário :
Postar um comentário
olá,digite aqui seu comentário!