 |
www.elektronik.si Forum o elektrotehniki in računalništvu
|
Poglej prejšnjo temo :: Poglej naslednjo temo |
Avtor |
Sporočilo |
msmiha Član

Pridružen-a: Sob 26 Feb 2005 16:48 Prispevkov: 115 Aktiv.: 0.49 Kraj: Slovenske Konjice
|
Objavljeno: Ned Feb 15, 2009 5:42 pm Naslov sporočila: Prikaz zmerjene napetosti na LCD |
|
|
Stvar je sledeča: Z AD pretvornikom, ki se nahaja na PICu berem analogne vrednosti, te se giblejo od 0 do 30V, vendar so s pomočjo uporovnega delilnika skalirane med 0 in 5V. AD pretvornik, ki je na PICu je 10 biten kar pomeni da en bit moje zmerjene napetosti predstavlja 30/1023 = 0,0294V. Imam pa sledeč problem, kodo pišem v mikroc-ju in zgleda takole:
Koda: |
unsigned int u0,u1,u2,u3;
unsigned long int ADC_res;
const delec = 294;
char text[6];
void inicial_main(){
OPTION_REG = 0x00;
TRISA = 0x1F; //Definiraj pine kot vhode
ADCON0 = 0x40; //Izberi ustrezno uro za AD pretvornik glede na frek.
ADCON1 = 0x82; //Vklopi AD pretvornike od AD0 do AD5 rezultat v desno
LCD_Init(&PORTB); //Na PORTB bo priklopljen LCD zaslon
LCD_Cmd(LCD_CURSOR_OFF);
}
void main(){
inicial_main();
while(1){
LCD_Out(1,1,"U1:");
u0 = ADC_Read(0);
ADC_res = (u0*delec)/100;
WordToStr(ADC_res,text);
LCD_Out(2,1,text);
}
}
|
Probelm je da ne dobim pravih rezultatov, ko je rezultat AD pretvorbe 1023 jaz dobim na zaslonu izpis 386 namesto 3007. V čem je problem, obstaja kakšen bolj eleganten način za pretvorbo? Lahko je podan v Cju ali assamblerju.
_________________ Edini način da odkrijemo meje mogočega je da, jih prestopimo in se znajdemo v nemogočem! |
|
Nazaj na vrh |
|
 |
dkone Član

Pridružen-a: Sre 07 Mar 2007 18:53 Prispevkov: 2116 Aktiv.: 9.51 Kraj: Krško
|
Objavljeno: Ned Feb 15, 2009 6:36 pm Naslov sporočila: |
|
|
igo je napisal/a: |
Ne kompliciraj z 294.
Če dobiš 1023 , na LCDju prikažeš 30,69V . To najenostavneje dobiš, če rezultat ADC pretvorbe množiš s 3.
1023 * 3 = 3069
Nato samo še pri prikazu vrineš vejico.
1023 * 3 = 30,69V
To si že vse napravil, samo vrivanje vejice poskusi napraviti ročno v .asm, saj z .../100 dobiš decimalke, ki jih niti ne rabiš, niti ne zaznaš. En delec namreč predstavlja točno 00,03V .
V .asm se to napravi z večkratnim 16bitnim deljenjem. Ob vsakem deljenju dobiš eno cifro in vmes izpišeš še vejico.
Koda: |
pBIN2B ; 16-bitno pretvarjanje
clrf TempC ;Cifra ; Izbrisemo cifro
pBIN2B1
movf Delitels,w ; Nizji bajt -> W
subwf Podateks,f ; Odstej nizje bajte
movf Delitelz,w ; Nalozi Deljitelj -> W
btfss STATUS,C ; Ali je prislo do prenosa?
incf Delitelz,w ; Da, napravi prenos
subwf Podatekz,f ; Odstej visje bajte
btfsc STATUS,C ; Ali je rezultat pozitiven?
goto pBIN2B2 ; Da, skoci na Ena_vec
movf Delitels,w ; Ne
addwf Podateks,f ; Naredi rezultat zopet pozitiven
btfsc STATUS,C ; pristeje, kar je prej odstel
incf Podatekz,f ; Upostevanje prenosa
movf Delitelz,w
addwf Podatekz,f ; Izracun ostanka po "deljenju"
movf TempC,w ;Cifra,w ; Cifra -> W
return ; Izhod iz podprograma
pBIN2B2
bcf EproPod,0 ; 0 = 0 ; 1 = Presledek ; Indikator nicle
incf TempC,f ;Cifra,f ; Povecamo cifro
goto pBIN2B1 ; Nadaljuj pretvorbo
return
pPrCasCT ; Prikaze Cas CT
movf UraCTzg,w
movwf Podatekz
movf UraCTsp,w
movwf Podateks
goto pPrCas ; Prikaze Cas
pPrCasBW ; Prikaze Cas BW
movf UraBWzg,w
movwf Podatekz
movf UraBWsp,w
movwf Podateks
pPrCas ; Prikaze Cas
; ' ' = 0x20 ; ':' = 0x3A
bsf EproPod,0 ; 0 = 0 ; 1 = Presledek ; Indikator nicle
; h:Mm:Ss
movlw 0x40 ;XYure ; Polozaj ure na zaslonu
call KurzorNa ; Pomaknemo kurzor na XY polozaj ure
call pPres2 ; Prikaze Presledke (call za Presledke Spredaj , goto za Presledke Zadaj)
call pPrTimeX ; Glede na jezik izpiše: Time , Zeit , Cas
;-----------
movlw 0x0E
movwf Delitelz
movlw 0x10
movwf Delitels ; 3600 -> Delitelj
call pBIN2B ; Pretvorimo ure, dobimo W
; h: ali __
btfsc EproPod,0 ; 0 = Številka ; 1 = Presledek ; Indikator nicle
movlw 0xF0 ; F0 + 30 = 20 = ' '
call LCD_stev ; NE, ASCII koda od Stevilke = W + 0x30
movlw 0x00
btfss EproPod,0 ; 0 = Številka ; 1 = Presledek ; Indikator nicle
movlw 0x1A ; 1A + 20 = 3A = ':'
addlw 0x20 ; 00 + 20 = 20 = ' '
call LCD_pisi ;
;-----------
movlw 0x02
movwf Delitelz
movlw 0x58
movwf Delitels ; 600 -> Deljitelj
call pBIN2B ; Pretvorimo desetice minut, dobimo W
; M ali _
btfsc EproPod,0 ; 0 = Številka ; 1 = Presledek ; Indikator nicle
movlw 0xF0 ; F0 + 30 = 20 = ' '
call LCD_stev ; NE, ASCII koda od Stevilke = W + 0x30
;-----------
clrf Delitelz
movlw .60 ; 60 -> Deljitelj
movwf Delitels ; Pretvorimo minute
call pBIN2B
; m: ali __
btfsc EproPod,0 ; 0 = Številka ; 1 = Presledek ; Indikator nicle
movlw 0xF0 ; F0 + 30 = 20 = ' '
call LCD_stev ; NE, ASCII koda od Stevilke = W + 0x30
movlw 0x00
btfss EproPod,0 ; 0 = Številka ; 1 = Presledek ; Indikator nicle
movlw 0x1A ; 1A + 20 = 3A = ':'
addlw 0x20 ; 00 + 20 = 20 = ' '
call LCD_pisi ;
;-----------
clrf Delitelz
movlw .10 ; 10 -> Deljitelj
movwf Delitels ; Pretvorimo desetice sekund, dobimo W
call pBIN2B
; S ali _
btfsc EproPod,0 ; 0 = Številka ; 1 = Presledek ; Indikator nicle
movlw 0xF0 ; F0 + 30 = 20 = ' '
call LCD_stev ; NE, ASCII koda od Stevilke = W + 0x30
;-----------
movf Podateks,w ; Enice sekund -> W
call LCD_stev ; Izpis enic na LCD
goto pPres2 ; Prikaze Presledke (call za Presledke Spredaj , goto za Presledke Zadaj)
pPres4
movlw ' ' ; Presledek
call LCD_pisi ;
pPres3
movlw ' ' ; Presledek
call LCD_pisi ;
pPres2
movlw ' ' ; Presledek
call LCD_pisi ;
pPres1
movlw ' ' ; Presledek
call LCD_pisi ;
return ; Konec podprograma
LCD_stev ; Izpiše Število
addlw 0x30 ; ASCII '0'
goto LCD_pisi
LCD_ToIz ; Izpiše ToIzpisi
movf ToIzpisi,w ; Kličem, če ne morem priti sem z znanim W, zato ga pravočasno shranim v ToIzpisi že prej
LCD_pisi ; Izpiše Znak
movwf ToIzpisi ; Kličem, če pridem sem z znanim W ; Shranimo W (podatek)
movlw 0x0F ; 0x0F -> W
andwf PORTB,f ; Izbrisemo zgornje 4 bite PORTB
movf ToIzpisi,w ; W povrnemo nazaj
andlw 0xF0 ; Izbrisemo spodnje 4 bite W (podatka)
iorwf PORTB,f ; Posljemo zgornje 4 bite podatka
bsf LcdE
....
|
KurzorNa postavi Kurzor Na mesto W
pPrTimeX izpiše besedo, glede na jezik. (lahko vržeš ven)
Spremeni samo Delitelz in Delitels (zgornji in spodnji del 16 bitnega delitelja), da deliš s 100.
Upam, da se boš znašel .
LP,
Igor |
_________________ Denis |
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
Objavljeno: Pon Feb 16, 2009 12:18 am Naslov sporočila: Re: Prikaz zmerjene napetosti na LCD |
|
|
msmiha je napisal/a: |
unsigned int u0,u1,u2,u3;
...
u0 = ADC_Read(0);
...
|
Definiraj u0 kot long int, verjetno ne bo več težav potem. Ne vem kako mikroc obravnava int, vendar če je le-to 8bitno število potem dobiš noter napako že pri branju
|
|
Nazaj na vrh |
|
 |
msmiha Član

Pridružen-a: Sob 26 Feb 2005 16:48 Prispevkov: 115 Aktiv.: 0.49 Kraj: Slovenske Konjice
|
Objavljeno: Pon Feb 16, 2009 1:58 am Naslov sporočila: |
|
|
No programček sem sedaj napisal takole in skoraj deluje:
Koda: |
unsigned int u0,u1,u2,u3;
char text[4];
char kontrolni;
char v_integer;
unsigned v_decimal;
unsigned long v_skup;
void inicial_main(){
OPTION_REG = 0x00;
TRISA = 0x1F; //Definiraj pine kot vhode
ADCON0 = 0x40; //Izberi ustrezno uro za AD pretvornik glede na frek.
ADCON1 = 0x82; //Vklopi AD pretvornike od AD0 do AD5 rezultat v desno
LCD_Init(&PORTB); //Na PORTB bo priklopljen LCD zaslon
LCD_Cmd(LCD_CURSOR_OFF);
}
void ADC_voltmat(unsigned int ADC_val){ //funkcija razbije rezultat na cela in decimalna števila
v_skup = (unsigned long)ADC_val*294; //skaliramo celotno zadevo
v_skup /= 10; //pretvorimo vse skupaj v mV
v_integer = (unsigned long)v_skup / 1000; //delimo z 1000 da dobimo volte
v_decimal = (unsigned long)v_skup % 1000; //dobimo ostanek od deljenja z 1000
}
void volt_izpis(char u_int, unsigned u_dec){ //funkcija nam izpiše vrednosti na LCD
ByteToStr(v_integer,text); //celo število pretvorimo v string
LCD_Out(2,1,text); //in ga izpišemo v drugo vrstico na začetek
LCD_Out_CP("."); //za celim številom izpišemo piko
ByteToStr(v_decimal,text); //pretvorimo decimalke v string
text[2]=86; //Namesto zadnje decimalke pišemo črko "V"
if(text[0]==32) text[0]=48; //če je na prvem dec mestu "SPC" znak piši "0"
if(text[1]==32) text[1]=48; //če je na prvem dec mestu "SPC" znak piši "0"
LCD_Out_CP(text); //nadaljuj z pisanjem teksta tam kjer si ostal
}
void main(){
inicial_main();
while(1){
LCD_Out(1,1,"U1:");
u0 = ADC_Read(0);
ADC_voltmat(u0);
volt_izpis(v_integer, v_decimal);
}
}
|
Problem je res bil v tistih tipih pri spremenljivkah. Sedaj programček dela dobro, vendar se še vedno pojavljajo problemi pri decimalnih mestih. Tam je zopet enak problem. Številke namreč gredo le od 0 do 255, kljub temu da so sedaj spremenljivke pravega tipa
_________________ Edini način da odkrijemo meje mogočega je da, jih prestopimo in se znajdemo v nemogočem! |
|
Nazaj na vrh |
|
 |
bungee Član


Pridružen-a: Pon 07 Mar 2005 18:49 Prispevkov: 1479 Aktiv.: 6.24 Kraj: Ljubljana
|
Objavljeno: Pon Feb 16, 2009 8:56 am Naslov sporočila: |
|
|
u0 imaš še vedno 8 biten
|
|
Nazaj na vrh |
|
 |
Sokrat Član


Pridružen-a: Čet 25 Avg 2005 11:00 Prispevkov: 5584 Aktiv.: 23.57
|
Objavljeno: Pon Feb 16, 2009 10:42 am Naslov sporočila: |
|
|
Pri toliko komplikacijah se sprasujem, ce ne bi bil vgrajeni sprintf in tip spremenljivke z decimalno piko priblizno enako potraten, a koda precej bolj berljiva ...
_________________ Ka ti bo pa torba ce si kupu kolo ? |
|
Nazaj na vrh |
|
 |
msmiha Član

Pridružen-a: Sob 26 Feb 2005 16:48 Prispevkov: 115 Aktiv.: 0.49 Kraj: Slovenske Konjice
|
Objavljeno: Pon Feb 16, 2009 11:10 am Naslov sporočila: |
|
|
bungee: Kje vidiš da je u0 8 biten? V prvi vrstici je namreč definiran kot unsigned int. Kar pomeni da je 16 biten.
Sokrat: Lahko bi, samo sem v helpu opazil sledeče:
Note: format string must be in the CONST area. sprintf function is not supported for p12 and p16 PIC MCU families.
Uporabljam pa 16F877A procesor, tako da ta funkcija mislim da odpade.
_________________ Edini način da odkrijemo meje mogočega je da, jih prestopimo in se znajdemo v nemogočem! |
|
Nazaj na vrh |
|
 |
Sokrat Član


Pridružen-a: Čet 25 Avg 2005 11:00 Prispevkov: 5584 Aktiv.: 23.57
|
Objavljeno: Pon Feb 16, 2009 11:29 am Naslov sporočila: |
|
|
ByteToStr() ? Bajt ne more imeti visje vrednosti kot 255, ostalo ti preprosto ignorira in gleda samo spodnji bajt tvoje spremenljivke.
IntToStr() ...
_________________ Ka ti bo pa torba ce si kupu kolo ? |
|
Nazaj na vrh |
|
 |
msmiha Član

Pridružen-a: Sob 26 Feb 2005 16:48 Prispevkov: 115 Aktiv.: 0.49 Kraj: Slovenske Konjice
|
Objavljeno: Pon Feb 16, 2009 11:47 am Naslov sporočila: |
|
|
Sokrat hvala. Nevem kaj sem študiral. Ensotavno sem hotel čimbolj optimirati zadevo
_________________ Edini način da odkrijemo meje mogočega je da, jih prestopimo in se znajdemo v nemogočem! |
|
Nazaj na vrh |
|
 |
Sokrat Član


Pridružen-a: Čet 25 Avg 2005 11:00 Prispevkov: 5584 Aktiv.: 23.57
|
Objavljeno: Pon Feb 16, 2009 12:32 pm Naslov sporočila: |
|
|
Se zgodi
_________________ Ka ti bo pa torba ce si kupu kolo ? |
|
Nazaj na vrh |
|
 |
Tonci Član

Pridružen-a: Tor 05 Avg 2008 18:14 Prispevkov: 629 Aktiv.: 3.06 Kraj: Domžale
|
Objavljeno: Pet Feb 20, 2009 5:33 pm Naslov sporočila: |
|
|
da ne odpiram nove teme bom kar tukaj vprašal, saj je tematika "podobna". Tudi sam nameravam narediti V-A meter s picom(vrjetno z 18F2520)! Zanima me, če je dana vezava ok (mogoče bi vezal še več uporov za merjenje napetosti, da pridobim še mV) in kakšen upor naj bo za merjenje toka? Kakšna zaščita bi bila ok, če pride do kratkega stika da ne odleti pic? Zanima me še glede na Vref če bi bilo bolje, da je nižja (1V), saj s tem pridobim več digitov!
Opis: |
|
 Download |
Ime datoteke: |
shema.pdf |
Velikost datoteke: |
7.19 KB |
Downloadano: |
23 krat |
|
|
Nazaj na vrh |
|
 |
msmiha Član

Pridružen-a: Sob 26 Feb 2005 16:48 Prispevkov: 115 Aktiv.: 0.49 Kraj: Slovenske Konjice
|
Objavljeno: Pet Feb 20, 2009 5:56 pm Naslov sporočila: |
|
|
Tonči vse je odvisno od napajalne napetosti in maksimalnega toka, ki ga bo usmernik sposoben dovesti (v kratkem stiku). Recimo jaz imam maksimalno napetost 30V, in maksimalen tok 3A. To pomeni da je potrebno tistih 30V spravit na napajalno napetost PICa. Zato sem uporabil en uporovni delilnik. Toka 3A, ki teče skozi 0,15 ohmski upor, mi na njem povzroči padec napetosti za 0,45V. To napetost s pomočjo OPja ojačim na 5V. Torej je ojačanje OPja nastavljeno na 11. Bom pa tudi objavil končno verzijo tega mojega amper, volt in wat metra. Zadevo mam zaenkrat narejeno tako, daleč da prikazuje te 3 stvari, vendar še imam namen narediti, da se bo lahko območje kazanja ampermetra in voltmetra programiralo preko RS232. Moogoče bom tudi dodal možnost priklopa LED displaya glede na to da sem res uporabil ogromen PIC in sicer 16F877A.
_________________ Edini način da odkrijemo meje mogočega je da, jih prestopimo in se znajdemo v nemogočem! |
|
Nazaj na vrh |
|
 |
Tonci Član

Pridružen-a: Tor 05 Avg 2008 18:14 Prispevkov: 629 Aktiv.: 3.06 Kraj: Domžale
|
Objavljeno: Pet Feb 20, 2009 6:03 pm Naslov sporočila: |
|
|
Ja pozabil omeniti, da je max napetost 17V, tok pa okoli 1A! Je nujno OP? Razmišlal sem tako, da bi bil maxi padec 1V, kar pomeni pri 10bitnem A/D 0.001A!
|
|
Nazaj na vrh |
|
 |
msmiha Član

Pridružen-a: Sob 26 Feb 2005 16:48 Prispevkov: 115 Aktiv.: 0.49 Kraj: Slovenske Konjice
|
Objavljeno: Pet Feb 20, 2009 7:34 pm Naslov sporočila: |
|
|
Načeloma bi to seveda šlo, ampak potem rabiš zgornjo referenco AD pretvornika 1V. Tako, da ti pri zmerjeni napetosti 1V. AD pretvornik vrne 1023, delcev in ne 205.
_________________ Edini način da odkrijemo meje mogočega je da, jih prestopimo in se znajdemo v nemogočem! |
|
Nazaj na vrh |
|
 |
|
|
Ne, ne moreš dodajati novih tem v tem forumu Ne, ne moreš odgovarjati na teme v tem forumu Ne, ne moreš urejati svojih prispevkov v tem forumu Ne, ne moreš brisati svojih prispevkov v tem forumu Ne ne moreš glasovati v anketi v tem forumu Ne, ne moreš pripeti datotek v tem forumu Ne, ne moreš povleči datotek v tem forumu
|
Uptime: 494 dni
Powered by phpBB © 2001, 2005 phpBB Group
|