Sari la conținut
ELFORUM - Forumul electronistilor

Viteza maxima de achizitie ADC PIC18F2550,PIC18F4550


Postări Recomandate

Pai cand ai aliniere la dreapta faci adread = ADRESL (citesti numai registrul L) *), cand e cu aliniere la stanga adread = ADRESH (citesti numai registrul H).

Nu citesti acelasi registru si la alinierea la stanga, si la alinierea la dreapta.

Si ce rost au intarzierile de 100 us? Daca tot le folosesti, atunci intre ADCON0.GO_DONE = 1 si citirea registrilor, pe post de "timp de achizitie".

Desi mai bine testezi ADCON0.GO_DONE. Conversia e gata cand ADCON0.GO_DONE = 0.

 

Ceva de genul

ADCON0.GO_DONE = 1

while ADCON0.GO_DONE = 1
  ' nu fa nimic,
wend

*) Nu prea are sens sa citesti numai ADRESL, ca-s bitii 7..0, pierzi prea multa informatie. E pentru "simetrie", dar mai bine folosesti varianta initiala - citesti toti cei 10 biti si-i arunci pe ultimii doi.

Editat de Liviu M
Link spre comentariu

Intirzierea ajuta simularea din Proteus sa nu intre in erori.

Pina acum nu am imbunatatit cu nimic viteza de achizitie, desi am facut vreo 100 de teste diverse

Am intrat intr-un hatis de setari care impun o renuntare deocamdata, la idea topicului.

Va multumesc pentru amabilitate, dorinta de a ajuta si competenta.

 

@gsabac

Link spre comentariu

Sunteti deosebit de pregatit si amabil, ati fost numai de ajutor, dar este clar ca nu se poate obtine o imbunatatire.

Nu m-ati deranjat cu nimic si din contra m-ati incurajat. Am pe forumuri vreo 1800 de postari constructive si nimic

pentru a adauga postari fara valoare. Cu topicul am invatat setari pina in inima uC-ului si pentru asta sunt foarte multumit.

Incurajarea lui @thunderer de acum vreo luna a fost inceputul si a Dvs. din acest topic de a continua.

In notele de la Microchip, Mikroe sau internet nu sunt decit descrieri si aplicatii normale pe care le-am realizat si eu cu succes.

 

Spor !

 

@gsabac

Link spre comentariu

Am rezolvat problema mea, cu viteza maxima de achizitie pentru ADC-ul intern al uC-ului PIC18F2550 si a celorlalte PIC-uri.
Programele din Mikroe sunt foarte bune, ca si functiile de citire a datelor sub orice forma. Programul de simulare Proteus are
citeva setari pentru ADC-ul intern, care trebuiesc modificate din "Default" la timpi mai mici, asa cum am gasit pe un site:
"But if i change "Adc Minimum Acquisition Time" from Proteus (that is in chip properties and advance properties) that was default 20u,
i set it 1u to 21u, these all values working ok,but as soon as this value increase 21u , same error appear there in simulation log."

Acum programul receptioneaza date la frecventa de esantionare de 40KHz, deci se poate vizualiza corect 10-15KHz,

cu componenta continua, calibrare si diverse scale si timpi de baleaj.

post-238209-0-52834500-1496245830_thumb.jpg

Realizat fizic, semnalul vizualizat cu aspect grafic bun (cu ferestre Hamming) va urca la circa 25KHz.

 

@gsabac

Editat de gsabac
Link spre comentariu

Nu sunt complet in problema, dar se incearca combinarea a 2 octeti intr-un word? Cer scuze daca scriu aiurea la subiect.

Word=adresh×256+adresl

Word=adresh<<8+adresl

Dupa mai multe cautari si probe am rezolvat si problema truncherii semnalului aratat in postarea #28.

Pur si simplu compilatorul nu stie sa lucreze cu numere "byte" convertite la intregi in relatii matematice.

Relatia Word=adresh×256+adresl nu este interpretata corect de compilator si truncheaza primii 4 biti pe care ii face "0".

O conversie buna am realizat cu numere "integer" si urmatorul cod:

ADC_Init()

Delay_ms(200)

HID_Enable(@readbuff,@writebuff) 'Enable HID communication

Delay_ms(200)

while TRUE ' USB servicing is done inside the while loop

USB_Polling_Proc() ' Call this routine periodically

for i=0 to 64

ADCON0.GO_DONE = 1 'start ADC 'adread = (ADC_get_sample(0)/4)sau (ADC_Read(0)/4 )

adcVal = ADRESH * 256 'adcVal = (ADRESH * 256 + ADRESL) / 4 relatie gresita ptr mikroBasic

adcVal = (adcVal + ADRESL)/ 4 'intreg

writebuff = adcVal 'conversie implicita la byte

next i

HID_Write(@writebuff[0],64)

wend

Variabila intermediara "adcVal" declarata "integer" ia valoarea corecta la inmultirea cu 256 dar si suma (adcVal + ADRESL).

Ca rezultat pe ecranul osciloscopului sinusoida arata ca si cu functiile predefinite ADC_get_sample si ADC_Read.

Pe mine ma intereseaza aceasta separare LOW si HIGH pentru a transmite prin USB un "stream" care in final

sa realizeze esantioane cu +/-512 nivele.

 

@gsabac

Editat de gsabac
Link spre comentariu
  • 2 săptămâni mai târziu...

Viteza maxima de achizitie a ajuns la maturitate (70KHz) si aplicatia s-a maturizat si arata asa:

post-238209-0-08172500-1497178865_thumb.png

Am trecut la faza 2 care presupune achizitia mai indelungata de date, deoarece PIC18F2550 nu are decit 2K x 8
si aceia ciuntiti, prin alocarea a 2 bancuri pentru lucrul tampon USB. Programul poate aloca pentru variabile
2 zone de circa 900 Bytes. In faza actuala am folosit doar zona 1 cu 964 / 2 de esantioane,

cu programul urmator. Merge oarece si cu extensia zonei 2 figurate ca program cu verde,

si se poate mari numarul de esantioane (10biti, 2-byte) la circa 850, dar este foarte putin

pentru vizualizarea frecventelor joase.

 

dim readbuff as byte [64] 'absolute 0x500 ' Buffers should be in USB RAM

‘ please consult datasheet

'dim writebuff as byte[64] 'absolute 0x540 Blocul2 asignat USB

dim writebuff as byte [974] ' max 976

'dim writebuff1 as byte [832]

'***********'adread = (ADC_get_sample(0)/4) '(ADC_Read(0)/4 )****

for i=1 to 964 step 2 ' 1784 step 2 '1806 step 2

'if i<= 964 then

ADCON0.GO_DONE = 1 'start ADC

for j=1 to nCicle ‘intirziere

next j

writebuff=ADRESH

writebuff[i+1]=ADRESL

'end if

'next i

'else

'ADCON0.GO_DONE = 1 'start ADC

' Delay_us(10)

'writebuff1[i-964]=ADRESH

' writebuff1[i+1-964]=ADRESL

'end if

next i

HID_Write(@writebuff[0],64) 'salva1 de la Blocul1

'***********************************************************

for j=1 to 14 'salva2 la salva14 de la Blocul1

Delay_us(100)

for i = 1 to 61 step 2

writebuff=writebuff[i + 62 * j] '63 la 123 , etc

writebuff[i+1]=writebuff[i+1 + 62 * j] '64 la 124

next i

HID_Write(@writebuff[0],64)

next j

 

' HID_Write(@writebuff1[0],64) 'salva1 de la Blocul2

' for j=1 to 6 'salva2 la salva6 Blocul2

' Delay_us(10)

' for i = 1 to 61 step 2

' writebuff=writebuff1[i + 62 * j] '63 la 123 , etc

' writebuff[i+1]=writebuff1[i+1 + 62 * j] '64 la 124

' next i

' HID_Write(@writebuff[0],64)

' next j

'******************* Total 1784/2 esantioane de 10 biti*********

end if

Ar fi utila o extensie de memorie de vreo 32K x 8 in care sa scriu datele provenite din ADC-ul intern si apoi

trimiterea lor prin USB spre PC.

Am tradus unele observatii utile cu privire la alocarea memoriei pentru USB-HID, pentru PIC.

 

Pe scurt: asigurati-va ca utilizarea RAM nu este mai mare de 1024 octeti
Daca utilizati mai mult de 4 x 256 octeti (bancuri de la 0 la 3), compilatorul va începe alocarea
variabilele bancurilor de la 4 la 7. Bancurile 4 pâna la 7 sunt împartite cu modulul USB.
Sectiunea 5.3.1 din fisa tehnica spune:
"Teoretic este posibil sa se utilizeze zonele de memorie USB RAM
care nu sunt alocate ca tampoane USB pentru normal,
memoria scratchpad sau alta stocare variabila.
In practica, natura dinamica a alocarii tamponului face acest lucru
riscant în cel mai bun caz. În plus, Bancul 4 este utilizat pentru tampon USB,
atunci când modulul este activat si ar trebui sa nu fie folosit în alte scopuri în acel moment"

 

@gsabac

Link spre comentariu

Ce mi-e for ce mi-e while. Daca preferi, se poate inlocui while-ul cu un for. :)

Si nu, nu vad nici o problema cu bucla in bucla. Asta nu inseamna ca nu sunt probleme, ci ca nu-mi dau eu seama de ce ar fi. Poti detalia la ce te gandesti?

 

Daca ma gandesc mai bine, ar fi un motiv pentru folosirea unei temporizari fixe - asigurarea unei distante egale intre esantionare, ca sa iasa o frecventa de esantionare "controlata". Dar fara legatura cu "bucla in bucla".

Link spre comentariu

Multumesc pentru idei, nCicle este o variabila care schimba frecventa de esantionare. Ea este setata din baza de timp

de pe PC si este transmisa PIC-ului in felul urmator:

 

while TRUE ' USB servicing is done inside the while loop

USB_Polling_Proc() ' Call this routine periodically

nCicle = 6 '6 cicluri da cam ca 10uS intirziere Fes=75KHz

'78 cicluri da Fes=7,5KHz si se poate vizualiza 100Hz

ida = HID_Read()

if (ida <> 0) then

if readbuff[0] = ("F") then

readbuff[0] = 48 ' se aduce la zero

if readbuff[1] = 1 then ' 6 cicluri echivaleaza cu 10uS =>75KHz

nCicle = 6

end if

if readbuff[1] = 2 then

nCicle = 78 ' 78 cicluri echivaleaza cu 100uS => 7,5KHz

end if

if readbuff[1] = 3 then

nCicle = 680 ' 680 cicluri echivaleaza cu 1mS

end if

if readbuff[2] = 1 then 'amplificare globala cu 10

TRISB.RB0 = 1

end if

if readbuff[2] = 0 then 'amplificare globala cu 1

TRISB.RB0 = 0

end if

if readbuff[3] = 1 then 'AC

TRISB.RB1 = 1

end if

if readbuff[3] = 0 then 'DC

TRISB.RB1 = 0

end if

if readbuff[4] = 0 then ' amplificare x1

TRISB.RB2 = 0

end if

if readbuff[4] = 1 then ' amplificare x10

TRISB.RB2 = 1

end if

end if

'***********'adread = (ADC_get_sample(0)/4) '(ADC_Read(0)/4 )****

Codul in continuare este postat anterior.

Nu am gasit o alta idee mai buna pentru schimbarea freventei de achizitie. Micsorarea acestei frecvente determina

un timp mai mare si se pot vizualiza si frecvente mai joase.

 

@gsabac

Editat de gsabac
Link spre comentariu

Multumesc pentru idei, nCicle este o variabila care schimba frecventa de esantionare. Ea este setata din baza de timp

Da, dupa ce am postat ideea cu while m-am gandit si eu ca o temporizare fixa ajuta uneori.

Editat de Liviu M
Link spre comentariu

Secventa de sincronizare la un DSO se poate face in mai multe moduri, la viteza maxima de achizitie a PIC-ului:

- Inainte de achizitia datelor prin metoda comparatorului analogic al uneia din intrarile PIC-ului sau digitala

prin soft cu o rutina executata inainte de achizitie ca mai jos:

post-238209-0-34416300-1497765739_thumb.png

Variabilele Vsincro, pragul de sincronizare si sensSincro, sensul frontului sunt transmise prin USB.

Comparatia se face numeric, dupa care se initiaza rutina de achizitie a datelor, la tensiunea Vsincro si

ca rezultat se obtine in final pe PC, o sincronizare la +/-2 pasi.

- Sincronizarea la receptia datelor in PC presupune pierderea pina la o intreaga perioada a semnalului

si este fezabila doar atunci cind achizitia are extrem de multe date. De exemplu la un alt model de DSO

am folosit intre 6800 si 2 milioane de esantioane de 16biti, dar la PIC am maximum 465 de esantioane,

de aceea am folosit metoda inainte de achizitie

Sunt oarece multumit de rezultat, dar as dori sa experimentez sincronizarea cu ajutorul unuia dintre comparatorii

analogici de la intrarile PIC-ului, poate reduc eroarea de sincronizare la +/- 1 pas.

Care ar fi setarile pentru selectarea unei intrari de comparator si ca iesirea sa comande achizitia.

 

@gsabac

Link spre comentariu

Care ar fi setarile pentru selectarea unei intrari de comparator si ca iesirea sa comande achizitia.

Asta e intrebare?

Pentru ca lipsesc detaliile despre proiect, e greu de dat un raspuns exact.

Eu:

- as face CMCON = &H01 - One Independent Comparator with Output. Iesirea n-as folosi-o, dar nu exista variante cu un singur comparator si fara iesire

- as conecta RA0 la un potentiomentru (cu capetele intre GND si VDD) pentru reglarea nivelului triggerului

- as conecta semnalul la RA3. Habar n-am daca se poate folosi acelasi pin si pentru achizitie. In caz ca da, as folosi RA3 si pentru achizitie.

- as sta intr-o bucla citind registrul CMCON (bitul 6, C1OUT) pana cand as detecta o schimbare in directia dorita (0->1 sau 1->0)

- as porni achizitia

 

Spor, suna din ce in ce mai interesant proiectul tau.

 

PS In codul din poza as folosi break in loc de goto.

Editat de Liviu M
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