Fórum témák
» Több friss téma |
Az lehet a gond, hogy a tmr1 tovább számol a TMR1IF beállítása után, de a program megint csak a 3035=65536-62500 -at tölti bele, azaz néhány számlálás elveszik másodpercenként.
A jó módszer a TMR1 aktuális értékéhez való hozzáadás lenne, ami nem egyszerű a 16 bites érték és a módosítás közbeni alsó byte átfordulás miatt. (ld.Timer1 Errata). Jobb lett volna a TMR2 -t használni. Vele nem lehet 1s időt előállítani, de ha hozzáteszünk egy szoftver számlálót, akkor meg lehet csinálni.
Igazad van, ez lehet az oka, erre nem is gondoltam. De ha a frekvenciát úgy vesszük fel az elején, hogy a timer nulláról épp 1 sec alatt csorduljon túl, akkor végülis megoldottuk!
Vagy használhatod a CCP modul special event triggert, az automatikusan nullázza a TMR1-et.
Azt meg tudjátok mondani, hogy hogy lehet azt programozni, hogy a PIC egyik bemenetére érkező jel (Volt) a nagyobb, vagy a másik bemenetelére érkező? Nem kell tudni, hogy melyik mennyi, csak a relációt. 0-5 V-os jelek érkeznek. Természetesen a bemeneteknél az analóg bemeneteket választom, de aztán megállt a tudomány. Csináltam már ADC-t használó programot, de az csak egy bemenetet használt. Köszönöm!
Igen tudom, de ez annyival volna bonyolultabb, hogy ha a két érték viszonylag közel van egymáshoz (pl. 10 %-on belül), akkor azt még egyenlőnek tekintse. Szerintem a komparátor ezt nem tudja.
A komparátor csak 2 értéket tud eredményül adni (kisebb/nagyobb). Ha 3 részre szeretnéd bontani az összehasonlítást, ahhoz 2db komparátor kell, vagy AD átalakító.
Akkor ADC. A mérés eredménye alapján döntöd el, hogy melyik a nagyobb, illetve ha a tűrésen belül van, akkor egyenlő.
Éppen úgy működik a dolog mintha egy csatornát használnál, de jelen esetben kettőt fogsz és két mérési eredményed lesz. PIC függő a dolog pontos menete de valószínűleg az ADCON0 regiszterrel lehet csatornát váltani. Csatonaváltás, mérés, eredmény kiolvasása, csatornaváltás, mérés, eredmény kiolvasása egy második változóba. Ezután pl. egyiket kivonod a másikból. Ha az eredmény kevesebb mint -10, akkor kevesebb, ha nagyobb mint 10, akkor nagyobb és ha a kettő között van, akkor pedig egyenlő. Hasraütéses számok, a pontos értékeket számolni kell.
Én így gondoltam, de nem működik (a főprogram még nincs kidolgozva, az már egyszerűbb lesz)
Idézet: „Én így gondoltam, de nem működik” Hiszen le sem fordul... A PORT.bitsRB0 nem értelmezett azonosító, a PORTBbits.RB0 lenne a jó. Felhívnám a figyelmet arra, hogy a 16F716 -ban csak 8 bites A/D van. unsigned char adc_valuek; unsigned char adc_valueb;//store output value Analog Read functoion void Analog_setting(){ ADCON0 = 0x81; ADCON1 = 0x02; } unsigned char Analog_read(unsigned char channel){ if(channel>7)return 0; ADCON0 = ADCON0 & 0xC5; ADCON0 = ADCON0 | (channel << 3); __delay_ms(2); ADCON0bits.GO_DONE = 1; while(ADCON0bits.GO_DONE); return ADRES; } A hozzászólás módosítva: Ápr 26, 2021
Szia!
Köszönöm! Elmagyaráznád ennek a logikáját, mert nem értem? ADCON0 = 0x81;ADCON1 = 0x02; Ezeket értem, itt állítjuk be a paramétereket. Az alábbiakat nem értem: if(channel>7)return 0; ADCON0 = ADCON0 & 0xC5; ADCON0 = ADCON0 | (channel << 3); Ebben a 3 sorban mit csinálunk? __delay_ms(2); Itt megvárjuk, hogy az átalakítás megtörténjen. ADCON0bits.GO_DONE = 1;Itt indítjuk az ADC-t return ADRES = itt visszatérünk oda, ahol tároljuk az elmentett értéket. Ez már digitális adat?
Idézet: „if(channel>7)return 0;” A 16F716 -on 8 analóg csatornát lehet választani (0 .. 7), ha valaki nagyobb csatorna számot adna meg, a mért érték 0. Idézet: „ADCON0 = ADCON0 & 0xC5;” A mérni kívánt csatorna számát az ADCON0 5..3 bitjeivel lehet kiválasztani. Ez az utasítás törli az 5..3 és a 1. bitet (ami nem használt). Idézet: „ADCON0 = ADCON0 | (channel << 3);” A mérni kívánt csatorna számát az ADCON0 5..3 bitjeivel lehet kiválasztani, ezeket a biteket a kapott csatorna száma alapján állítja be. Az értéket 3 bittel balra lépteti és az előzőleg 0 állított bitek helyére "írja" (logikai vagy kapcsolattal). Idézet: „__delay_ms(2);” Itt megvárjuk, hogy belső kondenzátorok felvegyék a bemeneten levő feszültséget. Idézet: „ADCON0bits.GO_DONE = 1;Itt indítjuk az ADC-t” Idézet: „while(ADCON0bits.GO_DONE);” Megvárjuk az átalakítás végét. Idézet: „return ADRES;” Egy eljárásban vagyunk, amit több helyről is meg lehet hívni. Az eljárás egy visszatérési értékkel deklaráltuk: unsigned char Analog_read(unsigned char channel) Ez az utasítás kiolvassa az ADRES (8 bites resiszter) értékét és visszatér oda, ahonnan hívták az eljárást. Az ADRES a kiválasztott csatornán történt mérés digitális formáját tartalmazza.
Köszönöm, értem!!
Korábban azért figyelmeztettél, hogy 8 bit-es az ADC ebben a PIC-ben, mert így a felbontás nem 1024, hanem csak 256? Így ez pontatlanabb? Ha 10 bit-eset választok, akkor a 10 bit 8 bitjét az ADRESL és a maradék 2 bitjét az ADRESH-ba kell rakni? Így? if(channel>7)return 0; ADCON0 = ADCON0 & 0xC5; ADCON0 = ADCON0 | (channel << 3); __delay_ms(2); ADCON0bits.GO_DONE = 1; while(ADCON0bits.GO_DONE); aadc = ADRESH; aadc = aadc<<2; bbdc = ADRESL; bbdc = bbdc >>6; ccdc = aadc|bbdc; return ccdc; Idézet: „Ha 10 bit-eset választok, akkor a 10 bit 8 bitjét az ADRESL és a maradék 2 bitjét az ADRESH-ba kell rakni?” Az átalakítás végén 12 bites értéket ad az A/D. Hogy miként kell értelmezni az ADRESH és ADRESL regisztereket, beállítható az ADCON1 regiszterben. A 16F818 adatlapjából: Idézet: „bit 7 ADFM: A/D Result Format Select bit 1 = Right justified, 6 Most Significant bits of ADRESH are read as ‘0’ 0 = Left justified, 6 Least Significant bits of ADRESL are read as ‘0’”
Érdemes egy típust csinálni:
Ekkor a
helyett
lesz. A hozzászólás módosítva: Ápr 28, 2021
Azt nem értem, hogy ha ez egy 12 bit-es érték, akkor az ADFM-nél miért kell megadnunk, hogy a bitek hogy helyezkedjenek el? Azt gondolnám, hogy az ADRESL-be kerülne az alsó 8 bit, az ADRESH-ba a maradék 4 bit, a többi hely pedig automatikusan kinullázódna. Pontosan mit adunk meg az ADFM 0/1 értékével?
Pedig van értelme. Mégpedig akkor, ha csak 8 bitet használunk fel belőle. Ekkor ADRESH-ban megkapjuk a felső 8 bitet, és nem kell a biteket tologatni.
Kétféle módon kezelhető a mért érték:
0...1023: egész szám 0, 1/2024 .. , 1023/1024 helyett 0, 64/65536, ... 65471/65536 tört érték. Az utóbbival egyes számítások egyszerűbbek.
Pillanatnyilag a tört értékes megoldás nekem bonyolultabbnak tűnik, de biztos, hogy vannak olyan esetek, amikor az a jobb. Az egész számos megoldásnál az ADFM értéke 1 legyen?
Idézet: „Az egész számos megoldásnál az ADFM értéke 1 legyen?” A 16F818 adatlapjából idéztem itt, 1 kell az egész szám formátum szerinti értelmezéshez. A kérdéses típus adatlapjában kell megnézni. Idézet: „Pillanatnyilag a tört értékes megoldás nekem bonyolultabbnak tűnik, de biztos, hogy vannak olyan esetek, amikor az a jobb.” Vannak olyan típusok, is, amelyekben 12 bites az A/D. Tört ábrázolásnál nem változik a program, csak pontosabb lehet a kiszámított érték. A hozzászólás módosítva: Ápr 30, 2021
Arra állítod be, ami neked (az adott feladatra) kényelmesebb, praktikusabb.
A hozzászólás módosítva: Ápr 30, 2021
Idézet: „unsigned int value; ... value = ADRESH; value <<=8; value |= ADRESL; return value;” Az én esetemben két analóg értéket kell összehasonlítani. Amikor már digitális értéke van (value), akkor is két értéknek kell lennie: valueb és valuek. A fenti idézett részbe ezt hogyan kell megkülönböztetnem?
Ahogy itt csináltad.
Analog_read(unsigned char channel) egy eljárás. Minden hívása egy mérést végez a paraméterként átadott számú csatornán. A visszatérési értéke a mért érték (digitálisan). Ha a típuson az A/D 8 bites, akkor célszerű unsigned char, ha 10 vagy 12 bites, akkor unsigned int típusú. Ha a két mérés (a Analog_read() visszatérési értékét) eltárolod egy-egy (átmeneti) változóban, később műveleteket végezhetsz velük. Pl:
Azt gondolnam, hogy az ADFM=1 meghatározza, hogy a bitek hova kerüljenek. Az ADRESL be 8 bit, az ADRESH ba pedig a felső kettő. De akkor mit csinálunk itt :
value = ADRESH; value <<=8; value |= ADRESL; return value;” És ez mennyire PIC függő?
Legyen ADRESH=0000 00xx, ADRESL=yyyy yyyy (4 bites bontásban az áttekinthetőségért)
A value-nek 16 bit hosszúnak kell lennie, mondjuk unsigned int... value = ADRESH; value=0000 0000 0000 00xx value <<=8; value=0000 00xx 0000 0000 value |= ADRESL; value=0000 00xx yyyy yyyy vagyis itt a 10 bit AD érték A hozzászólás módosítva: Máj 3, 2021
Idézet: „És ez mennyire PIC függő?” 8 biteseken általános. 16 és 32 bitesen nem kell, egyben beolvasható a 10 / 12 bites érték.
Xc16 fordító alatt el lehet érni valahogy a konkrét PIC flash méretét? Létezik rá valamilyen konstans?
A header állományban vannak ilyen definíciók:
|
Bejelentkezés
Hirdetés |