Vai al contenuto
PLC Forum


Usare L'a/d Del 16f876


Simons

Messaggi consigliati

Salve a tutti..

Ho in mente di costruire un piccolo voltmetro con 3 display a 7 segmenti e uno o due ingressi analogici per le misure...

utilizzerei la PORTC per i 7 segmenti, la PORTB per gli enable dei display e la PORTA per l'acquisizione..

mi serviva un chiarimento su come funziona l'A/D del pic..

in pratica in ingresso io ho una tensione (per es 0-5v) e il pic cosa mi restituisce? mi sembra che il 16f876 abbia 10 bit di conversione... è giusto?

grazie a tutti :)

Link al commento
Condividi su altri siti


Gli A/D converter della serie 16F87x possono essere usati a 8 e 10 bits. Se scarichi il tutor TUT87, che solitamente è usato come programma di prova per ICD1 e ICD2, hai un esempio facile di uso dell'A/D converter

Link al commento
Condividi su altri siti

a questo proposito vorrei chiedere un'altra cosa...

ho un pulsante collegato a un ingresso (RC4).. come faccio per "costruire" un latch antirimbalzo

via software?

premetto che il pulsante "chiude" a massa e quando è aperto c'è la resistenza di pull-up tra il +5v e l'ingresso RC4..

:)

Link al commento
Condividi su altri siti

Io uso sempre questo sistema. Ho un timer da 50ms, sull'interrpt leggo gli ingressi e metto lo stato in una memoria. Lo confronto con lo stato memorizzato alla lettura precedente, se sono uguali tengo buono lo stato, altrimenti attendo che i due stati coincidano. praticamente filtro tutti i rimbalzi entro 50ms.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

Salve...

ho imparato a gestire l'interrupt e il prescaler del TIMER0... però mi sfugge come confrontare gli ingressi con quello che c'era prima...

uso CCS C compiler...

:)

Link al commento
Condividi su altri siti

Qui trovi un esempio con CCS di uso del convertitore A/D; c'è anche la routine di conversione BCD e la parte di visualizzazione su un display a 3 cifre da 7 segmenti. Ignora quello che non ti interessa.

Per eseguire la comparazione.

Leggi l'ingresso e lo memorizzi in una variabile. Esegui XOR con la memoria dello stato precedente Se i due valori sono diversi, XOR == 1, memorizzi lo stato attuale nella memoria dello stato precedente.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

Salve avrei ancora un paio di chiarimenti da chiedere sull' AD

- Dunque il valore restituito dalla funzione read_adc() in che formato è? (intero, long, etc...)

- Quando vado a fare dei confronti con il valore dell'adc (per esempio if(read_adc()>341) ) anche se l'adc assume valore più grande di 341(in questo caso), l'if non viene eseguito..

Premetto che per provare i miei programmi uso un simulatore di pic che si chiama pic simulator IDE

grazie

simons

:)

Link al commento
Condividi su altri siti

Non hai letto gli esempi che ti ho postato? Le dichiarazioni chiariscono che è una long, nel formato CCS compiler. Poi basta leggere l'help in linea del CCS che ti chiarisce tutto, anche come funziona la conversione.

Io ti consiglio di usare MPLAB, che si scarica gratuitamente dal sito Microchip. Il compilatore CCS è perfettamente integrato con l'ambiente MPLAB basta configuralo e scaricare l'apposito plug in dal sito CCS.

Se il valore letto dall'A/D è, nel caso esemplificato, >341 l'IF viene eseguito.

Link al commento
Condividi su altri siti

Si ho letto gli esempi che mi hai passato, però ho notato che in questo punto:

 while (TRUE)
    {
        if (icnt_conv = 5)
            {
                icnt_conv = 0;
                sum = 0;
                for(i=0;i<5;++i)
                      {
                         delay_ms(10);
                        sum+=lrd_AD(i);
                       }
                conv = (sum/5);
            }

non c'è la funzione read_adc() che serve appunto per leggere l'adc...

com'è che viene letto in questo programma?

ps. scusa se sono così rompi*** però dovrei fare un progetto con un pic e sto imparando :rolleyes::)

Link al commento
Condividi su altri siti

Bhe non hai tutti i torti. Non ho incluso la routine sotto interrupt a tempo che legge l'A/D_C; sorry.

Nella routine a tempo si eseguono 5 letture consecutive del canale 0, completate le 5 misure il main esegue la media e la butta sul display

.............................
          1rd_AD(i) = read_adc(0);
....................................

In ogni modo leggi l'help in linea dell CCS: è tutto spiegato e ci sono anche i file di esempio.

Link al commento
Condividi su altri siti

Si ho guardato i files di esempio ed ho provato a fare una lettura.

A me serve una routine che converte l'intervallo dell'adc (se 8 bit è 0-255 se è 10 bit è 0-1023) in un intervallo da -50 a +100 e ho fatto una semplice funzione:

   
long tOut(long ad)
{
long OUTPUT,tmp;

   if(ADC<341) //se l'adc è minore di 341 la temperatura è sotto lo zero (341=0°C)
   {
      OUTPUT=abs((ad*(150/1023))-50);
//eseguo la conversione da 0-1023 a -50 a 100 
//prendendo il valore assoluto della conversione 
//e poi impostando un flag se è negativo o meno
      neg=1;
   }
   if(ADC>341) //se è maggiore di 341 allora è sopra lo zero
   {
      OUTPUT=abs((ad*(150/1023))-50);
      neg=0;
   }
return OUTPUT;
}

il fatto è che la funzione OUTPUT=abs((ad*(150/1023))-50) mi restituisce SEMPRE il valore 50. Quindi ho dedotto che la moltiplicazione (ad*(150/1023)) risulta sempre zero.. :unsure:

. :toobad:

Modificato: da Simons
Link al commento
Condividi su altri siti

Hai ragione! ma quindi dovrei usare dei float e poi riconvertirli in intero successivamente?

intendo al posto dei long dichiarare come float le variabili

Link al commento
Condividi su altri siti

certamente, Suprattutto stai attento all'ordine con cui moltiplichi e dividi con le costanti.

Link al commento
Condividi su altri siti

Ok ho risolto la conversione da AD a numero sul display .. ora visualizza tutto correttamente.

Però un paio di cose:

- Multiplexando i 3 display, non ho il refresh continuo, ma solo quando l'adc ha finito la conversione. C'è un modo per far si che quando l'adc sta convertendo il refresh ci sia comunque (sul valore precedente ovviamente) e quando ha finito la conversione mi cambi la visualizzazione e faccia il refresh continuo di nuovo? Ho provato a " nazzicare" con gli interrupts ma senza risultato :toobad:

- In ingresso al pin analogico RA0 ho un segnale variabile tra 0 e 5 volt. Configurando l'adc a 10 bit, vuol dire che a 1023 corrispondono 5 volt? è giusto come ragionamento?

grazie ancora dell'immenso aiuto!!!! ;)

Link al commento
Condividi su altri siti

Se analizzi il codice che ho postato vedi come ho risolto il problema: usando displies con latches. Puoi usare anche displaies normali con decodifica "latchata".

Altrimenti avrai sempre problemi sui diplaies, o ci sono sfarfallii o hai luninosità bassa sui displaies.

Si, se setti gli A/D a 10 bits avrai 5v divisi in 1023 passi.

Modificato: da Livio Orsini
Link al commento
Condividi su altri siti

scusami ma non capisco :(

Se analizzi il codice che ho postato vedi come ho risolto il problema: usando displies con latches. Puoi usare anche displaies normali con decodifica "latchata".
Link al commento
Condividi su altri siti

Come ti ho scritto nel post precedente, io uso displaies con decoder latchato. Uso 7 linee; 4 per i BCD e 3 per gli strobes ai latches. Nel mio caso ho usato displaies TL311(TIL311?), ma si possono usare dei 7 segmenti normali più decoder tipo CD4511. Questo integrato accetta 4 linee BCD, ha un ingresso di latch enable e pilota un display a 7 segmenti.

Link al commento
Condividi su altri siti

Crea un account o accedi per commentare

Devi essere un utente per poter lasciare un commento

Crea un account

Registrati per un nuovo account nella nostra comunità. è facile!

Registra un nuovo account

Accedi

Hai già un account? Accedi qui.

Accedi ora
×
×
  • Crea nuovo/a...