Sari la conținut
ELFORUM - Forumul electronistilor

buton si pic


Vizitator m3_catalin

Postări Recomandate

  • Răspunsuri 31
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • Liviu M

    14

  • lama

    2

  • francezu

    1

  • 10vid

    1

Top autori în acest subiect

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

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

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

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

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

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

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 biti
Pentru 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

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

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
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

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

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