Liviu M Postat Mai 29, 2017 Partajează Postat Mai 29, 2017 (editat) 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 Mai 29, 2017 de Liviu M Citează Link spre comentariu
gsabac Postat Mai 29, 2017 Autor Partajează Postat Mai 29, 2017 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 Citează Link spre comentariu
Liviu M Postat Mai 29, 2017 Partajează Postat Mai 29, 2017 Scuze, n-am intentionat sa te descurajez. Continua, te rog. Promit sa-mi tin gura. Citează Link spre comentariu
gsabac Postat Mai 29, 2017 Autor Partajează Postat Mai 29, 2017 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 Citează Link spre comentariu
gsabac Postat Mai 31, 2017 Autor Partajează Postat Mai 31, 2017 (editat) 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. Realizat fizic, semnalul vizualizat cu aspect grafic bun (cu ferestre Hamming) va urca la circa 25KHz. @gsabac Editat Mai 31, 2017 de gsabac Citează Link spre comentariu
gsabac Postat Iunie 2, 2017 Autor Partajează Postat Iunie 2, 2017 (editat) 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 Iunie 2, 2017 de gsabac Citează Link spre comentariu
gsabac Postat Iunie 11, 2017 Autor Partajează Postat Iunie 11, 2017 Viteza maxima de achizitie a ajuns la maturitate (70KHz) si aplicatia s-a maturizat si arata asa: 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 octetiDaca 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 Citează Link spre comentariu
Liviu M Postat Iunie 11, 2017 Partajează Postat Iunie 11, 2017 Salut, in loc sa astepti un timp fix for j=1 to nCicle ‘intirziere next j poti sa testezi bitul ADCON0.GO_DONE. Cand conversia se termina, bitul trece in 0. while ADCON0.GO_DONE nop wend Citează Link spre comentariu
Mircea Postat Iunie 11, 2017 Partajează Postat Iunie 11, 2017 Corect, Liviu, dar recomanzi bucle in bucle? S-ar putea implementa un Break acolo, daca tot se pun bucle, dar ar complica codul si nu e ceea ce se voia acolo. Citează Link spre comentariu
Liviu M Postat Iunie 11, 2017 Partajează Postat Iunie 11, 2017 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". Citează Link spre comentariu
gsabac Postat Iunie 11, 2017 Autor Partajează Postat Iunie 11, 2017 (editat) 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 Iunie 11, 2017 de gsabac Citează Link spre comentariu
Liviu M Postat Iunie 11, 2017 Partajează Postat Iunie 11, 2017 (editat) 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 Iunie 11, 2017 de Liviu M Citează Link spre comentariu
gsabac Postat Iunie 18, 2017 Autor Partajează Postat Iunie 18, 2017 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: 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 Citează Link spre comentariu
Liviu M Postat Iunie 18, 2017 Partajează Postat Iunie 18, 2017 (editat) 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 Iunie 18, 2017 de Liviu M Citează Link spre comentariu
gsabac Postat Iunie 18, 2017 Autor Partajează Postat Iunie 18, 2017 Multumesc. Mai scriu ceva coduri si un potentiometru este interesant, poate si un DAC (sau o retea R-2R) comandat din PC. In legatura cu "break", am o retinere, trebuie sa iasa din If, din Select Case si din For. @gsabac Citează Link spre comentariu
Postări Recomandate
Alătură-te conversației
Poți posta acum și să te înregistrezi mai târziu. Dacă ai un cont, autentifică-te acum pentru a posta cu contul tău.
Notă: Postarea ta va necesita aprobare moderator înainte de a fi vizibilă.