Liviu M Postat Iulie 15, 2011 Partajează Postat Iulie 15, 2011 Si sunt functiile astea definite in picc? Link spre comentariu
Vizitator m3_catalin Postat Iulie 15, 2011 Partajează Postat Iulie 15, 2011 sigur ca nu, asta gasisem eu pe net, nu cunosc functiile, doar vazusem principiul Link spre comentariu
Liviu M Postat Iulie 15, 2011 Partajează Postat Iulie 15, 2011 Asta e principiul daca ai functiile, daca nu, arata cam ca setarile anterioare. Am si eu un proiectel in care folosesc AN0 ca intrare si VREF diferit de VDD. Cam asa arata partea de initializare (la inceputul proiectului) ADCON0 = 0b10000000; // ADCON<7:6> = 10 -> Tosc/32 // ADCON<5:3> = 000 -> AN0 = intrarea activa // ADC inca inactiv, o sa-l activez cand o sa fie cazul ADCON1 = 0b10000011; // ADCON1<7> = 1 -> rezultatul conversiei e aliniat la dreapta // ADCON1<3:0> = 0011 -> RE<2:0> -> Digital // RA<5,0> -> Analog // RA<0> -> AN<0> // RA<3> == AN<3> == VREF+ // PORTA - intrari analoge (cu exceptia RA4); folosesc numai o intrareanaloga => numai RA0 "activata" TRISA = 0b00001001; // RA0 == AN0 = intrare pentru ADC // RA3 == AN3 = VREF+ = intrare (?) PORTA = 0b00000000;iar citirea o fac "relaxat", o data la 2 secunde (in secunda impara comand achizitia, in cea para citesc valoarea si o afisez). /**************************************** Masurare pH*************************************/ if (bAdcGo) // la fiecare secunda alterneaza cererea de masurare a temperaturii si citirea valorii { BITSET(ADCON0,2); bAdcGo = 0; } else { iPhVal = ADRESH*256 + ADRESL; bAdcGo = 1; } /* else if(bAdcGo)*/ PS Nu te lua dupa comentarii, ca-s sanse sa nu mai fie valabile, uita-te in data sheet daca ai dubii. LE BITSET e un macro pe care-l gasesti in documentatia de la picc. Link spre comentariu
Vizitator m3_catalin Postat Iulie 15, 2011 Partajează Postat Iulie 15, 2011 m-ai bagat in ceata ) merci oricum Link spre comentariu
Liviu M Postat Iulie 15, 2011 Partajează Postat Iulie 15, 2011 Pai zi-mi ce nu intelegi si incerc sa-ti explic. Da' asta dupa ce citesti data-sheetul picului (macar partea de adc). Link spre comentariu
Vizitator m3_catalin Postat Iulie 15, 2011 Partajează Postat Iulie 15, 2011 am citit pagina cu ADC si am inteles urmatoarele am 2 registri, ADCON0 si ADCON1. Cu ADCON0 controlez operatiile modulului AD si cu ADCON1 configurez pinii. ADCON1 l-am configurat mai devreme cu pinul AN0 pe analog asa cum vreau eu, restu pe digital si ca referinta voi folosi Vdd si Vss. Cu ADCON0 am treaba: am registrul asa: ADCS1 ADCS0 CHS2 CHS1 CHS0 GO/DONE — ADON ADCS1-ADCS0 cum ar trebui sa le setez? 8 TOSC 001 5 MHz - daca eu am 4mhz frecventa pe placa ar trebui sa pun 0 01 aici ? prima coloana e ADCS2 setat in ADCON1, iar a 2-a sunt ADCS1 si ADCS0 0 00 FOSC/2 0 01 FOSC/8 0 10 FOSC/32 0 11 FRC (clock derived from the internal A/D RC oscillator) 1 00 FOSC/4 1 01 FOSC/16 1 10 FOSC/64 1 11 FRC (clock derived from the internal A/D RC oscillator) apoi trebuie sa aleg channel 0 pentru ca am nevoie de AN0. CHS2:CHS0: Analog Channel Select bits 000 = Channel 0 (AN0) 001 = Channel 1 (AN1) 010 = Channel 2 (AN2) 011 = Channel 3 (AN3) 100 = Channel 4 (AN4) 101 = Channel 5 (AN5) 110 = Channel 6 (AN6) 111 = Channel 7 (AN7) cand ADON = 1, adica bitul 0 din ADCON0 am 2 valori pentru bitul 2, adica GO/DONE 1 = A/D conversion in progress (setting this bit starts the A/D conversion which is automatically cleared by hardware when the A/D conversion is complete) 0 = A/D conversion not in progress ar trebui sa pun 1 in acest bit, 2 din ADCON0 ca sa pornesc conversia A/D din cate inteleg. cu bitul 1 din ADCON0 n-am treaba ultimul bit bit 0 ADON: A/D On bit 1 = A/D converter module is powered up 0 = A/D converter module is shut-off and consumes no operating current cand fac conversie trebuie sa-l pun pe 1 la inceput.. acum, cu toate astea stiute , cum citesc eu valoarea de pe pinul AN0, RA0 ? ce functie citeste valoarea care o salvez intr-o variabila, o impart apoi la 1023(daca e pe 10biti) si inmultesc cu 5 (ca sa imi dea valoarea in tensiune) si o compar cu Vdd si Vss.... ? LE: am gasit si asta http://ww1.microchip.com/downloads/en/d ... 33023a.pdf e explicat mai pe larg, nu e foarte usor din cate vad. Link spre comentariu
Vizitator m3_catalin Postat Iulie 15, 2011 Partajează Postat Iulie 15, 2011 pe mine de fapt nu ma intereseaza tensiunea, ma intereseaza pozitia potentiometrului, rezistenta acestuia instantanee. pana acum am facut asa: ADCON1 = 0xCE; ADCON0 = 0x81; // (10 = FOSC/32-nu stiu cum sa aleg asta) 000 = canalul 0, (AN0) 0 0 1- porneste modulul AD delayms(1); ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie AD delayms(1); if (ADCON0,2 == 0) //testez daca am 0 pe bitul GO ca sa vad daca s-a terminat conversia { citire = ADRESH; } // (Rezultatul apare in perechea de registrii ADRESH:ADRESL cu cei mai semnificativi 6 biti din ADRESH --> 0 ) Cum transform eu rezultatul asta din acesti registri intr-un numar intreg ? delayms(1); Link spre comentariu
lama Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 pe mine de fapt nu ma intereseaza tensiunea, ma intereseaza pozitia potentiometrului, rezistenta acestuia instantanee.pana acum am facut asa:ADCON1 = 0xCE;ADCON0 = 0x81; // (10 = FOSC/32-nu stiu cum sa aleg asta) 000 = canalul 0, (AN0) 0 0 1- porneste modulul ADdelayms(1);ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie ADdelayms(1);if (ADCON0,2 == 0) //testez daca am 0 pe bitul GO ca sa vad daca s-a terminat conversia{ citire = ADRESH; } // (Rezultatul apare in perechea de registrii ADRESH:ADRESL cu cei mai semnificativi 6 biti din ADRESH --> 0 ) Cum transform eu rezultatul asta din acesti registri intr-un numar intreg ?delayms(1);SalutPoate cu ceva de tipul data = ( ADRESH << 8) + ADRESL;Vezi ca data sa aiba loc (un unsigned int, ceva)si vezi ca tocmai am patit-o cu MikroC: "data" e acum cuvant rezervat(in vers 4.60) Link spre comentariu
Liviu M Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 Pai daca te intereseaza numai pozitia potentiometrului, poti incerca sa folosesti modulul comparator. Are 2 comparatoare, cu care poti testa 2 praguri, unul pentru potentiometru stanga si altul pentru potentiometru dreapta (casa nu ai "ambiguitati" lasi un "spatiu" oarecare intre ele). Referitor la intrebarile tale legate de ADC, secventa de configurare/masurare cu ADC-ul e data la pag. 129 in data-sheet, criteriile de alegere a frecventei sunt precizate la pagina 131 (in cazul tau, avand clockul sistemului 4 MHz, trebuie minim 8TOsc, da poti folosi si 16Tosc, 32Tosc sau 64Tosc; recomand 8TOsc, altfel achizitia dureaza mai mult). Pentru conversie, vezi postul lui lama sau postul meu anterior, iPhVal = ADRESH*256 + ADRESL;unde iPhVal e o variabila integer (de data asta merge si fara unsigned, ca valoarea finala e pe 14 biti, nu pe 16), iar inmultirea cu 256 e echivalenta cu o deplasare la stanga cu 8 biti. Link spre comentariu
Vizitator m3_catalin Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 deci in principiu asta ar fi codul ADCON1 = 0xCE; //setare registru bitii AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 VREF+ VREF- // D D D D D D D A VDD VSS - pinul AN0 analog pentru potentiometru delayms(1); ADCON0 = 0x41; // 01 = 8Tosc 000 = canalul 0, (AN0) 0 0 1- porneste modulul AD delayms(1); ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie AD delayms(1); if (ADCON0,2 == 0) { citire2 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 biti delayms(1); } pe mine ma intereseaza sa fac intr-o bucla while(1) 2 citiri consecutive si sa compar rezultatele din cele 2 variabile, citire1 si citire2 de exemplu. ca sa fac alta conversie trebuie sa pun tot codul inca odata incepand cu setarea lui ADCON1 ? asa vad scris in datasheet 1. Configure the A/D module: • Configure analog pins / voltage reference / and digital I/O (ADCON1) • Select A/D input channel (ADCON0) • Select A/D conversion clock (ADCON0) • Turn on A/D module (ADCON0) 2. Configure A/D interrupt (if desired): • Clear the ADIF bit • Set the ADIE bit • Set the GIE bit 3. Wait the required acquisition time. 4. Start conversion: • Set the GO/DONE bit (ADCON0) 5. Wait for A/D conversion to complete, by either: • Polling for the GO/DONE bit to be cleared OR • Waiting for the A/D interrupt 6. Read A/D Result register (ADRES), clear the ADIF bit, if required. 7. For next conversion, go to step 1 or step 2 as required. Link spre comentariu
Liviu M Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 In loc de if (ADCON0,2 == 0) // nu cred ca picc stie constructia asta, incearca cu ADCON0 & 0x04{As face while(ADCON0 & 0x04) // cat timp bitul 2 in ADCON0 e 1, astept { __delay_ms(1); //asta e forma acceptata de picc; mai trebuie sa #define _XTAL_FREQ 4000000 undeva la inceput}citire2 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 bitiPentru a doua valoare, dupa un delay oarecare (suficient de mare sa ai timp sa faci ceva la potentiometru), repeti de la partea cu ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie AD, picul fiind deja configurat. LE Cum nu-s eu mai priceput decat data-sheetul, nu-ti ramane decat sa testezi, sa vezi daca merge cum cred eu sau cum scrie in data-sheet (in bucata anterioara de cod parca nu repet toata configurarea). Link spre comentariu
Vizitator m3_catalin Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 deci asa ar trebui sa arate codul pana acum pentru partea de citire potentiometru si comparare valori void main() { TRISA = 0b00000001; TRISB = 0x00; //PORTB- iesire TRISD = 0x00; //PORTD- iesire TRISC = 0x00; //PORTC- iesire TRISE = 0b00000111; //PORTE- intrare ADCON1 = 0xCE; //setare registru bitii AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 VREF+ VREF- // D D D D D D D A VDD VSS - pinul AN0 analog pentru potentiometru __delay_ms(1); ADCON0 = 0x41; // 01 = 8Tosc 000 = canalul 0, (AN0) 0 0 1- porneste modulul AD __delay_ms(1); while (1) { ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie AD __delay_ms(1); while(ADCON0 & 0x04) // cat timp bitul 2 in ADCON0 e 1, astept { __delay_ms(1); citire1 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 biti __delay_ms(1); } ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie AD __delay_ms(1); while(ADCON0 & 0x04) // cat timp bitul 2 in ADCON0 e 1, astept { __delay_ms(1); citire2 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 biti __delay_ms(1); if (citire1 > citire2) x=1; else x=0; if (citire1 < citire2) y=1; else y=0; } } } codul este compilat fara erori, urmeaza sa-l incarc pe microcontroller, sa leg potentiometrul la 5v, pinul AN0 si GND si sa inlocuiesc secventele x=1 si y=1 dupa comparare cu ce-mi trebuie mie. Link spre comentariu
Liviu M Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 Aici eai o greseala: deci asa ar trebui sa arate codul pana acum pentru partea de citire potentiometru si comparare valori void main() { while(ADCON0 & 0x04) // cat timp bitul 2 in ADCON0 e 1, astept { __delay_ms(1); citire1 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 biti __delay_ms(1); } Citirea se face in afara buclei while, cand conversia e gata: while(ADCON0 & 0x04) // cat timp bitul 2 in ADCON0 e 1, astept { __delay_ms(1); } citire1 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 biti __delay_ms(1); Link spre comentariu
Vizitator m3_catalin Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 void main(){ TRISA = 0b00000001; TRISB = 0x00; //PORTB- iesire TRISD = 0x00; //PORTD- iesire TRISC = 0x00; //PORTC- iesire TRISE = 0b00000111; //PORTE- intrareADCON1 = 0xCE; //setare registru bitii AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 VREF+ VREF- // D D D D D D D A VDD VSS - pinul AN0 analog pentru potentiometru __delay_ms(1);ADCON0 = 0x41; // 01 = 8Tosc 000 = canalul 0, (AN0) 0 0 1- porneste modulul AD __delay_ms(1);while(1) {//-------------------------------------------------------------------------ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie AD__delay_ms(1); while(ADCON0 & 0x04) // cat timp bitul 2 in ADCON0 e 1, astept { __delay_ms(1); } citire1 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 biti __delay_ms(1);//------------------------------------------------------------------------- ADCON0 = ADCON0 && 0b00000100; // setare bit GO, pornire conversie AD__delay_ms(1); while(ADCON0 & 0x04) // cat timp bitul 2 in ADCON0 e 1, astept { __delay_ms(1); } citire2 = ( ADRESH << 8) + ADRESL; // citire valoare conversie , shiftare la stanga cu 8 biti __delay_ms(1);//------------------------------------------------------------------------if (citire1 > citire2) x=1; else x=0; if (citire1 < citire2) y=1; else y=0; } } Link spre comentariu
Liviu M Postat Iulie 16, 2011 Partajează Postat Iulie 16, 2011 Dupa parerea mea, pauza dintre 2 achizitii consecutive e mult prea mica (1 ms), intr-o milisecunda nu se intampla (mai) nimic (sau mult prea multe - vezi observatia urmatoare). Pe de alt parte, chiar daca nu atingi potentiometrul, tot o sa ai mici variatii in semnalul de pe AN0; dupa parerea mea, x si y or sa "falfaie" continuu. Cred ca ti-ar trebui un mic histeresis, de genul if (citire1 > citire2 + 5) x=1;else x=0; if (citire1 < citire2 - 5) y=1;else y=0;In felul asta o sa ai un histeresis de 10 LSB. Daca ajunge sau nu (sau daca e nevoie sau nu de histeresisul asta) o sa vezi cand o sa testezi practic schema. In continuare iti recomoand sa te uiti si la partea de comparator a picului. 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