gsabac Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 (editat) In documentatii se indica o viteza de achizitie in jur de 40KHz. Eu nu am reusit in simularea virtuala decit 16KHz, probabil cu setarile implicite si cu urmatorul cod. main: CMCON = CMCON or 7 ' Disable comparators TRISA=0xFF ' PORTA is input TRISB=0 ' PORTB is output TRISC=0 ' PORTC is output HID_Enable(@readbuff,@adread) ' Enable HID communication while TRUE ' USB servicing is done inside the while loop USB_Polling_Proc() ' Call this routine periodically for i=0 to adread=(ADC_Read(0) / 4) ' maximum 256 din 1024 la 10 biti. Si memoria este de 8 biti next i adread[0]=70 HID_Write(@adread[0],64) Delay_ms(5) wend end. Cu ajutorul sau doresc sa proiectez un osciloscop USB, deocamdata pentru 10-20KHz, dar asa cum este poate merge doar la 5KHz datorita ratei mici de esantionare pe care am realizat-o, 16KHz. Asa arata imaginea pentru 2KHz la intrare si se vad pe ea cite 8 puncte care corespund esantionarii pe o perioada. Stie cineva mai avansat decit mine, cum se poate seta ADC-ul pentru rata maxima de asantionare. Precizez ca acum uC-ul este la 48MHz. @gsabac Editat Mai 27, 2017 de gsabac Link spre comentariu
Stefan Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 Nu ma pricep cine stie ce la PICe dar cand m-am jucat cu ADC-ul la 887, in mikroC, am observat ca functia lor de citire ADC era mai lenta fata de functia facuta de mine. Functia ADC_Read este fcuta de dvs.? Intreb pentru ca nu vad nimic despre setarea registrului ADCON2. Link spre comentariu
gsabac Postat Mai 27, 2017 Autor Partajează Postat Mai 27, 2017 (editat) Functia ADC_Read(0) este Mikroe pentru mikroBasic intrarea "0" . Buna idee, am sa ma uit in fisierul de definitie al ADC-ului. Edit. M-am uitat si sunt 25 de linii in fisierul asm. @gsabac Editat Mai 27, 2017 de gsabac Link spre comentariu
gsabac Postat Mai 27, 2017 Autor Partajează Postat Mai 27, 2017 (editat) Nu cred ca progamul HEX este cheia problemei, sunt ceva setari ale ADC-ului pe care nu le stiu. Desi am incercat multe variante, nici una nu merge. Fie sunt erori la compilarea Mikroe, fie erori la executie in Proteus. Unele chiar blocheaza conexiunea USB-HID. @gsabac Editat Mai 27, 2017 de gsabac Link spre comentariu
Stefan Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 Pe aici ai incercat sa te uiti? http://www.edaboard.com/thread238460.html sau http://www.microchip.com/forums/m629283.aspx si foarte util http://extremeelectronics.co.in/microchip-pic-tutorials/using-adc-of-pic-microcontroller/ Nu bagi in seama partea de comunicatie UART ci doar setarea ADC-ului. Link spre comentariu
Liviu M Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 Intr-un exemplu de calcul din data-sheet (pagina 270), timpul de achizitie (incarcarea condensatorului sample&hold) le iese 2,45 us. Adaugand si timpul necesar conversiei, se mai lungeste putin, dar ar trebui sa dea mai bine decat ce ai tu. In afara de diversele setari pentru modulul ADC (ceas, timp de achizitie... - vezi data-sheet-ul pentru detalii), eu as implementa propria functie "read_adc". Tinand cont ca nu te intereseaza decat cei mai semnificativi 8 biti, poti scrie o functie care sa citeasca si sa returneze numai ADRESH. In felul asta economisesti doua conversii - doi registri in 10 biti, 10 biti in 8 biti. Un exemplu de functie de citire a unui ADC (nu e optima, nu m-a interesat viteza) am pus intr-un proiect "de pornire" pentru un VA-metru. unsigned long adcRead(unsigned char adcCh) { ADCON0bits.CHS = adcCh; //select the channel ADCON0bits.ADON = 1; //activate the ADC __delay_ms(1); //wait the acquisition time ADCON0bits.GO = 1; //start the conversion do{ //wait the conversion to complete NOP(); }while(ADCON0bits.GO); ADCON0bits.ADON = 0; //deactivate the ADC return(ADRESH * 256 + ADRESL); //return the ADC value } Tu trebuie sa optimizezi delay-ul de dupa activarea modulului si sa renunti la conversia rezultatului. Daca ma gandesc mai bine, as face intreaga achizitie intr-o astfel de functie. Ai economisi pentru fiecare sample apelul functiei si return-ul. PS: for-ul tau nu se termina: for i=0 to adread[i]=(ADC_Read(0) / 4) ' maximum 256 din 1024 la 10 biti. Si memoria este de 8 biti next i Link spre comentariu
gsabac Postat Mai 27, 2017 Autor Partajează Postat Mai 27, 2017 (editat) Am studiat inainte de topic adresele propuse si acum chiar am incercat sa le implementez si toate variantele dau erori la compilare, nu sunt coduri compatibile mikroe. Interesanta idea cu renuntarea la 2 biti, cu scuze va anunt ca eu chiar doresc +/- 512 esantioane pentru osciloscop si voi trece la 10 biti, dupa probele de acum, care sunt aproape reusite. @gsabac Editat Mai 27, 2017 de gsabac Link spre comentariu
Liviu M Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 (editat) nu sunt coduri compatibile mikroe. A, clar, al meu e C (compilatorul e xc8 de la uChip). OK, daca-ti trebuie toti bitii nu ramane decat sa muti toata achizitia intr-o functie dedicata si sa faci "de mana" toate operatiile. Editat Mai 27, 2017 de Liviu M Link spre comentariu
gsabac Postat Mai 27, 2017 Autor Partajează Postat Mai 27, 2017 (editat) Asa este cu for-ul, eroare de editare, era 64 caci probele le fac cu 64 de esantioane pentru inceput. Codul complet din ASM este mai jos. HID_Read_Write_Polling.mbas provine de la clonarea programului initial pe care l-am modificat. _main: ;HID_Read_Write_Polling.mbas,15 :: main:;HID_Read_Write_Polling.mbas,18 :: CMCON = CMCON or 7 ' Disable comparators MOVLW 7 IORWF CMCON+0, 1;HID_Read_Write_Polling.mbas,19 :: TRISA=0xFF ' PORTA is input MOVLW 255 MOVWF TRISA+0;HID_Read_Write_Polling.mbas,20 :: TRISB=0 ' PORTB is output CLRF TRISB+0;HID_Read_Write_Polling.mbas,21 :: TRISC=0 ' PORTC is output CLRF TRISC+0;HID_Read_Write_Polling.mbas,22 :: HID_Enable(@readbuff,@adread) ' Enable HID communication MOVLW _readbuff+0 MOVWF FARG_HID_Enable_readbuff+0 MOVLW hi_addr(_readbuff+0) MOVWF FARG_HID_Enable_readbuff+1 MOVLW _adread+0 MOVWF FARG_HID_Enable_writebuff+0 MOVLW hi_addr(_adread+0) MOVWF FARG_HID_Enable_writebuff+1 CALL _HID_Enable+0, 0;HID_Read_Write_Polling.mbas,23 :: while TRUE ' USB servicing is done inside the while loopL__main2:;HID_Read_Write_Polling.mbas,24 :: USB_Polling_Proc() ' Call this routine periodically CALL _USB_Polling_Proc+0, 0;HID_Read_Write_Polling.mbas,25 :: for i=0 to 64 CLRF _i+0 CLRF _i+1L__main7:;HID_Read_Write_Polling.mbas,26 :: adread = (ADC_Read(0) / 4) ' maximum 256 din 1024 la 10 biti. Si memoria este de 8 biti MOVLW _adread+0 ADDWF _i+0, 0 MOVWF FLOC__main+0 MOVLW hi_addr(_adread+0) ADDWFC _i+1, 0 MOVWF FLOC__main+1 CLRF FARG_ADC_Read_channel+0 CALL _ADC_Read+0, 0 MOVF R0, 0 MOVWF R2 MOVF R1, 0 MOVWF R3 RRCF R3, 1 RRCF R2, 1 BCF R3, 7 RRCF R3, 1 RRCF R2, 1 BCF R3, 7 MOVFF FLOC__main+0, FSR1 MOVFF FLOC__main+1, FSR1H MOVF R2, 0 MOVWF POSTINC1+0;HID_Read_Write_Polling.mbas,27 :: next i MOVLW 0 XORWF _i+1, 0 BTFSS STATUS+0, 2 GOTO L__main13 MOVLW 64 XORWF _i+0, 0L__main13: BTFSC STATUS+0, 2 GOTO L__main10 INFSNZ _i+0, 1 INCF _i+1, 1 GOTO L__main7L__main10:;HID_Read_Write_Polling.mbas,28 :: adread[0]=70 MOVLW 70 MOVWF _adread+0;HID_Read_Write_Polling.mbas,29 :: HID_Write(@adread[0],64) MOVLW _adread+0 MOVWF FARG_HID_Write_writebuff+0 MOVLW hi_addr(_adread+0) MOVWF FARG_HID_Write_writebuff+1 MOVLW 64 MOVWF FARG_HID_Write_len+0 CALL _HID_Write+0, 0;HID_Read_Write_Polling.mbas,30 :: Delay_ms(5) MOVLW 78 MOVWF R12, 0 MOVLW 235 MOVWF R13, 0L__main11: DECFSZ R13, 1, 1 BRA L__main11 DECFSZ R12, 1, 1 BRA L__main11;HID_Read_Write_Polling.mbas,31 :: wend GOTO L__main2L_end_main: GOTO $+0; end of _main De fapt trebuie o crestere a vitezei de 3-4ori pentru ca in final sa obtin o curba vizualizata acceptabil, la 20KHz pe intrare. @gsabac Editat Mai 27, 2017 de gsabac Link spre comentariu
MifTy Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 ... 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"... Link spre comentariu
gsabac Postat Mai 27, 2017 Autor Partajează Postat Mai 27, 2017 Asa este, vreau sa vad aplicatia cu maximum din ce poate. Vreau sa cresc acesti mini 16K esantioane pe secunda la normalul de 50K. Stiu teoria si am soft implementat care realizeaza o vizualizare de buna calitatate chiar la 0,95 din frecventa Nyquist. Daca realizez o esantionare la 50K, pot realiza osciloscopul la peste 20K, cu acest uC. Desigur sunt si modele de viteza mai mare din seria PIC18xxxxx, urmeaza sa le incerc capabilitatile. @gsabac Link spre comentariu
Liviu M Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 (editat) Viteza nu-i totul La pagina 273 din data-sheet e un tabel cu configurarea ceasului de esantionare in functie de frecventa de lucru. Cu cat frecventa de lucru e mai mare, cu atat frecventa de esantionare e generata folosind un divizor mai "tare". Editat Mai 27, 2017 de Liviu M Link spre comentariu
Mircea Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 (editat) Un sfat: folositi ADC_get_sample in loc de ADC_read. Ultima face initializarea ADC la fiecare chemare a functiei. Mai scutiti ceva cicluri de program. ADC_read are acelasi comportament indiferent de C, Pascal sau Basic. ADC_read : Initializes PIC’s internal ADC module to work with RC clock. Clock determines the time period necessary for performing AD conversion (min 12TAD) ADC_get_sample : The function aquires analog value from the specified channel. ADC_init trebuie chemata in rutina de initializare a PIC-ului. Editat Mai 27, 2017 de thunderer Link spre comentariu
gsabac Postat Mai 27, 2017 Autor Partajează Postat Mai 27, 2017 (editat) Multumesc, am vazut capitolul din documentatie. Nimic din ce este acolo nu se regaseste in ASM. O constatare de confirmare este ca si prin simularea de la 4MHz la 48MHz, frecventa de esantionare ramine constanta, datorita automatismului intern. Am remarcat ca si la frecvente peste 10KHz virfurile de esantionare nu scad ca amplitudine, deci esantioanele convertorului ADC sunt corecte, doar frecventa este aceea ce trebuie crescuta. Nu am acces decit la codul mikroC sau mikroBasic pentru cresterea vitezei. @thunderer, am incercat si compilatorul spune ca nu este declarata, desi exista ca functie in descrierea ADC la librarie. Oare se poate adauga referinta in ASM ? Editare ulterioara si multumesc. Comanda merge bine, dar are urmatoarea forma: ADC_get_sample(0) @gsabac Editat Mai 27, 2017 de gsabac Link spre comentariu
Mircea Postat Mai 27, 2017 Partajează Postat Mai 27, 2017 In fereastra din dreapta se bifeaza in Library Manager. https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQA89OEi9esOPJ3e0aFwmVGOSeS6xpfC4wsyk1Dca_m68A01cpUmQ Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum