conversioni A/D multiple

Sezione dedicata all'elettronica in generale.
Rispondi
aduri
Junior
Junior
Messaggi: 106
Iscritto il: mercoledì 15 novembre 2006, 19:17
Località: Genova

conversioni A/D multiple

Messaggio da aduri » martedì 17 luglio 2007, 8:29

Spero di non essere OT ma ho provato, per la prima volta, a vedere come funziona il convertitore A/D del pic16f877a ed ha funzionato alla prima ma ho provato ad apportare delle modifiche al codice MiKrobasic (MKB) per avere la possibilita' di conversioni multiple ma non ha funzionato o per meglio dire funziona solo un canale e l'altro segue molto disturbato i valori del primo.
Il mio dubbio e' anche capire MKB cosa fa con i registri intco1 e intcon0 quando usa la macro ADC_read(2).

Qualcuno ha esperienze a proposito?
Allego il listato:

program adc2_lcd
'(*
' * Project name:
' adconlcd
' * Copyright:
' © mikroElektronika, 2005 - 2006
' * Revision History:
' 20050312:
' - initial release.
' * Description:
' This code demonstrates how to use library function ADC_read, and library
' procedures and functions for LCD display (4 bit interface)
' * Test configuration:
' MCU: PIC16F877A
' Dev.Board:
' Oscillator: HS, 4.000 MHz
' Ext. Modules: None
' SW: mikroBasic v5.0 or higher
' * NOTES:
' - If you are using EasyPIC4, use provided jumper on top right to connect potentiometer to RA2
' *)

dim ch1 as byte
ch2 as byte
t1 as word
t2 as word
Text1 as char[17]
Text2 as char[17]
tlong1 as longint
tlong2 as longint
main:
PORTB =0 ' clear portb
TRISB =0 ' designate portb as output (LCD is connected to portb)
intcon =0 ' disable all interrupts
Lcd_Init(PORTB) ' initialize (4-bit interface connection)
Lcd_Cmd( LCD_CURSOR_OFF) ' send command to LCD (cursor off)
Lcd_Cmd(LCD_CLEAR) ' send command to LCD (clear LCD)
Text1 ="A/D Aduri" ' assign text to string a
Lcd_Out(1,1, Text1) ' print string a on LCD, 1st row, 1st column
Text2 ="Prova" ' assign text to string a
Lcd_Out(2,1, Text2) ' print string a on LCD, 2nd row, 1st column
OPTION_REG = $80
ADCON1 = $82 ' configure VDD as Vref, and analog channels
TRISA = $FF ' designate porta as input
Delay_ms(2000)
Text1 = "voltage1:" ' assign text to string a
Lcd_Out(1,1,Text1) ' print string a on LCD, 2nd row, 1st column
Lcd_Chr(1,14,"V")
Text2 = "voltage2:" ' assign text to string a
Lcd_Out(2,1,Text2) ' print string a on LCD, 2nd row, 1st column
Lcd_Chr(2,14,"V")
while true
t1 = ADC_read(1) ' get ADC value from 1st channel
tlong1 = t1*5000
t1 = tlong1 >> 10
ch1 = t1 div 1000 ' prepare value for diplay
Lcd_Chr(1,11,48+ch1) ' write ASCII at first row, 9th column
Lcd_Chr(1,12,".")
ch1 = (t1 div 100) mod 10
Lcd_Chr(1,13,48+ch1)
ch1 = (t1 div 10) mod 10
Lcd_Chr(1,14,48+ch1)
ch1 = t1 mod 10
Lcd_Chr(1,15,48+ch1)
delay_ms(1)

t2 = ADC_read(2) ' get ADC value from 2nd channel
tlong2 = t2*5000
t2 = tlong2 >> 10
ch2 = t2 div 1000 ' prepare value for diplay
Lcd_Chr(2,11,48+ch2) ' write ASCII at 2nd row, 9th column
Lcd_Chr(2,12,".")
ch2 = (t2 div 100) mod 10
Lcd_Chr(2,13,48+ch2)
ch2 = (t2 div 10) mod 10
Lcd_Chr(2,14,48+ch2)
ch2 = t2 mod 10
Lcd_Chr(2,15,48+ch2)

delay_ms(1)
wend
end.


Cordiali saluti

Avatar utente
Steulm
Member
Member
Messaggi: 364
Iscritto il: venerdì 13 aprile 2007, 10:52
Località: Sabaudia (LT)
Contatta:

Messaggio da Steulm » martedì 17 luglio 2007, 18:12

Ciao Aduri,
per quanto riguarda le funzioni dei registri, puoi trovare le informazioni sul datasheet del micro. Comunque le operazioni di conversione vengono effettuate e gestite tramite i registri ADCON0 e ADCON1. Il primo gestisce le operazioni pratiche di conversione, mentre il secondo, serve a settare le porte da usare per le conversioni. Con MKB, tramite la macro ADC_READ(channel), ti devi preoccupare solamente del settaggio dei pin delle porte che vuoi utilizzare, come c'è sull'esempio che hai utilizzato, tramite la linea "ADCON1=$82" con la quale setti i pin da 0 a 5 della PORTA del micro, come Analog input (configure VDD as Vref, and analog channels), quindi vai a leggere il dato tramite la funzione ADC_READ(channel). Ricorda che ADC_READ(0) legge il valore della conversione sul pin RA0(AN0). Spero di esserti stato di aiuto.
Ciao, Stefano.

Giudica i tuoi successi dagli sforzi che hai fatto per raggiungerli.

aduri
Junior
Junior
Messaggi: 106
Iscritto il: mercoledì 15 novembre 2006, 19:17
Località: Genova

Messaggio da aduri » mercoledì 18 luglio 2007, 8:48

Ti ringrazio della risposta,
ma il listato che ho allegato, da come dici, dovrebbe funzionare e leggere i 2 segnali analogici dalla porta RA1 e RA2 ma ne legge correttamente solo uno.
Ho messo nel ciclo infinito While-wend ADC_read(1) e ADC_read(2) eppure non va.
Cortesemente potresti mettere nel post la parte di codice che fa la conversione multipla cosi' cerco di capire cosa non va?

Grazie

Avatar utente
Steulm
Member
Member
Messaggi: 364
Iscritto il: venerdì 13 aprile 2007, 10:52
Località: Sabaudia (LT)
Contatta:

Messaggio da Steulm » mercoledì 18 luglio 2007, 22:14

Scusa aduri, stai usando la easypic per caso?
Se si, sei sicuro di aver settato i jumper correttamente?
Perchè anche io sono partito dagli esempi di mikrobasic, e modificandoli non ho avuto problemi (uso la easypic4).
Ciao, Stefano.

Giudica i tuoi successi dagli sforzi che hai fatto per raggiungerli.

aduri
Junior
Junior
Messaggi: 106
Iscritto il: mercoledì 15 novembre 2006, 19:17
Località: Genova

Messaggio da aduri » giovedì 19 luglio 2007, 8:38

No purtroppo non la ho.
Ho una multipic board
http://multipic.elettronicamente.com/
con cui ho sempre fatto cose egregie anche perche' ti da un sacco di liberta' avendo praticamente tutti i pins accessibili.
L'unico settaggio che devi fare e quello che riguarda il tipo di processore e per l'abilitazione dell' RS232.
Con un solo canale in acquisizione non da problemi con piu' canali si'.
Probabilmente e' solo una sciocchezza a livello sw per questo motivo ti chiedevo se cortesemente potevi farmi vedere lo stralcio di programma che riguarda la conversione multipla magari riesco a capire dove e' l'inghippo.

ciao e grazie ancora

Avatar utente
Steulm
Member
Member
Messaggi: 364
Iscritto il: venerdì 13 aprile 2007, 10:52
Località: Sabaudia (LT)
Contatta:

Messaggio da Steulm » giovedì 19 luglio 2007, 19:42

Ok, questo è l'esempio che ho utilizzato, devi solo duplicare la routine di lettura e aggiustarlo per le tue esigenze. Io l'ho usato per la lettura su otto linee A/D (5 su PORTA e 3 su PORTE) del PIC16F877A e funziona.

program AdcOnLcd2

dim ch as byte
CurrentValue, LastValue as word
Text as char[10]
qqqq, rrrr as float


sub procedure WordToStrWithZeros2(dim input_ as word, dim byref output as char[4])
dim len_, tmp as byte

len_ = 1
if input_ > 9 then
Inc(len_)
end if
if input_ > 99 then
Inc(len_)
end if
if input_ > 999 then
Inc(len_)
end if
output = "0000" ' right justified
dec(FSR)
while len_ > 0
tmp = (input_ mod 10) + 48
INDF = tmp
dec(FSR)
input_ = input_ div 10
dec(len_)
wend
end sub

main:
PORTB = 0 ' clear portb
INTCON = 0 ' disable all interrupts
OPTION_REG = $80
ADCON1 = $82 ' configure VDD as Vref, and analog channels
TRISA = $FF ' designate porta as input

Lcd_Init(PORTD) ' initialize (4-bit interface connection)
Lcd_Cmd( LCD_CURSOR_OFF) ' send command to LCD (cursor off)
Lcd_Cmd(LCD_CLEAR) ' send command to LCD (clear LCD)
Lcd_Out(1,1,"mikroElektronika") ' print string a on LCD, 1st row, 1st column
Lcd_Out(2,1,"LCD example") ' print string a on LCD, 2nd row, 1st column
Delay_ms(2000)
Lcd_Out(2, 1, "voltage:") ' print string a on LCD, 2nd row, 1st column
Lcd_Chr(2, 15, "V") ' Write "V" out of the loop, since it never changes

LastValue = 0 ' Inititalize LastValue

while true

CurrentValue = ADC_read(2) ' get ADC value from channel No.2

if CurrentValue <> LastValue then ' perform conversion only if they are different

rrrr = CurrentValue*(5000.0/1024.0)' 5 Volts over 1024 levels (10-bit conversion)

CurrentValue = rrrr ' This assignment will convert float to word

WordToStrWithZeros2(CurrentValue, Text) ' Convert word to string with zeros (right justified)

Text[4] = Text[3] ' This sequence will
Text[3] = Text[2] ' insert the "." character
Text[2] = Text[1] ' just after the first char in Text.
Text[1] = "."
Text[5] = 0 ' The string always ends with 0

Lcd_Out(2, 9, Text) ' Write formatted text

LastValue = CurrentValue' Equalize them so next time we do not write the same value
end if
wend
end.
Ciao, Stefano.

Giudica i tuoi successi dagli sforzi che hai fatto per raggiungerli.

aduri
Junior
Junior
Messaggi: 106
Iscritto il: mercoledì 15 novembre 2006, 19:17
Località: Genova

Messaggio da aduri » venerdì 20 luglio 2007, 8:16

Grazie,
sei stato molto gentile provero stasera stessa.

Ciao

aduri
Junior
Junior
Messaggi: 106
Iscritto il: mercoledì 15 novembre 2006, 19:17
Località: Genova

Messaggio da aduri » lunedì 23 luglio 2007, 12:58

Niente da fare mi fa sempre lo stesso difetto anche con questo codice.
Con un solo ingresso funziona perfettamente con 2 analogiche ne funziona uno solo.

Avatar utente
tontillo
Junior
Junior
Messaggi: 142
Iscritto il: venerdì 9 febbraio 2007, 14:32
Località: sotto l'Etna

Messaggio da tontillo » martedì 24 luglio 2007, 12:44

vedo che sei testardo
Se leggi il datasheet ti accorgi che nel pic c'è UN SOLO convertitore.
Lo stesso convertitore ti legge tutte le porte.
Una volta effettuata la prima lettura da una porta, devi dare del tempo al convertitore affinchè si possa scaricare un condensatore interno.
Se non dai questo tempo otterrai piu o meno lo stesso valore alle letture successive su altre porte.
Quando cambi porta devi dare 10 microsecondi almeno di pausa.
E scordati la lettura contemporanea proprio perchè il convertitore è uno solo.

aduri
Junior
Junior
Messaggi: 106
Iscritto il: mercoledì 15 novembre 2006, 19:17
Località: Genova

Messaggio da aduri » mercoledì 25 luglio 2007, 8:38

Sono riuscito a risolvere e funziona. :D
Non avevo letto bene il datasheet :? che limitava il valore dell'impedenza d'ingresso ho sostituito i trimmer con valori piu' bassi.
X Tontillo lo so che il D/A e' unico ma e possibile multiplexarlo 8 volte quindi puoi leggere in contemporanea, se setti bene i registri INTCON0 e INTCON1, fino a 8 ingressi analogici.
Fino ad ora ho provato con 2 e funziona perfettamente.

Avatar utente
Steulm
Member
Member
Messaggi: 364
Iscritto il: venerdì 13 aprile 2007, 10:52
Località: Sabaudia (LT)
Contatta:

Messaggio da Steulm » mercoledì 25 luglio 2007, 21:12

=D> =D> =D>
E andiamo....

#-o #-o
Al valore dei trimmer non ci avevo proprio pensato... continuavo a dare per scontato che lavorassi con la easypic!!!
Comunque, meno male..... un problema in meno (tutta esperienza!!)
Ciao, Stefano.

Giudica i tuoi successi dagli sforzi che hai fatto per raggiungerli.

Rispondi

Torna a “Elettronica”