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
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
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..
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:
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:
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

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.