Sida 1 av 2

PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 6 september 2009, 14:21:50
av net4all
Hej!
Har precis gått över från C till asm och har skrivit ett program som ska blinka en lysdiod i 0.5 sek intervaller.

Givetvis fungerar det inte :humm:
Använder Wisp628 för programmering, allt ok där, inga felmedelanden.
MCLRE sitter med 10kohm till VDD.
På RC4 har jag först 1kohm och sedan en lysdiod till GND (lysdioden testad, funkar fint)
Matningen får genom en 7805, får 4.93V. Sitter även en 47uF elektrolyt över matningen
(Vänd åt rätt håll)
Samt en tantal direkt vid PICen.

Lysdioden tänds, men den släcks inte, bara lyser.

Så jag tror det är ett mjukvaru/nybörjarfel :)

Koden:

Kod: Markera allt

;"Base" program for the 16F886 processor, Version 0.1
;Made by Net4All net.4.all@hotmail.com

	Processor 16F886
	LIST P=PIC16F886
	#include <p16f886.inc>
	__config _CONFIG1, _WDT_OFF & _LVP_OFF & _BOR_OFF & _DEBUG_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTOSCIO
	__config _CONFIG2, _WRT_OFF 

	org 0x00
	;clrf PCLATH ;The program will later be used with a bootloader
	;pagesel main 
	goto main
	
	cblock ;some vars used by the 0.5 sec delay routine
	d1
	d2
	d3
	endc


init ;Setup all modules in the PIC (TRIS,Interrupt,ADC,CMP,CCP,Timers)
	;we use 4Mhz intosc, no matter what the config says
	movlw 0x61 
	banksel OSCCON
	movfw OSCCON
	
	;Now, disable interrupts
	banksel PIE1
	clrf PIE1
	banksel PIE2
	clrf PIE2
	banksel INTCON
	clrf INTCON

	;Set all pins to inputs
	movlw 0xff
	banksel TRISA
	movfw TRISA
	banksel TRISB
	movwf TRISB
	banksel TRISC
	movfw TRISC
	
	;ADC off
	banksel ADCON0
	clrf ADCON0
	banksel ADCON1
	clrf ADCON1
	banksel ANSEL
	clrf ANSEL
	banksel ANSELH
	clrf ANSELH	

	;CCP off
	banksel CCP1CON
	clrf CCP1CON
	banksel CCP2CON
	clrf CCP2CON
	
	;CMP off
	banksel CM1CON0
	clrf CM1CON0
	banksel CM2CON0
	clrf CM2CON0
	
	;Disable timers
	banksel T1CON
	clrf T1CON
	banksel T2CON
	clrf T2CON
	banksel OPTION_REG
	clrf OPTION_REG
	
	banksel SSPCON
	clrf SSPCON
	return 

delay ;A delay routine, delays 0.5 sec at 4Mhz, made using http://www.piclist.com/techref/piclist/codegen/delay.htm
	banksel d1
	movlw	0x03
	movwf	d1
	movlw	0x18
	movwf	d2
	movlw	0x02
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

	goto	$+1
	goto	$+1
	goto	$+1
	return

	

main
	call init ;Initiate port, and all the rest
	banksel TRISC
	bcf TRISC,4 ;RC4 output
loop
	banksel PORTC
	bsf PORTC,4 ;turn on led
	call delay ;wait 0.5 sec
	banksel PORTC
	bcf PORTC,4 ;switch off led
	call delay ;wait another 0.5 sec
	goto loop ;over and over

	end ;we will never get here
Det är det första jag har skrivit i "ren" asm och jag antar att det finns *massor* med saker som kan göras bättre.
MEN, borde inte den här koden funka, även om den är dåligt skriven?

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 6 september 2009, 14:57:19
av hcb

Kod: Markera allt

 goto delay ;wait 0.5 sec
Det borde nog vara

Kod: Markera allt

call delay

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 6 september 2009, 16:47:05
av net4all
Gjorde ingen skillnad :(
Har dock testat med ett annat program(gjort i C) och där fungerar det fint, så hårdvaran är garanterat rätt.

(går igenom asm koden från CC5X(C) programmet och ser om jag fattar varför det funkar)

EDIT: Testat ytterligare ett program, gjort i asm, där lysdioden styrs av en knapp på RC5. Funkar finfint :?
Tror det kan vara något fel i delay-rutinen, har dock inte en aning om vad..

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 6 september 2009, 18:41:35
av hcb
OK, en sak till: den sista raden

call loop

skall ändras till

goto loop

Har du provat att stega igenom programmet i MPLAB-SIM?

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 6 september 2009, 19:08:01
av net4all
MPLAB-SIM? :?:
(kollar upp på google)

Sista call-goto fixat, ändrar koden i första inlägget till den nuvarande.

MPLAB-SIM, hur kunde jag missa det?
Nåja, felet ligger i delay rutinen(enligt simulatorn)
Allt funkar fint, tills den går in i delayrutinen.
När den kommer till "Delay_0"(en label) så tar den ett "skutt" och hamnar i init-rutinen istället?!
Stämmer perfekt med att lysdioden inte släcks..

Kod: Markera allt

Delay_0
	decfsz	d1, f
	goto	$+2
Hmm, vad är f? (letar i datablad)

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 6 september 2009, 20:10:39
av vfr
f är file registry. I motsats till W t.ex.

Använd alltid lablar på goto och call. Annars har du ingen riktig koll på var den egentligen tar vägen. $+x betyder olika saker på PIC18 och PIC16. Det gör att koden är mycket svårare att porta, om du skulle vilja det så småningom.

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 7 september 2009, 00:24:26
av sodjan
> decfsz d1, f
> Hmm, vad är f ? (letar i datablad)

Det framgår dels av beskrivningen av DECFSZ, dels av den generella
beskrivningen av instruktionsformatet som finns på 1-2 sidor i
början av kapitlet med instruktionera. Var letade *du* ?

> När den kommer till "Delay_0"(en label) så tar den ett "skutt" och hamnar i init-rutinen istället?!

Här är jag inte med. Vilken instruktion kör den och vilken kör den inte.
Jag tror aldrig SIM stannar på en label. Exakt hur hoppar koden ?

Och om inte koden i första inlägget längre är den aktuella (som du har problem med)
så posta gärna den aktuella versionen. Om du fortfarande har problem, vill säga....

Lägg gärna CBLOCK'et före den första ORG, det blir lite rörigt (och jag är
inte 100% säker på att det är korrekt) att lägga CLOCK inne i ett block med
exekverbar kod. Sannolikt OK, men inte snyggt.

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 7 september 2009, 21:02:16
av net4all
Nu blev det ett uppehåll här (mycket läxor)

Den senaste koden är den som finns i första inlägget (Bytte ut den tidigare)
Men det kanske är bättre att ha kvar gammalt och posta nytt?

Med "skuttet" så menar jag att när den kommer till labeln "Delay_0" och då ska köra:

Kod: Markera allt

Delay_0
   decfsz   d1, f
   goto   $+2
Så hamnar den uppe i init-rutinen("banksel OSCON" står pilen på efter att den kör decfsz instruktionen)

(Ändrade CBLOCK enligt sodjans instruktioner, men fortfarande samma fel)

Det jag funderar på är om antingen felet orsakas av att f bestämmer var resultatet ska lagras, dvs det kan hamna i W och loopen låser sig.
Eller om "goto $+2" inte gör det som skaparen hade tänkt sig.
(Delay rutinen har jag fått från Piclist )

Jag ska gå ut och testa dom två sakerna(f och goto) nu, får se om det löser sig..

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 7 september 2009, 21:50:07
av BMI
Varför använda "goto $+2" när det finns labels och hoppa från-till ?
Säger inta att det är det som är felet ,om man räknat rätt.

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 7 september 2009, 22:39:20
av sodjan
Om du kollar vilka symboler som din CBLOCK skapar så hittar du felet.
Du bör även få ett "Message[313]" när du bygger koden som också
ger en ledtråd till att något inte står rätt till.

> Men det kanske är bättre att ha kvar gammalt och posta nytt?

Nej, det räcker med att i ett (nytt) inlägg säga att koden är utbytt (i första inlägget).
Eller lägga in den nya koden i ett eget nytt inlägg för att inte förstöra samanhanget i tråden.
Det får du avgöra vilket som blir tydligast. Bara det framgår vad som gäller...

EDIT:
Jag kan tillägga att så som din kod ser ut så är betendet helt förväntat och logiskt.
Den gör helt enkelt som den är tillsagd... :-)

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 7 september 2009, 23:11:20
av net4all
Aha, jo, jag får en msg313.
Så cblock är bara för konstanter och inte variabler?

Så man borde använda tex "res" istället?
dvs:

Kod: Markera allt

d1 res 1
d2 res 1
d3 res 1
Edit: Ang. "goto $+2" Jag har inte skrivit delay-koden, den är skriven av ett program, härifrån

Edit2: Såg sodjans edit, Asm-nybörjarfel med andra ord :roll:

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 8 september 2009, 09:33:01
av bos
> Så cblock är bara för konstanter och inte variabler?

Om du tittar i hjälpen för MPASM, söker på "cblock" och sen läser exempelkoden längst ner på den sidan så får du både svar och ett konkret exempel på frågeställningen.

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 8 september 2009, 10:04:25
av sodjan
> Så cblock är bara för konstanter och inte variabler?

CBLOCK skapar en (eller flera) *symboler* med stigande värde.
Startvärdet sätts med en parameter till CBLOCK. Detta är alltså
bara symboler med ett numeriskt värde. CBLOCK har inte någonting
alls med hur du sedan väljer att *använda* dessa symboler. En vanlig
användning är som adress parameter i olika kommandon, men det väljer du.
CBLOCK gör ingen "allokering" av minne alls ! Detta missförstås ofta. En
CBLOCK med några symboler är i princip samma sak som ett antal EQU
med samma symboler, skillnaden är bara att CBLOCK själv räknar upp värdena.

RES är en helt annan sak, och det är "rätt" metod för att allokera minne
till sina variabler. Notera att du inte bara kan byta CBLOCK mot RES rakt av,
du måste även göra övriga ändringar för att konvertera koden till "relocatable mode".
Se : http://www.jescab.se/Relocmode.html och http://www.jescab.se/abs_reloc.html

Jag antar att du nu har sett vad problemet med din kod var. Om du bara lägger till
h'20' till ditt CBLOCK direktiv så tror jag att det fungerar. Och att du nu även har
förstått vad det var som faktiskt hände i din kod. Du har en symbol som heter "d3"
som du ger värdet h'02' med din CBLOCK. När du sedan flyttar h'02' till "d3" så kommer
du att skriva h'02' till PCL (eftersom PCL ligger på adress h'02'), alltså en "calculated
GOTO" som det kallas i databladet). Koden hoppar därför till den instruktion i början av
programmet som råkar ligga på adress h'02'. Klart som korvspad... :-)

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 8 september 2009, 10:27:31
av vfr
CBLOCK kan närmast jämföras med en "struct" i C. Den definierar bara "fälten" inom en struktur. Sedan kan den användas för antingen variabler eller konstanter allt efter behov.

Re: PIC16F886 + ASM (asm nybörjarhjälp)

Postat: 8 september 2009, 11:43:05
av sodjan
> Sedan kan den användas för antingen variabler eller konstanter allt efter behov.

Nej, CBLOCK definierar enbart konstanta symboler (Constant BLOCK). Det är inte
CBLOCK i sig som kan "användas för variabler", utan de definierade symbolerna !

CBLOCK skapar inga "fält", den skapar enbart symboler. Jämförelsen med en
struct i C haltar en del, eftersom en struct även allokerar lagringsutrymme för
innehållet i structen (när den används i en typedef), bättre kanske att jämföra
med en "enum" typ, även om det inte heller är helt korrekt. Allra bäst är att
inte försöka jämföra med C alls... :-)

Det är heller ingen skillnad på en symbol som har skapats med EQU och en
som skapas med CBLOCK i den vidare bearbetningen. MPASM ser ingen
skillnad alls, de är båda bara symboler med ett värde.

Det är en viktig skillnad som är central för att förstå skillnaden mellan EQU
och CBLOCK jämfört med RES (som ju faktiskt även *allokerar* minne !)

Den mest naturliga användningen av CBLOCK är för att definiera t.ex olika
status värden eller liknande :

CBLOCK ; error codes
ERR_NO_DATA
ERR_NO_COMMAND
ERR_NO_VALUE
ERR_WRONG_VALUE
...
ENDC

CBLOCK ; process status
PROC_IDLE
PROC_BUSY
PROC_WAITING
PROC_READING
PROC_WRITING
...
ENDC

I sådana fall vill man bara ha olika symboler/konstanter som sedan
används i koden. Att både ERR_NO_DATA och PROC_IDLE har samma
värde spelar i det fallet ingen som helst roll. Och det spelar inte heller
någon roll vilket faktisk värde de olika symbolerna har eftersom de alltid
används "symboliskt" i alla fall.

Sedan använder man RES för att definiera de variabler som är tänkta
att *innehålla* dessa felkoder och processtatus.