Sari la conținut
ELFORUM - Forumul electronistilor

Problema citire mai multe canale ADC 16f877a


ramsesrr

Postări Recomandate

Incerc sa citesc 8 canale ADC la 16f877a dar canalele se influenteza intre ele,adica daca pun 5V pe o intrare si pe restul le las in aer apare si pe ele 5V . In simulator totul e Ok insa practic nu .Care ar putea fi problema.Codul este urmatorul:

 

// PIC16F877a Sms controller// Hi-Tech C #include <pic.h>#include <htc.h>#include <stdio.h>#include <string.h>#include "stdlib.h"__CONFIG(HS & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN & DEBUGEN & UNPROTECT);#define _XTAL_FREQ 10000000ULbank1  char ReadBuffer[20]; volatile unsigned int i;void initialize(void)	{		GIE=1;				// enable interrupts	PEIE=1;           	//enable peripheral interrupt 	INTE = 0;			//intrerupere oprita pe RB0	RBIE=0;	TMR0IE=0;	ADCS1 = 1;		//select Fosc/8	ADCS0 = 1;	ADCON1=0b10000000;		// A/D port configuration 0	ADFM = 1;		//right justified result	ADON=1;			// turn on the AD conversion module			}/* return a 10-bit result */unsigned int read_adc(unsigned char channel){	channel&=0x07;			// truncate channel to 3 bits	ADON = 1;	ADCON0&=0xC5;			// clear current channel select	ADCON0|=(channel<<3);	// apply the new channel select	__delay_ms(10);	ADGO=1;					// initiate conversion on the selected channel	while(ADGO)continue;	ADON = 0;	return(((ADRESH&0x03)<<8)+ADRESL);	// return the 10-bit result}int temp_lm35(void){	int temp_an, temp, i;	temp_an=0;	for(i=0; i<4; i++)	{		temp_an =temp_an+read_adc(0);		__delay_ms(5);	}	temp_an=(temp_an/4);	temp = temp_an*(int)((5.0*100.0)/1023.0);	return(temp+1);}void InitUSART() //rutina de setare si initializare a modulului USART{		SPBRG=64;//(int)((F_CPU/(baund_rate*16))-1);		BRGH=1;		//high speed	SYNC=0;		//modul asincron	SPEN=1;		//activare port serial	TXIE=0;		//dezactivare intrerupere USART la transmisie	TX9=0;		//transmisie pe 8 biti	TXEN=1; 	//activare transmisie 	RCIE=1;		//activare intrerupere USART la receptie	RX9=0;		//receptie pe 8 biti	CREN=1; 	//activare receptie}void USARTWriteChar(unsigned char c)	//Rutina de transmitere a unui octet la portul serial{	while(!TXIF);	//asteapta sa se termine transmisia precedenta	TXREG=c;	//incarca si transmite noua valoare}void TransmitUSARTC(const char* c){	unsigned int i =0;	while(c[i]!=0x0 && c[i]!=0xd)	{		USARTWriteChar(c[i]);		i++;	}	//USARTWriteChar(0xd); //new line}unsigned char ReceiveUSART()	//Rutina pt receptia unui octet de la portul serial{	unsigned char c;								while(!RCIF);	//asteapta pana se incheie receptia	c=RCREG;	//octetul receptionat este preluat din RCREG		return c;	}/////////////////////////////////////////////////////////////////////////////////void Wait(unsigned int n){   unsigned int i,temp;   temp=n*10;   for(i = 0;i < temp ;i++)   {      __delay_ms(100);	}}//////////////////////////////////////////////////////////void interrupt isr(void){	GIE=0;	if(RCIF){	ReadBuffer[i++] = RCREG;    if(i>78) i = 0;		}	RCIF = 0;	GIE=1;}void Reset_RXBuff(void){        i = 0;        memset(ReadBuffer, 0, 75);}void main(void){	   int val1,val2,val3,val4;	char b [40];volatile unsigned char flag8 = 0;   	   	initialize();	PIE1|=(1<<RCIE);   	__delay_us(20);   	InitUSART();   	TRISA|=(1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<5);   	TRISE|=(1<<0)|(1<<1)|(1<<2);			TransmitUSARTC("start");		USARTWriteChar('\r');memset(ReadBuffer, 0, 75); //reset bufferi = 0; //reset pointer	while(1)	{unsigned int adc[8];unsigned int w = 0;			for(w = 0;w <=7; w++)		{		adc[w] = read_adc(w);		Wait(1);		} 			for(w = 0;w <=7; w++)		{		sprintf(b,"valoarea ADC pe canalul %d este : %d ",w,adc[w]);		TransmitUSARTC(b);		USARTWriteChar('\r');		memset(b,' ', 40);		}		TransmitUSARTC("#########################################");		USARTWriteChar('\r');	}		}
Link spre comentariu
  • Răspunsuri 3
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • ramsesrr

    2

  • XAN77

    1

  • Liviu M

    1

Top autori în acest subiect

Si ce motiv ar avea celelalte intrari sa faca altceva?Intrarile ADC sunt conectate prin rezistente la condensatorul sample/hold. In momentul in care il incarci pe ala (maqsurand prima intrare), restul intrarilor fiind in aer condensatorul n-are nici un motiv sa se descarce, asa ca atunci cand masori in continuare, regasesti aceeasi valoare pe el. *)Oricum, e bad practice sa lasi intrari in aer, ca nu mai poti controla comportamentul circuitului.*) Ia afirmatiile de mai sus cu putina circumspectie, ca sunt sanse sa fiu "pe langa".

Link spre comentariu

si de ce te surprinde asa tare comportamentul unui pin de date setat intrare care e in gol? Oricum asta nu e modul normal de a folosi un pin care este intrare. Folosestel cum trebuie si daca tot nu face ceea ce te astepti abia atunci iti pui intrebari. Cu un 10k la masa mai citeste AD-ul 5V pe acel pin?

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări