Mindre än 1? (ASM)

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Mindre än 1? (ASM)

Inlägg av squiz3r »

Hej, Jag har en kod som gör att en variabel (time) blir en siffra. Sen vill jag att om denna sifran är mindre än 35 så ska den gå till "label1", så då tänkte jag att man kan göra såhär:

Kod: Markera allt

movfw   time 
sublw    35 
btfsc     STATUS, Z 
goto     label1
Men sen kom jag på att Z "biten" reagerar väll bara om det blir 0, men jag vill att det ska reagera om det blir Tex. -6 också. dvs. allting som är noll eller under.

Hur gör jag då?

Tack på förhand!
//Daniel A
Användarvisningsbild
Marta
EF Sponsor
Inlägg: 7487
Blev medlem: 30 mars 2005, 01:19:59
Ort: Landskrona
Kontakt:

Inlägg av Marta »

Använd carry istället före zero.
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Okej. men carry sätts väll inte fören det blir under noll, vilket betyder att jag måste kolla zero också eller har jag fattat fel?
Då kan jag väll skriva koden såhär:

Kod: Markera allt

movfw      time           ;W = time - 35
sublw    35 
btfsc     STATUS, Z     ; om W = 0 gå till label1
goto     label1 
btfsc     STATUS, C     ; om W är mindre än 0 gå till label 1
goto     label1

........                       ; förtsätt här....
........
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Ladda ner " Instruction Set - PICmicro Mid-Range MCU Family"
http://ww1.microchip.com/downloads/en/D ... 31029a.pdf

Där finns det fler exempel än i databladet. T.ex för SUBLW finns
just det fall som du frågar om (d.v.s "resultat mindre än noll").

> Okej. men carry sätts väll inte fören det blir under noll,

Dra av 36 istället för 35...

Dessutom, väldigt viktigt !!!!!!!

Skriv *aldrig* "sublw 35 ", utan "sublw d'35'" (om du menar 35 decimalt)
eller "sublw h'35'" (om du menar 35 hexadecimalt) !!

Ange *alltid* radix på *alla* konstanter !
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Så nu har jag laddat ner den, den verkar ju ha bra exempel :)

>Dra av 36 istället för 35...
hmm... hur kunde jag låta bli o tänka på det? :?

Okej då ska jag skriva d'36' i stället

Tack så mycket!
//Daniel A
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

En liten "side-note" om att ange radix i koden...

Man ser ofta ett HEX-värde skrivet som t.ex 0x3B.

Detta format är i och för sig OK i MPASM, men personligen
föredrar jag formatet h'3B'. Anledningen är att detta format
kan användas till alla radix :

a'A' : ASCII tecken.
d'98' : decimalt.
h'3B' : hexadecimalt.
o'26' : oktalt.
b'00010000' : binärt.

Det finns ingen motsvarighet till "0x" formatet i de andra radix'en...

På så sätt får man ett konsekvent skrivsätt oavsett radix.
Snyggare tycker jag...
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Sodjan: Okej, då får jag ta och fixa till det där jag har skrivit det också :)

Men nu har jag skrivit ihop en kod som inte vill fungera som jag vill :shock: :

Kod: Markera allt

; Assign your microcontroller
        LIST P=16F628A

; This include file makes programming more understandeble
        include <P16F628A.INC>
        
        
    __CONFIG _CP_OFF & _DATA_CP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF

; save on free ram in bank0

delay_var1       	equ	20h
delay_var2       	equ	21h  
delay_var3       	equ	22h  

pause_var1			equ 23h

time				equ 24h

;define pinouts

#define  alarm		PORTA,2
#define  sw1		PORTB,2 
#define  sw2		PORTB,3 
#define  G_LED		PORTA,1 
#define  R_LED		PORTA,0 
#define  sens1		PORTB,5
#define  sens1_off	PORTB,4
#define  keypad		PORTB,0


;startadres of the controller
	 org 0x0000


; For using A0-A3 as digital I/O 
    	movlw	D'7' 		    ; 
            movwf	CMCON		; Comparators off, all pins digital I/O 

; Reset Port values
        clrf	PORTA	
        clrf	PORTB
        
; define your pin direction (input/output)

portb5_out

    bsf	STATUS, RP0	          ; Switch to bank 1
		movlw	b'00000000'	  ;
		movwf	TRISA		  ; PORTA = 0,1,2,3,4,5,6,7 out,

        movlw	b'00000000'	  ; 
        movwf	TRISB	      ; PORTB = b5 out
	bcf	STATUS, RP0	          ; Switch to bank 0
	goto step_1

portb5_in
	 bsf	STATUS, RP0	          ; Switch to bank 1
		movlw	b'00000000'	  ;
		movwf	TRISA		  ; PORTA = 0,1,2,3,4,5,6,7 out,

        movlw	b'00100000'	  ; 
        movwf	TRISB	      ; PORTB = b5 in
	bcf	STATUS, RP0	          ; Switch to bank 0
	goto step_2

; main loop


watch_resistans
	goto	portb5_out
	
step_1	
	bsf		sens1
	call	delay
	bcf		sens1
	movlw	0h
	movwf	time
	movlw	1h
	goto	portb5_in

step_2	
	addwf	time,f
	bsf		G_LED
	call	pause
	bcf		G_LED
	call	pause
	btfsc	sens1
	goto	step_2
	goto	step_3

step_3
	bsf		R_LED
	call	pause
	bcf		R_LED
	call	pause
    decfsz  time,1h
    goto    step_3
    goto	portb5_out
	
button1
	bsf		R_LED
	call	delay
	goto	watch_resistans	



; Delay routine 
; This code uses about 5 x 99975 instructions. At 4Mhz this is approx 500 milliseconds.

pause	movlw	0xFF
	    movwf	pause_var1	
pause2	decfsz	pause_var1,1		;     is placed in the file	
   		goto	pause2
		return

delay   movlw	0x5
	    movwf	delay_var3
delay1  movlw	0x5
	    movwf	delay_var2
delay2  movlw	0xFF
	    movwf	delay_var1
delay3	decfsz	delay_var1, f 
	    goto	delay3
	    decfsz	delay_var2, f
        goto	delay2
     	decfsz	delay_var3, f
        goto	delay1
    	return

        END
Den läser av ett motstånd med hjälp av "RC-TIME", när Jag har mätt i oscyloscopet så blinkar den den den gula leden (G_LED) 4ggr.
då den borde väll R_LED blinka lika många gånger som den gula? För att efter att den gula har blinkat fyra gånger blinkar den röda 29ggr :? Sedan satte jag på ett 2K (innan var det 10Kohm) motstånd i stället, då blinkade den gula 1ggr. o den röda 32ggr. Är det jag som har fattat något fel, eller?

//Daniel A
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Men nu har jag skrivit ihop en kod som inte vill fungera som jag vill

Kommentera koden så att det går att veta *vad* det är du vill...
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Här kommer koden med komentarer. Hoppas att dem är tydliga nog.

Kod: Markera allt

; Assign your microcontroller
        LIST P=16F628A

; This include file makes programming more understandeble
        include <P16F628A.INC>
        
        
    __CONFIG _CP_OFF & _DATA_CP_OFF & _BODEN_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _LVP_OFF

; save on free ram in bank0

delay_var1       	equ	20h
delay_var2       	equ	21h  
delay_var3       	equ	22h  

pause_var1			equ 23h

time				equ 24h

;define pinouts

#define  alarm		PORTA,2
#define  sw1		PORTB,2 
#define  sw2		PORTB,3 
#define  G_LED		PORTA,1 
#define  R_LED		PORTA,0 
#define  sens1		PORTB,5
#define  sens1_off	PORTB,4
#define  keypad		PORTB,0


;startadres of the controller
	 org 0x0000


; For using A0-A3 as digital I/O 
    	movlw	D'7' 		    ; 
            movwf	CMCON		; Comparators off, all pins digital I/O 

; Reset Port values
        clrf	PORTA	
        clrf	PORTB
        
; define your pin direction (input/output)

portb5_out

    bsf	STATUS, RP0	          ; Switch to bank 1
		movlw	b'00000000'	  ;
		movwf	TRISA		  ; PORTA = 0,1,2,3,4,5,6,7 out,

        movlw	b'00000000'	  ; 
        movwf	TRISB	      ; PORTB = b5 out
	bcf	STATUS, RP0	          ; Switch to bank 0
	goto step_1

portb5_in
	 bsf	STATUS, RP0	          ; Switch to bank 1
		movlw	b'00000000'	  ;
		movwf	TRISA		  ; PORTA = 0,1,2,3,4,5,6,7 out,

        movlw	b'00100000'	  ; 
        movwf	TRISB	      ; PORTB = b5 in
	bcf	STATUS, RP0	          ; Switch to bank 0
	goto step_2

; main loop


watch_resistans
	goto	portb5_out		;gör sens1 (portb5) till utgång 
	
step_1	
	bsf		sens1			;ladda upp kondensatorn
	call	delay
	bcf		sens1
	movlw	0h				;nollställ "time"
	movwf	time
	movlw	1h				;lägg 1hex i W registret
	goto	portb5_in		;ändra sens1 (portb5) till ingång

step_2	
	addwf	time,f			;time = time + 1 (lägg till 1h till "time")
	bsf		G_LED			;tändgul status LED
	call	pause			;pausa
	bcf		G_LED			;släck den igen
	call	pause			;pausa	
	btfsc	sens1			;kolla om kondensatorn fortfarande är uppladdad.
	goto	step_2			;om den är det gå till step_2 o lägg till 1 till i variablen m.m.
	goto	step_3			;annars gå till step_3

step_3						;visa hur många gånger den loopade i "step_2" loopen.	
	bsf		R_LED			;tänd röd LED	
	call	pause			;pausa	
	bcf		R_LED			;släck den igen
	call	pause			;pause igen
    decfsz  time,1h			;visa hur stor variablen är genom att köra denna loopen lika många gånger
    goto    step_3			;om variablen fortfarande innehåller något gå till baks till "step_3" 
    goto	portb5_out		;annars kör hela processen igen....
	
button1						;********************************************
	bsf		R_LED
	call	delay			;Detta används inte nu....		
	goto	watch_resistans	;*********************************************





pause	movlw	0xFF			;*************************************
	    movwf	pause_var1		;gör en kort pause
pause2	decfsz	pause_var1,1	;	
   		goto	pause2			;
		return					;*************************************

delay   movlw	0x5				;*************************************
	    movwf	delay_var3		;
delay1  movlw	0x5				;
	    movwf	delay_var2		;gör en lång pause
delay2  movlw	0xFF			;
	    movwf	delay_var1		;
delay3	decfsz	delay_var1, f 	;
	    goto	delay3			;
	    decfsz	delay_var2, f	;
        goto	delay2			;
     	decfsz	delay_var3, f	;
        goto	delay1			;
    	return					;**************************************

        END
//Daniel A
Maalobs
Inlägg: 1304
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Inlägg av Maalobs »

sodjan skrev:En liten "side-note" om att ange radix i koden...

Man ser ofta ett HEX-värde skrivet som t.ex 0x3B.

Detta format är i och för sig OK i MPASM, men personligen
föredrar jag formatet h'3B'. Anledningen är att detta format
kan användas till alla radix :

a'A' : ASCII tecken.
d'98' : decimalt.
h'3B' : hexadecimalt.
o'26' : oktalt.
b'00010000' : binärt.

Det finns ingen motsvarighet till "0x" formatet i de andra radix'en...
Jo, för oktalt finns det ju det, nämligen "0".
Fast jag vet inte om det är med i Microchips värld, och det var kanske i det sammanhanget du menade att det inte existerar något liknande.
Ett exempel med Perl one-liners:

Kod: Markera allt

$ perl -we "print 011"
9
$ perl -we "print 11"
11
$ perl -we "print 0x11"
17
Om jag minns rätt kommer det här från standard c.lib, så resten av världen funkar mestadels så här.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Fast jag vet inte om det är med i Microchips värld,

Hela resonemanget rör naturligtsvis vad som accepteras av MPASM,
d.v.s assembler för PIC's. Se tablell 3-3 på sidan 42 i MPASM manualen.

> Ett exempel med Perl...

Perl är (ö-) känt för att acceptera nästan vad som helst... :-)
Maalobs
Inlägg: 1304
Blev medlem: 3 februari 2005, 14:35:15
Ort: Stockholm

Inlägg av Maalobs »

Det har inte så mycket med egenskaper i Perl att göra, det är en ärvd egenskap av standard C libbet som den och alla andra program skrivna i C är länkade mot.
En googling hittade:
"leading 0X or 0x implies hexadecimal, leading 0 implies octal, otherwise decimal"
Under stdlib.h:
http://www.csse.uwa.edu.au/programming/ ... brary.html
Men som sagt, man använder ju inte direkt det kompletta ANSI C-biblioteket när man utvecklar mot mikrokontrollers, om man nu ens skulle få för sig att göra sådant i C.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> "leading 0X or 0x implies hexadecimal, leading 0 implies octal, otherwise decimal"

OK, visst...

*Problemet* är att man i MPASM kan ställa om "default radix", så att
ett värde helt utan prefix kan i princip betyda vad som helst (så länge
värdet i sig är giltigt så klart).

Min rekomendation kvarstår, ange alltid radix-prefix, och kör med det format
som ser likadant ut oavsett radix (för läsbarhetens och konsekvensens skull).

Och igen, detta gäller MPASM, I couldn't care less hur det ser ut i std-C... :-)
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Ingen som kan se något fel i min kod? Jag har gått igenom den gång efter gång men som sagt så vill den inte....

Myckat tacksamföralla svar!
//Daniel A
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Nja, jag vet inte vad som går fel, men ett par saker i alla fall...

PÅ ett ställe står det "; main loop" och sedan kommer labeln "watch_resistans".
Lite längre ner kommer "goto watch_resistans".

Så långt är det OK, detta borde alltså vara just "main loop".

**Men** i koden i denna loop så finns det "goto" till labels som
ligger **utanför** loopen (till "portb5_in" och "portb5_out").
Inte alls snyggt ! Alla anrop till kod som ligger *utanför* main-loop
borde ska vara call's till subrutiner.

Gör de två port5_xx rutinerna till subrutiner och avsluta med return istället.
Du får komplettera med en extra "goto step_1" efter det andra anropet
till portb5_out, men det blir i alla fall snyggare så.

Jag skulle föreslå att du städer upp strukturen i programmet.
Kanske att problemet som du ser försvinner på samma gång, vem vet.

>step_2
> addwf time,f ;time = time + 1 (lägg till 1h till "time")

Hur vet du att du lägger till just + 1 ?? Var kommer ettan från ???

> decfsz time,1h

Om det är "decfsz time, f" som avses så är det bättre att skriva så.
Använd alltid "w" eller "f" som "destination".
Skriv svar