Sida 2 av 5
Postat: 25 februari 2007, 16:51:08
av sodjan
OK, du kör den enklare (men något långsammare) metoden med upprepade
subtraktioner av 100 resp 10. OK, själva metoden är väl helt solklar
hoppas jag, annars borde du "torrsimma" den med papper och penna
med lite olika värden så att det sitter ordentligt.
Sen ska vi se på koden...
Som det ser ut så förväntar du en 100-talssiffra på enbart "1" eller "0", eller hur ?
Vad är h'30' i "movwf h'30'" ?
För 10-tals siffran gör du i princip samma sak, men med det som blev
över från "Omvandla1" men du behöver en räknare för att hålla reda på
hur många gånger du har dragit av 10. Något i stil med :
Kod: Markera allt
crlf tens ; tens är en tidigare definierad variabel...
movf Result, W ;Läs värdet till W, måste ligga för labeln !!
Omvandla3 ;Ental
sublw 10 ;Dra av 10.
incf tens, f ; Öka tens med 1
btfss W ;är värdet negativt? Ja=hoppa en instruktion
goto Omvandla3 ;upprepa OMvandla3
decf tiotal,f ; minska tens med 1 eftersom det nu är 1 för mycket...
addlw 10 ;Gör värdet positivt, är nu "ental".
movwf ental ; En tidigare definbierad varabel...
Vad "movwf 0x40 ;lägger värdet i registret" är förstår jag inte alls...
Sen, om du tror att du kan testa W-registret för "noll" med "btfss W" så har du fel !
Kolla beskrivningen av instruktionerna SUBLW och BTFSS. Det är bitarna
i STATUS registret du ska kolla, t.ex "BTFSS STATUS, C" eller något liknande.
Det får räcka tillsvidare...
Postat: 25 februari 2007, 17:04:20
av mr_fatise
Jo de är säkerligen inte den bästa metoden, var de första sättet som dök upp ur mitt huvud när ja skrev själv. Metoden skiljer dock lite från hur du tänkte tror ja! däremot så tänkte jag ta 10-talet och dela med 10 för att få fram andra siffran. Problemet är att jag förstör värdet för det ensifriga. Där ja tänkte dra av tio tills jag har ett ental.
>Som det ser ut så förväntar du en 100-talssiffra på enbart "1" eller "0", eller hur ?
Japp de stämmer precis de!
>Vad "movwf 0x40 ;lägger värdet i registret" är förstår jag inte alls...
Va nog mest bara för att spara den nånstans.
>Sen, om du tror att du kan testa W-registret för "noll" med "btfss W" så har du fel !
Kolla beskrivningen av instruktionerna SUBLW och BTFSS. Det är bitarna
i STATUS registret du ska kolla, t.ex "BTFSS STATUS, C" eller något liknande.
Trodde det när jag läste instruktionen i databladet, slarvsäkert!
Ska läsa på lite om STATUS registret, känns inte helt solklart.
Hur är min tanke att lägga ut 2bcd på samma port då? Ena på de första 4-bitarna och sedan 100tals siffran på de andra 4-bitarna genom multiplikation med 16. Borde det fungera?
Postat: 25 februari 2007, 17:12:11
av sodjan
> Jo de är säkerligen inte den bästa metoden,
Den är helt OK. Fördelen är att den är lätt att förstå...
> däremot så tänkte jag ta 10-talet och dela med 10 för att få fram andra siffran.
Förstår inte alls, ge ett exempel.
> Problemet är att jag förstör värdet för det ensifriga. Där ja tänkte dra av tio tills jag har ett ental.
"Entalet" är ju det du har kvar när du har dragit av "10" tillräckligt många gånger.
D.v.s "resten" som det heter.
> >Vad "movwf 0x40 ;lägger värdet i registret" är förstår jag inte alls...
> Va nog mest bara för att spara den nånstans.
Ange *aldrig* adresser på det sättet ! Använd assembler symboler.
> Ska läsa på lite om STATUS registret,..
Gör så, det är väldigt enkelt...
> Hur är min tanke att lägga ut 2bcd på samma port då?
Jag tycker inte att du ska blanda ihop det med själva bin => bcd omvandligen.
Se *först* till att omvandligen går bra, fundera *sedan* på presentationen
med multiplexning o.s.v. Varför röra till det ?
> genom multiplikation med 16...
Vilket är det samma som 4 shift/rotate eller en SWAP instruktion.
Postat: 25 februari 2007, 17:25:15
av mr_fatise
>Förstår inte alls, ge ett exempel.
Låt säga att vi har talet 53. Det talet delar vi med 10. Resultatet blir 5,3decimalt och borde väll bli 5 binärt? eller man kanske inte kan räkna så!
På det sättet så slår man ju även sönder talet för att använda det för att beräkna entalet.
>"Entalet" är ju det du har kvar när du har dragit av "10" tillräckligt många gånger. D.v.s "resten" som det heter.
Lättast kanske ändå är att räkna gångerna och sen så har man båda talen på en gång. SKa se om jag hittar nån bra info om hur man får fart på en räknare.
>Vilket är det samma som 4 shift/rotate eller en SWAP instruktion.
Ahh men då löste vi ett problem till. Då tar vi presentationen i ett eget steg.
Ska se om man får någon överblick på statusregistret också.
Postat: 25 februari 2007, 17:48:18
av sodjan
> SKa se om jag hittar nån bra info om hur man får fart på en räknare.
Det finns inget som heter "räknare" i en PIC !!
Det är bara en helt vanlig variabel som *DU* har valt
att använda för att "räkna" något. För PIC'en är det bara en
vanlig variabler som vilken som helst (som t.ex "Result").
För att öka/minska "räknaren" används oftast INCF/DECF
eller INCFSZ/DECFSZ.
> Låt säga att vi har talet 53. Det talet delar vi med 10.
Jo visst !
Helt OK, **OM** det hade varit enkelt att "dela med 10"...

Det är därför vi kör med metoden med "SUBLW d'10' " i en loop
istället...
> Då tar vi presentationen i ett eget steg.
Helt klart enklast.
Jag minns inte riktigt, kommer inte displayerna att multiplexas ?
Eller är de alla direktdrivna (statiskt) ?
Om de ska multiplexas, så sker det enklast med en rutin som
triggas av en timer med lämpligt intervall (för att inte få flimmer).
Postat: 25 februari 2007, 17:57:31
av sodjan
Ett par andra småsaker...
> sublw 10
Kan betyda "minska W med 8, 10 eller 16" beroende på hur MPASM är inställt.
Se direktivet RADIX i MPASM manualen kapitel 4.55 sidan 106.
Notera att default radix är hexadecimalt, så då fungerar din kod inte alls !
*Bäst* är att *alltid* ange konstanter med explicit radix.
Se kapitel 3.4 sidan 41 i MPASM manualen och tabell 3.3 sidan 42.
Alltså borde det stå så här :
> sublw d'10'
Samma sak så klart med "addlw 100" => "addlw d'100' "
och alla andra ställen....
Postat: 25 februari 2007, 18:52:27
av sodjan
Ett litet förtydligande. Jag skrev tidigare :
> Det finns inget som heter "räknare" i en PIC !!
De PIC's som har en CCP modul har möjlighet att köra
den (CCP modulen) som en "counter". Men det var inte
riktigt det som avsågs i frågan, antar jag...

Postat: 25 februari 2007, 20:38:54
av mr_fatise
>Det finns inget som heter "räknare" i en PIC !! Det är bara en helt vanlig variabel som *DU* har valt
att använda för att "räkna" något.
Ahhh, nu e jag med...
>Jag minns inte riktigt, kommer inte displayerna att multiplexas ?
Eller är de alla direktdrivna (statiskt) ?
Tanken från början var att köra multiplex, men som det ser ut nu så spar jag knappt några portar på det. Och det blir nästan enklast att bara köra det rakt ut till en BCD => 7segment krets.
Har betat av en del nu och tycker att "binär =>BCD" borde vara korrekt. Testade också att slänga ihop en SWAPF instruktion. Samt gått igenom koden ett antal gånger utan att "JAG" hittar några fel.
Dessvärre får jag ett error när jag ska köra ut det i HEX. =40 : Illegal opcode (ADRESH), verkar vara rrl som strular till de.
Lägger upp den fullständiga koden. Kommentera gärna, tror de flesta felen ska vara åtgärdade.
Kod: Markera allt
;Information Data
;PIC16F876A
;------inkludera definitioner----
#include <p16f876a.inc>
;-------Start--------------------
org 0x000
Result equ 0x20
Hundratal equ 0x21
Tiotal equ 0x22
Ental equ 0x23
TioEntal equ 0x24
Start
banksel PORTA ;Väljer rätt bank
clrf PORTA
banksel TRISB
clrf TRISB ;sätter alla I/O till utgångar
banksel TRISC
clrf TRISC ;sätter alla I/O till utgångar
banksel ADCON1 ;väljer rätt bank
movlw b'11001110'
movwf ADCON1 ;Frc, AN0 Analog, resten I/O
movlw b'00000001'
movwf TRISA ;sätter RA0 till ingång
movlw b'11000001'
movwf ADCON0 ;Frc A/Dchannel0 A/D=On
;---- Kör A/D omvanling---------
Kor
bsf ADCON0,GO ;Kör A/DChannel0
Wait
btfsc ADCON0,GO ;Väntar på resultat
goto Wait
bcf STATUS, C
rrl ADRESH, W ;Värdet divideras med 2
movwf Result ;255/2= 0-127
;-------Omräkning av värde-----------
Omvandla1 ;Om talet är över 100
movf Result, W
sublw D'100' ;Drar av 100. C biten blir 1 om minus.
btfss STATUS, C ;Hoppar över nästa instruktion om C biten är 1=negativ
goto Positiv
addlw D'100' ;Lägg till 100
addwf Result ;Ursprungligt värde
goto Omvandla2 ;Upprepa
Positiv ;Om talet är över 100
movwf Result
movlw b'00000001' ;över 100 värde
movwf Hundratal
Omvandla2
clrf Tiotal ;återställ räknaren
movf Result, W
Omvandla3 ;10-tal samt 1-tal
sublw D'10' ;Dra av 10
incf Tiotal, F ;Lägg till 1 i räknaren
btfss STATUS, C ;Negativt? Hoppa nästa instruktion
goto Omvandla3 ;upprepa
decf Tiotal, F ;Dra av 1
addlw D'10' ;Gör värdet positivt
movwf Ental
;------Presentation----------------
clrf TioEntal ;töm
swapf Tiotal, F ;flyttas 4-bitar uppåt
movfw Tiotal
movwf TioEntal ;lägger talet i bit4-7
movfw Ental
addwf TioEntal ;lägger talet i bit0-3
movfw TioEntal
movwf PORTB ;till seg1 och 2
movfw Hundratal
movwf PORTC ;till seg3
Goto Kor
END
PS: ska jag ha "Goto kor" i slutet eller ska jag bara ha END?
Postat: 25 februari 2007, 20:48:20
av Icecap
Du ska ha 'goto' med..... men 'Kor'???? Varför inte grisar? Hästar?
Det gör ont i mina ögon men denna svengelska som bara blir missvisande och otydlig och i slutskedet blir det källa till en massa intressanta fel.
'Kor'.... om du menar 'Kör' vore det generellt bättre att kanske kalla den 'Mainloop', 'HereWeGo', 'Main' eller liknande vettigt.
Fast du kan ju mena just Kor (Bregottfabrikens anställda typ) ..... vad det så har med programmet att göra.
Postat: 25 februari 2007, 21:44:18
av BEEP
Det går bra att använda Kor i koden men för att det ska fungera så måste man byta ut BSF till SJB,SLB eller SRB.
Postat: 25 februari 2007, 22:13:45
av mr_fatise
>Det gör ont i mina ögon men denna svengelska som bara blir missvisande och otydlig och i slutskedet blir det källa till en massa intressanta fel.
Vet inte riktigt om jag vågar mig på att ändra om det till ren engelska nu, blir väll bara nåt som säkert krånglar till alltihop. Men jag gör ett försök om de gör lättare att läsa. Kör på
Satsar på att kalla "Korna" till Mainloop istället också.
>Det går bra att använda Kor i koden men för att det ska fungera så måste man byta ut BSF till SJB ,SLB eller SRB.
Verkar inte funka. Får bara ytterligare ett error och en varning.
33 : Found label after column 1. (srb)
Error[122]
33 : Illegal opcode (ADCON0)
Tack för er tid måste ja säga också! Inga andra fel som ni ser direkt?
Postat: 25 februari 2007, 22:18:38
av sodjan
Postat: 25 februari 2007, 22:24:57
av mr_fatise
>Angående SJB ,SLB, SRB o.s.v.
Jag måste nästan små le lite när jag tänker på att du tog dig tid att leta upp den faktan! Låter mitt BSF stå kvar tror ja.
Postat: 25 februari 2007, 22:39:12
av sodjan
Tid och tid...
"SJB ,SLB, SRB" i Google, 5'te träffen i listan.
(Men jag visste innan att det är olika ko-raser...)

Postat: 25 februari 2007, 22:44:37
av mr_fatise
>Tid och tid...
Vissade engagemang iallfall..
Lägger även upp koden på engelska om det underlättar läsning.
Kod: Markera allt
;Information Data
;PIC16F876A
;------Include defintions----
#include <p16f876a.inc>
;-------Start--------------------
org 0x000
Result equ 0x20
Hundreds equ 0x21
Tens equ 0x22
Singels equ 0x23
TensSingels equ 0x24
Start
banksel PORTA ;Choose correct bank
clrf PORTA
banksel TRISB
clrf TRISB ;set all I/O at outputs
banksel TRISC
clrf TRISC ;set all I/O at outputs
banksel ADCON1
movlw b'11001110'
movwf ADCON1 ;Frc, AN0 Analog, rest I/O
movlw b'00000001'
movwf TRISA ;set RA0 at input
movlw b'11000001'
movwf ADCON0 ;Frc A/Dchannel0 A/D=On
;---- Run A/D converting---------
Mainloop
bsf ADCON0,GO ;Run A/D Channel0
Wait
btfsc ADCON0,GO ;Wait for Result
goto Wait
bcf STATUS, C
rrl ADRESH, W ;Value divided by 2
movwf Result ;255/2= 0-127
;-------Recalculate the Value-----------
Convert ;If the value is over 100
movf Result, W
sublw D'100' ;Subtract 100 from Value
btfss STATUS, C ;Negative? Skip next instruction
goto Positive
addlw D'100' ;Add 100
addwf Result ;Original Value
goto Convert2 ;Repeat
Positive
movwf Result
movlw b'00000001' ;BCD Value for 1
movwf Hundreds
Convert2
clrf Tens ;Clear the counter
movf Result, W
Convert3 ;10-tal samt 1-tal
sublw D'10' ;Subtract 10
incf Tens, F ;Add 1 to counter
btfss STATUS, C ;Negativ? Skip next instruction
goto Convert3 ;Repeat
decf Tens, F ;Subtract 1
addlw D'10' ;Make it positive
movwf Singels
;------Presentation----------------
clrf TensSingels ;Clear
swapf Tens, F ;Swap the first 4-bits
movfw Tens
movwf TensSingels ;Move Value into bit4-7
movfw Singels
addwf TensSingels ;Move value into bit0-3
movfw TensSingels
movwf PORTB ;to seg1 och 2
movfw Hundreds
movwf PORTC ;to seg3
Goto Mainloop
END