Skrivning av första assembler kod! kört fast

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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...
mr_fatise
Inlägg: 93
Blev medlem: 22 september 2004, 03:24:49

Inlägg 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?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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.
mr_fatise
Inlägg: 93
Blev medlem: 22 september 2004, 03:24:49

Inlägg 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å.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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).
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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....
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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... :-)
mr_fatise
Inlägg: 93
Blev medlem: 22 september 2004, 03:24:49

Inlägg 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?
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg 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.
Användarvisningsbild
BEEP
EF Sponsor
Inlägg: 1593
Blev medlem: 21 januari 2006, 16:57:56
Ort: Mölndal

Inlägg 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.
mr_fatise
Inlägg: 93
Blev medlem: 22 september 2004, 03:24:49

Inlägg 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?
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Angående SJB ,SLB, SRB o.s.v.

http://www.arla.se/Default____19232.aspx
mr_fatise
Inlägg: 93
Blev medlem: 22 september 2004, 03:24:49

Inlägg 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.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg 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...)

:-)
mr_fatise
Inlägg: 93
Blev medlem: 22 september 2004, 03:24:49

Inlägg av mr_fatise »

>Tid och tid...

Vissade engagemang iallfall.. :D

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