PIC 16F870 som voltmätare - designhjälp!
Mult (eller div) med en jämn potens av två blir rena shift operationer.
Mult med andra tal kan oftast förenkas till kombinationer av shift och additioner.
T.ex x3 blir en shift och en addition (d.v.s x2 + x1) O.s.v.....
x6 kan förenklas till en dubbel-shift (x4) och en enkel-shift (x2)
vars resultat sedan adderas.
O.s.v...
Multiplikationer med valfria tal blir naturligtsvis lite mer komplext.
Eller så kör man en PIC18 modell där det finns en färdig MULT instruktion...
Mult med andra tal kan oftast förenkas till kombinationer av shift och additioner.
T.ex x3 blir en shift och en addition (d.v.s x2 + x1) O.s.v.....
x6 kan förenklas till en dubbel-shift (x4) och en enkel-shift (x2)
vars resultat sedan adderas.
O.s.v...
Multiplikationer med valfria tal blir naturligtsvis lite mer komplext.
Eller så kör man en PIC18 modell där det finns en färdig MULT instruktion...
Givetvis! Nu när jag ser det är det ju självklart.
Tack för den enkla men logiska förklaringen.
Däremot multiplikation med decimaler hoppar jag över til en annan gång, hehe
Nästa fråga blir då följande (om du orkar förklara, det uppskattas) :
Hur konverterar man lättast ett binärt tal till decimalt med flera siffror?
Ex.
Jag får resultatet b'00001111' av en operation och det ska skickas till två siffror på displayen varav den ena är 1 och den andra 5, resultatet är ju 15 decimalt.
Om det bara hade varit en siffra i resultatet så hade jag fixat det. Bara att ta det binära värdet och lägga på lookupen så är det klart. Nu är det svårare.
Nu bör jag väl få två värden på något sätt där den ena är b'00000101' (5) och den andra b'00000001' (=1)
Dessa värden använder jag som vanligt i lookupen och skickar multiplexat till displayerna.
Hur räknar jag fram dessa binära tal?
/Mattesnillet
Tack för den enkla men logiska förklaringen.
Däremot multiplikation med decimaler hoppar jag över til en annan gång, hehe
Nästa fråga blir då följande (om du orkar förklara, det uppskattas) :
Hur konverterar man lättast ett binärt tal till decimalt med flera siffror?
Ex.
Jag får resultatet b'00001111' av en operation och det ska skickas till två siffror på displayen varav den ena är 1 och den andra 5, resultatet är ju 15 decimalt.
Om det bara hade varit en siffra i resultatet så hade jag fixat det. Bara att ta det binära värdet och lägga på lookupen så är det klart. Nu är det svårare.
Nu bör jag väl få två värden på något sätt där den ena är b'00000101' (5) och den andra b'00000001' (=1)
Dessa värden använder jag som vanligt i lookupen och skickar multiplexat till displayerna.
Hur räknar jag fram dessa binära tal?
/Mattesnillet

Börja med att dra bort 10 från resultatet och kontrollera om det är mindre än 0 om inte dra bort 20 från resultatet och kontrollera om det är mindre än 0 o.s.v. När svaret är mindre än 0 så var det den föregående som var rätt, börja sedan att dra bort 1 från det överblivande resultatet är det mindre än 0 om inte dra bort 2 o.s.v....
Hoppas att du fattar
Sen klarar du kanske inte det med en PIC med tanke på att den andra spänningen som du skall mäta är negavit...
Hoppas att du fattar

Sen klarar du kanske inte det med en PIC med tanke på att den andra spänningen som du skall mäta är negavit...

Okej,
Hade det varit ett 8-bits värde från ADn så har jag nog klurat ut det.
Nollställ siffrorna
Ta AD värdet och minska med 1000
Blev det 0?
Gå vidare, annars öka "siffra1" med ett och loopa.
Minska återstående värde med 100
Blev det 0?
Gå vidare, annars öka "siffra2" med ett och loopa.
Minska återstående värde med 10
Blev det 0?
Gå vidare, annars öka "siffra3" med ett och loopa.
Samma sak fast med 1
Problemet nu är att jag har 8 bitar plus 2 bitar i ett annat register.
ADRESH och ADRESL ska räknas ner samtidigt?
Usch, det här var en hård nöt att klura ut när man är nybörjare =)
Ni får gärna fylla i så jag kommer vidare och kan börja skriva kod och simulera.
Hade det varit ett 8-bits värde från ADn så har jag nog klurat ut det.
Nollställ siffrorna
Ta AD värdet och minska med 1000
Blev det 0?
Gå vidare, annars öka "siffra1" med ett och loopa.
Minska återstående värde med 100
Blev det 0?
Gå vidare, annars öka "siffra2" med ett och loopa.
Minska återstående värde med 10
Blev det 0?
Gå vidare, annars öka "siffra3" med ett och loopa.
Samma sak fast med 1
Problemet nu är att jag har 8 bitar plus 2 bitar i ett annat register.
ADRESH och ADRESL ska räknas ner samtidigt?
Usch, det här var en hård nöt att klura ut när man är nybörjare =)
Ni får gärna fylla i så jag kommer vidare och kan börja skriva kod och simulera.
Som Jeppson skrivar kan man göra ett upprepade antal "dra av 10 och se om det gick bra" och räkna antalet upprepningar. Ska man dela 3000 på detta sätt blir det dock många upprepningar och för att få skapligt fast tid på rutinen ska man dela med 10, en gång för varje tal.
Sodjan länkade till en rutin på PICLIST som gjorde just detta, duger inte den?
Jag letade en aning och hittade detta, duger det? Du kanske inte behöver att förstå hur det fungerar, bara ATT det fungerar eller hur?
Senare kanske du fattar, det är inte så logisk innan man fattar det hela.
Sodjan länkade till en rutin på PICLIST som gjorde just detta, duger inte den?
Jag letade en aning och hittade detta, duger det? Du kanske inte behöver att förstå hur det fungerar, bara ATT det fungerar eller hur?
Senare kanske du fattar, det är inte så logisk innan man fattar det hela.
- bengt-re
- EF Sponsor
- Inlägg: 4829
- Blev medlem: 4 april 2005, 16:18:59
- Skype: bengt-re
- Ort: Söder om söder
- Kontakt:
Till den negativa spänningen använder du en OP-förstärkare enklast...
Mata opń med plus minus 12VDC. Dela ner -12 mot jord med någon passande faktor. Förstärk signalen OPń kopplad som en inverterad förstärkare , dela ev ner spänningen till dina 0 till 2,5V med en ny motstånds spänningsdelare.
EDIT:

Ungefär så, Väljer du den lösningen så får du med 2,5V ref ungefär fullt utslag vid 12VDC, ändra motståndsvärderna för önskad skalning
Mata opń med plus minus 12VDC. Dela ner -12 mot jord med någon passande faktor. Förstärk signalen OPń kopplad som en inverterad förstärkare , dela ev ner spänningen till dina 0 till 2,5V med en ny motstånds spänningsdelare.
EDIT:

Ungefär så, Väljer du den lösningen så får du med 2,5V ref ungefär fullt utslag vid 12VDC, ändra motståndsvärderna för önskad skalning
Mätarprojektet är lagt på hyllan tills vidare.
För det första så fanns det inte utrymme nog i chassit jag använde mig av, och för det andra blev jag inte klok på hur jag skulle göra för att räkna ner 10bitar (som ju är två register) och omvandla till siffror. Koden på piclist fungerade inte riktigt.
Tillsvidare kommer jag använda aggregatet endast med dom analoga mätarna. Behöver man finjustera så är det ju enkelt att koppla in en av multimetrarna till den.


Skönt att äntligen ha positiv och negativ spänning samlat i en och samma burk..
Två identiska aggregat på var sin trafolindning.
*Kan köra dom i serie, 0-60V, 3A,
*som två separata nätaggregat (utan elektrisk koppling alls),
*med en knapp kan jag få kanal två att förlja kanal ett (perfekt när man kör den i +- läge och vill ha samma spänning/strömgräns på båda)
*separat V/A inställning på varje halva och
Finns det intresse för detta aggregat så kan jag skapa en ny tråd om den där jag beskriver hur jag gick tillväga.
För det första så fanns det inte utrymme nog i chassit jag använde mig av, och för det andra blev jag inte klok på hur jag skulle göra för att räkna ner 10bitar (som ju är två register) och omvandla till siffror. Koden på piclist fungerade inte riktigt.
Tillsvidare kommer jag använda aggregatet endast med dom analoga mätarna. Behöver man finjustera så är det ju enkelt att koppla in en av multimetrarna till den.
Skönt att äntligen ha positiv och negativ spänning samlat i en och samma burk..
Två identiska aggregat på var sin trafolindning.
*Kan köra dom i serie, 0-60V, 3A,
*som två separata nätaggregat (utan elektrisk koppling alls),
*med en knapp kan jag få kanal två att förlja kanal ett (perfekt när man kör den i +- läge och vill ha samma spänning/strömgräns på båda)
*separat V/A inställning på varje halva och
Finns det intresse för detta aggregat så kan jag skapa en ny tråd om den där jag beskriver hur jag gick tillväga.
Här är kod för att omvandla 16bitar (från två register alltså) till fem siffror ASCII (för att skicka till LCD-modul) som jag skrev för en massa år sedan. Vill man inte ha ASCII utan vanlig BCD kan man skippa ASCIIconvEnd-delen. Kanske kan va nåt? Dåligt kommenterad tyvärr men det är ju inte så mycket kod.markusb skrev:Mätarprojektet är lagt på hyllan tills vidare.
För det första så fanns det inte utrymme nog i chassit jag använde mig av, och för det andra blev jag inte klok på hur jag skulle göra för att räkna ner 10bitar (som ju är två register) och omvandla till siffror. Koden på piclist fungerade inte riktigt.
Kod: Markera allt
;--------------------------------------------------------------------------------------------;
;Converts 16bit number in TEMP1/TEMP2 to ASCII dec ;
;--------------------------------------------------------------------------------------------;
ASCIIconv clrf digit5 ;1's digit
clrf digit4 ;10's digit
clrf digit3 ;100's digit
clrf digit2 ;1000's digit
clrf digit1 ;10000's digit
ASCIIconvLoop1 tstf TEMP1 ;
bz ASCIIconvLoop3 ;
ASCIIconvLoop2 decf TEMP1,F ;
call ASCIIconvInc ;
goto ASCIIconvLoop1 ;
ASCIIconvLoop3 tstf TEMP2 ;
bz ASCIIconvEnd ;
decf TEMP2,F ;
goto ASCIIconvLoop2 ;
ASCIIconvEnd movlw 48 ;ASCII "0"
addwf digit1,F ;
addwf digit2,F ;
addwf digit3,F ;
addwf digit4,F ;
addwf digit5,F ;
return ;
ASCIIconvInc incf digit5,F ;
movlw 10 ;
xorwf digit5,W ;
skpz ;
return ;
clrf digit5 ;
incf digit4,F ;
movlw 10 ;
xorwf digit4,W ;
skpz ;
return ;
clrf digit4 ;
incf digit3,F ;
movlw 10 ;
xorwf digit3,W ;
skpz ;
return ;
clrf digit3 ;
incf digit2,F ;
movlw 10 ;
xorwf digit2,W ;
skpz ;
return ;
clrf digit2 ;
incf digit1,F ;
return ;
Se där ja!
Ska sätta mig och lusläsa koden nu för att försöka lära mig hur det funkar.
Ev så kan man ju ha en lös displaylåda till aggregatet som man kan sätta vart man vill på arbetsbänken
..om jag får det att funka.
Har som sagt fått det att funka när jag bara räknar ner ett register (ADRESL) men det ger inte tillräcklig noggranhet.
Tack för hjälpen!
Ska sätta mig och lusläsa koden nu för att försöka lära mig hur det funkar.
Ev så kan man ju ha en lös displaylåda till aggregatet som man kan sätta vart man vill på arbetsbänken

Har som sagt fått det att funka när jag bara räknar ner ett register (ADRESL) men det ger inte tillräcklig noggranhet.
Tack för hjälpen!