Sida 1 av 1

PIC ASM-vill inte som jag vill.. *LÖST!*

Postat: 11 mars 2007, 13:56:31
av squiz3r
Hej,
Jag har en kodsnutt som jag ska ha till mitt larm, den ska kolla sens1 pinnen, men endast om ingången sw1 är hög... Men oavsett om den ärhög eller låg så struntar den att kolla sens1 pinnen :? någon som kan se varför?

Kod: Markera allt

main_loop
                call watch_sens1
                goto watch_sw1

watch_sens1
	movf	sens_1_var,F         ;kolla om sens_1_var är 0 eller 1
	BTFSS	STATUS, Z             ;om den är 1 dvs, om 
	return                                    ;ingången är hög, gå till baks
	BTFSC        sens                     ;If sens1 high then...
	goto 	breaking_time       ;somebody breaking in	
	return

watch_sw1
	BTFSC	sw1                      ;om switch1 är hög...
	goto 	off_sens1              ;gå till off_sens
	bsf	LED1                    ;annars tänd LED1
	movlw	0h                       ;och lägg en nolla i
	movwf	sens_1_var           ;sens_1_var
	goto	main_loop            ;gå tillbaks till main_loop

off_sens1
	bcf	LED1                    ;släck LED1
	movlw	1h                       ;och flytta en 1.a...
	movwf	sens_1_var           ;till sens_1_var
	goto	main_loop            ;gå till baks till main_loop
Tack på förhand!
//Daniel A

Postat: 11 mars 2007, 20:23:46
av squiz3r
Problemet är löst! Jag satte bara en variabel fel.

//Daniel A

Postat: 11 mars 2007, 20:30:17
av Icecap
Du läsar alltså HELA byten ("movf sens_1_var,F") och setter/resetter Z-flaggan. Om du enbart använder bit 0 ville det vara bättre att testa denna bit ("btfss sens_1_var,0")

Men jag lurar en hel del på "BTFSC sens".... vad kollar du där? Alltså vilken bit?

Postat: 11 mars 2007, 20:35:46
av squiz3r
>Men jag lurar en hel del på "BTFSC sens".... vad kollar du där? Alltså vilken bit?

Oj glömde jag säga, det är en ingång som är döpt till det.

Postat: 11 mars 2007, 20:39:24
av squiz3r
Så om man bara har en 1 eller nolla använder man bara en bit, o kan kolla den med "bit test f..." i så fall är det ju lättare o bättre =)

tack!
//Daniel A

Postat: 11 mars 2007, 21:50:21
av sodjan
> Så om man bara har en 1 eller nolla...

Variabler som bara kan vara "1" eller "0" brukar kallas "flaggor" ("flags").
Du kan ha 8 flaggor i varje register i RAM minnet. T.ex :

FLAGS RES 1 ; reservera ett register för 8 flaggor.

#DEFINE FLAG1 FLAGS, 0 ; Definiera ett namn på varje flagga.
#DEFINE FLAG2 FLAGS, 1
#DEFINE FLAG3 FLAGS, 2
#DEFINE FLAG4 FLAGS, 3
#DEFINE FLAG5 FLAGS, 4
#DEFINE FLAG6 FLAGS, 5
#DEFINE FLAG7 FLAGS, 6
#DEFINE FLAG8 FLAGS, 7

Och sedan i koden :

bsf flag1 ; Sätt flagga 1
bcf flag4 ; Cleara flagga 4

btfss flag2 ; Testa om flagga 2 är "1"
btfsc flag5 ; Testa om flagga 5 är "0"

o.s.v

Naturligtsivs ska de ha bättre namn än "flag1" o.s.v
som talar om vad de är till för.

Postat: 12 mars 2007, 20:13:08
av squiz3r
Om man har en flagga som är 1, och man tar den + 1 blir den 0 då eller?

Edit: om jag inte har helt fel för mig så kan jag väll skriva "sens_flags equ 25h" för "RES", "EQU" och "cblock" gör väll samma sak?

//Daniel A[/code]

Postat: 12 mars 2007, 21:00:14
av sodjan
En flagga är en flagga och är (konceptuellt) bara logiskt "på" eller "av".
Så att *räkna* med dom är i princip aldrig rellevant.
Varför ska du lägga till 1 till något som bara kan vara är "på" eller "av" ??
Du lägger ju aldrig till 1 till strömbrytaren på väggen...
Flaggor hanteras i princip enbart med BSF, BCF, BTFSC och BTFSS.

Angående RES kontra EQU/CBLOCK...

EQU och CBLOCK gör *i princip* samma sak.
De används då man skriver kod i det gamla formatet som kallas
"absolut mode".
EQU och CBLOCK sätter bara ett värde på en konstant (symbol)
i assembler koden. Det *reserverar* inte någon minnesplats,
vilken många ibland tycks tro. Det finns alltså ingenting som hindrar
att man skriver "sens_flags1 equ 25h" och "sens_flags2 equ 25h" (d.v.s
att man av misstag satte värdet h'25' på båda). MPASM kommer *inte*
att klaga och du kommer att få väldigt konstiga fel tills du upptäcker felet.

Alltså, om man gör "var1 equ h'25' ", så har MPASM inte en aning om att
*du* menar att var1 är en variabel på adress h'25'. Det är bara en symbol
med ett värde som vilken annan symbol som helst.


RES används när man skriver kod i det modernare formatet
"relocatable mode". RES inte bara ger en symbol ett värde utan den
*reserverar* också en RAM address för variabeln. Väldigt stor
skillnad, det betyder att en annan variabel inte *kan* råka dela
adress med den första. Dessutom så anger man (normalt) inte några
adresser, utan det överlåter man till MPASM/MPLINK att reda ut.
Variabler kan alltså hoppa runt lite hur som helst mellan varje "build",
vilket inte är något problem alls. Det är i princip helt *ointressant* vilken
adress en viss variabel ligger på. Om man ändå är nyfiken och måste
veta, så finns alla allokeringar i MAP filen (som MPLINK skapar).

Alltså, om man gör "Var1 res 1" så vet MPASM att Var1 är en variabel
i RAM-minnet på en viss adress (som allokeras automatisk från de
lediga adresserna). Eller, för att vara helt korrekt, den slutgiltiga adressen
allokeras av MPLINK, MPASM bara vet *att* det är en RAM variabel.

See även : http://www.jescab.se/Rellocmode.html

Postat: 12 mars 2007, 21:12:16
av squiz3r
Okej, det var ungefär som jag hade för mig angående "RES".
Det har jag fått att funka nu också :D

Men angående flaggorna, så hade jag behöft ha en flagga som när jag får en puls på en ingång så ska den ändra läge, så omden är 1 ska den bli 0, är den 0 ska den bli 1. Det är det jag inte vet hur man gör i asm. I Pbasic skrev jag:

...
variabel1 = variabel1 + 1
if variabel1 = 2 then variabel1 = 0
...


På det viset var den *alltid* 1 eller 0.

Tack!
//Daniel A

Postat: 12 mars 2007, 21:20:20
av Icecap
Om man har flaggan i en byte som man har definierat "som vanligt" är det ganska enkelt:

Flags res 1 ; Reserverar hela byten till flaggor

Flag0Toggle equ h'01' ; Används för att flippa bit 0

Flip-Flag:
movlw Flag0Toggle ; Ladda in vilket bitmönster som det ska togglas med
xorwf Flags,F ; Sådär, nu har bit 0 bytt läge

Postat: 12 mars 2007, 21:27:45
av sodjan
T.ex:

Kod: Markera allt

   btfsc   flags, flag1   ; skip if flag1 is clear
   goto    clear_flag1    ; flag1 was set, goto clear_flag1
   bsf     flags, flag1   ; set flag1
   goto    endof_flag1
clear_flag1
   bcf     flags, flag1   ; clear flag1
endof_flag1
   ...
   ...
Ovanstående kan göras till ett "toggle-flag" macro, så blir det inte så
mycket att skriva i koden och den blir mer lättläst.

Icecap's förslag fungerar också, *men* den skriver sönder värdet i W.
Om man behöver spara undan och hämta tillbaka värdet i W så blir
det lika många instruktioner som i mitt fall. :-)

Notera att PIC18 serien har förrutom "Bit Set f" och "Bit Clear f" även
ett "Bit Toggle f" (BTG) som gör allt i *en* instruktion... :-)

Postat: 13 mars 2007, 10:00:48
av squiz3r
Okej :) jag förstår inte riktigt men jag får labba lite med det o se om jag får det att fungera.

Tack!
//Daniel A

Postat: 13 mars 2007, 11:42:13
av sodjan
> jag förstår inte riktigt...

Bara fråga på... :-)