Sari la conținut
ELFORUM - Forumul electronistilor

Viteza maxima de achizitie ADC PIC18F2550,PIC18F4550


gsabac

Postări Recomandate

Librariile erau bifate, am introdus asa cum ati spus si ADC_Init() in combinatie cu ADC_get_sample(0) si blocheaza USB.

Arata ca se conecteaza, dar cind cer validarea device-lui nu merge identificarea prin ID.

Mai este ceva de sapat si sper ca va merge.

Editare.

Totul trebuie elaborat mult mai complex si precis decit in analogic. Al dracului "microb".

 

@gsabac

Editat de gsabac
Link spre comentariu

M-am ambitionat dupa indicatiile date de @thunderer, @Liviu M si @Stefan Nicolae si am baleiat toate setarile

posibile pentru ADC-ul din PIC18F2550, dupa urmatoarele coduri acceptate in mikroe mikroC si mikroBasic.

Am folosit ambele variante ADC_get_sample(0) si ADC_read(0).

 

CMCON = CMCON or 7 ' Disable comparators
TRISA=0xFF ' PORTA is input
TRISB=0 ' PORTB is output
TRISC=0 ' PORTC is output
............................................................................................................................
ADCON0.ADON=1 'deschide ADC

ADCON0.CHS0 = 0 ' 4 biti selecteaza un canal din 12
ADCON0.CHS1 = 0
ADCON0.CHS2 = 0
ADCON0.CHS3 = 0
.................................................................................................................................
'ADCON1 selecteaza sursele de referinta interna sau externa
'ADCON2=0B101110 idea de cod dintr-un ASM
ADCON2.ADFM=1 'bit 7 '1= right just. 0 = Left justified
'ADCON2.Bit6 nu este implementat
ADCON2.ACQT0=0 'bit 5 0 1 0 1 0 1 0 1
ADCON2.ACQT1=0 'bit 4 0 0 1 1 0 0 1 1
ADCON2.ACQT2=0 'bit 3 0 0 0 0 1 1 1 1
'----------------------------------------------
ADCON2.ADCS0=0 'bit 2 0 1 0 1 0 1 0 1
ADCON2.ADCS0=0 'bit 1 0 0 1 1 0 0 1 1
ADCON2.ADCS0=0 'bit 0 0 0 0 0 1 1 1 1

Ultimii 6 biti se ocupa cu setarile registrului ADCON2 care determina timpii de achizitie si frecventa de tact pentru ADC.

bit 6 Unimplemented: Read as ‘0’

bit 5-3 ACQT2:ACQT0: A/D Acquisition Time Select bits

111 = 20 TAD

110 = 16 TAD

101 = 12 TAD

100 = 8 TAD

011 = 6 TAD

010 = 4 TAD

001 = 2 TAD

000 = 0 TAD(1)

bit 2-0 ADCS2:ADCS0: A/D Conversion Clock Select bits

111 = FRC (clock derived from A/D RC oscillator)(1)

110 = FOSC/64

101 = FOSC/16

100 = FOSC/4

011 = FRC (clock derived from A/D RC oscillator)(1)

010 = FOSC/32

001 = FOSC/8

000 = FOSC/2

Rezultatul cel mai bun a fost 18K esantioane pe secunda si minimum 8K esantioane pe secunda.

Or fi si alte setari utile, dar inca nu le-am dibuit. Acum tind sa banuiesc rutinele ADC Mikroe.

 

@gsabac

Editat de gsabac
Link spre comentariu

Tinand cont de la tabelul de la pagina 267 din foaia de catalog, as fi jurat ca setarea

  La 28.05.2017 la 11:04, gsabac a spus:

 

  '----------------------------------------------
  ADCON2.ADCS0=0    'bit 2       0 1 0 1 0 1 0 1
  ADCON2.ADCS0=0    'bit 1       0 0 1 1 0 0 1 1
  ADCON2.ADCS0=0    'bit 0       0 0 0 0 1 1 1 1

 

n-are cum sa mearga cu clock de 48 MHz.
Link spre comentariu

48Mhz la care va referiti, a ramas de la unele variante anterioare.

Este o constatare logica, este asa cum spuneti, la unele setari am ajuns la 4MHz

si uneori am introdus si o intirziere de 10uS.

Am incercat pe rind toate combinatiile si am ales viteza maxima la care functioneaza, in functie de setari,

fara sa obtin imbunatatiri. Ma intriga un model scris in C cu ASM care merge la 32 KHz.

Am incercat si cu ADRESL si ADRESH direct fara ADC_get_sample(0) si ADC_read(0).

Pentru truncherea doar cu ADRESH am obtinut un semnal caricatura, dar cu esantionare de 32KHz.

 

@gsabac

Editat de gsabac
Link spre comentariu
  La 28.05.2017 la 16:55, gsabac a spus:

Pentru truncherea doar cu ADRESH am obtinut un semnal caricatura

Trebuie sa faci alinierea datelor la stanga. Acum ai probabil aliniere la dreapta si in ADRESH ai numai bitii b9b8. Ar trebui sa-ti iasa cam acelasi lucru ca in poza de ieri.

Ma refer la setarea asta.

  La 28.05.2017 la 11:04, gsabac a spus:
 ADCON2.ADFM=1     'bit 7                                                  '1= right just.    0 = Left justified
Editat de Liviu M
Link spre comentariu

Am incercat si alinierea "stigace" si caricatura s-a strimbat cu sus-ul in jos.

Mai sap citeva zile, acumulez date noi si poate gasesc idea care sa ma linisteasca.

 

@gsabac

Link spre comentariu
  La 29.05.2017 la 4:19, gsabac a spus:

Am incercat si alinierea "stigace" si caricatura s-a strimbat cu sus-ul in jos.

Hm, poti posta codul de test? Pentru ca cel putin "aritmetic" cu alinierea la stanga ar trebui sa obtii tot cei 8 biti pe care-i obtineai cu impartirea la 4 intr-unul din posturile initiale.

Link spre comentariu
  La 27.05.2017 la 17:02, MifTy a spus:

... e un motiv pentru care cei care fac (comercial sau home-made) osciloscoape DSO cam evită ADC-urile integrate în microcontrollere...sunt pur şi simplu prea lente! :)

dar dacă e vorba de "hai să văd cum merge"... :)

 

Sau aleg alte micro mai rapide, cum ar fi un ARM de la ST.

DSO138:

  • Maximum real-time sampling rate: 1Msps.
  • Accuracy: 12Bit.
  • Sampling buffer depth: 1024Bytes.
  • Analog bandwidth: 0 – 200KHz.

Eu am un DSO138 si mi se pare o jucarie, cu PIC nu stiu ce se poate obtine in afara de satisfactia constructiei.

  La 28.05.2017 la 16:55, gsabac a spus:

Ma intriga un model scris in C cu ASM care merge la 32 KHz.

Am incercat si cu ADRESL si ADRESH direct fara ADC_get_sample(0) si ADC_read(0).

 

Nu am incercat cu C dar am observat cu AVR, in MikroC imi este mult mai comod sa scriu direct in registrii de control al adc decat sa folosesc functiile lor.

Acelasi lucru si pentru PWM sau timere in general. Uneori este scris in documentatie "initializeaza cu setarile implicite" dar nu se spune care setari sunt implicite.

Link spre comentariu

Asa este, am obtinut aceeasi amplitudine, am folosit si ADRESH si ADRESL in combinatie cu

ADCON2.ADFM=0 si ADCON2.ADFM= 1 si diverse intirzieri si frecvente. Ramine sa inteleg cum

sunt incarcate registrele L si H, deoarece la anumite setari, se obtine o jumatate de sinusoida corecta si cealalta este

intoarsa pe dos si cu un mare salt intre ele.

In coduri Mikroe, asa cum ati spus, este acces la orice setare pentru uC, dupa cum rezulta si din codul folosit.

Am depasit multe faze cu setari implicite, prin acces direct la toate setarile registrelor de configurare.

 

main:
'ADCON1 = ADCON1 or 0x0F ' Configure all ports with analog function as digital

CMCON = CMCON or 7 ' Disable comparators
TRISA=0xFF ' PORTA is input
TRISB=0 ' PORTB is output
TRISC=0 ' PORTC is output
ADCON0.ADON=1 'deschide ADC
ADCON0.CHS0 = 0 ' 4 biti selecteaza un canal din 12
ADCON0.CHS1 = 0
ADCON0.CHS2 = 0
ADCON0.CHS3 = 0

'ADCON1 selecteaza sursele de referinta interna sau externa
'ADCON2=0B101110
'ADCON2.ADFM=0 'bit 7
ADCON2.ADFM=1 'bit 7 '1= right just. 0 = Left justified
'ADCON2.Bit6 nu este implementat
ADCON2.ACQT0=0 'bit 5 0 1 0 1 0 1 0 1
ADCON2.ACQT1=0 'bit 4 0 0 1 1 0 0 1 1
ADCON2.ACQT2=0 'bit 3 0 0 0 0 1 1 1 1
'----------------------------------------------
ADCON2.ADCS0=0 'bit 2 0 1 0 1 0 1 0 1
ADCON2.ADCS0=0 'bit 1 0 0 1 1 0 0 1 1
ADCON2.ADCS0=0 'bit 0 0 0 0 0 1 1 1 1
ADC_Init()
Delay_ms(200)
HID_Enable(@readbuff,@adread) ' 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

adread = (ADC_get_sample(0) /4) '(ADC_Read(0)/4 )' ' maximum 256 din 1024 la 10 biti. Si memoria este de 8 biti
'ADCON0.GO_DONE = 1 'start ADC
'adread = (ADRESL/8) 'ADC reading
Delay_us(5)
'adread = ADRESH*20

next i
HID_Write(@adread[0],64)
'Delay_ms(5)
wend

end.

Unele din datele si combinatiile incercate sunt cu apostrof, deci acum sunt comentarii in mikroBasic.

Editare ulterioara.

Pentru a lamuri unele aspecte ale formei de unda, am schimbat si tensiunea continua a semnalului dar si

amplitudinea sa. Pentru ca sinusoida sa fie simetrica tensiunea continua de polarizare a intrarii este de 2500mV.

Aceasta valoare corespunde la valoarea ADC=512 si fata de aceasta valoare in plus si in minus se realizeaza

esantioanele sinusoidei.

Daca se ia doar ADRESL sau ADRESH rezulta un semnal trunchiat, asa cu l-am obtinut pe ecran. Deci ar fi

o idee sa cobor referinta la 1250mV pentru a folosi ADRESL si implicit date intre 0 si 255. Am acces la

registrul care comanda referinta.

La unele combinatii de viteza, datorita aliasing-ului te poti pacali usor si se creaza falsa impresie ca a crescut

frecventa de esantionare, este ca la schimbarea de frecventa cind te apropii de purtatoare.

 

@gsabac

Editat de gsabac
Link spre comentariu

Hm, nu inteleg nimic. Ma rog.

Aliniere la dreapta (ADFM = 1):

ADRESH      ADRESL
000000b9b8  b7b6b5b4b3b2b1b0

Daca folosesti numai ADRESL, folosesti de fapt cei mai putin semnificativi 8 biti (b7..b0) ai conversiei.

Aliniere la stanga (ADFM = 0):

ADRESH              ADRESL
b9b8b7b6b5b4b3b2    b1b0 000000

Daca folosesti numai ADRESH, folosesti cei mai semnificativi 8 biti (b9..b2).

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

Editat de thunderer
Link spre comentariu

Intr-un post pe la inceputuri era un program care folosea numai cei mai semnificativi 8 biti (b9..b2). Pentru ca obtinerea lor era destul de complicata - citit pe 10 biti (combinat in functie din 2 * 8 biti) si impartit la 4, si pentru ca se dorea cresterea vitezei, am sugerat alinierea rezultatului achizitiei la stanga si citirea si folosirea ulterioara numai a registrului ADRESH.

Link spre comentariu

Pozele cu rezultatele diverselor setari. Explicatia este in numele pozei.

Folosirea functiilor complete dau sinusoide esantionate si doar a functiilor

de citire L si H dau un rezultat la care nu ma asteptam.

Edit.

Pe verticala sunt 256 de unitati asa cum primesc datele prin USB. Componenta continua se transmite si ea.

 

@gsabac

post-238209-0-37609000-1496078631_thumb.jpg

post-238209-0-34090800-1496078687_thumb.jpg

post-238209-0-39677900-1496078702_thumb.jpg

post-238209-0-40029400-1496078720_thumb.jpg

post-238209-0-76324300-1496078742_thumb.jpg

post-238209-0-21082800-1496078976_thumb.jpg

Editat de gsabac
Link spre comentariu

Am pus setarile in numele pozelor, dar postez si separat cele 3 situatii.

 

for i=0 to 64 cu 1Vvv si 5Vvv

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

next i

for i=0 to 6 'cu aliniere stinga si dreapta ADCON2.ADFM=1 si ADCON2.ADFM=0

ADCON0.GO_DONE = 1 'start ADC

adread = ADRESL 'ADC este incarcat
Delay_us(100)
next i

for i=0 to 64 'cu aliniere stinga si dreapta ADCON2.ADFM=1 si ADCON2.ADFM=0

ADCON0.GO_DONE = 1 'start ADC

adread = ADRESH *64
Delay_us(100)
next i

 

@gsabac

Editat de gsabac
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