Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

PIC: (simpel) assembler probleem...

Pagina: 1
Acties:

  • almightyarjen
  • Registratie: Maart 2002
  • Laatst online: 22:31

almightyarjen

When does the hurting stop?

Topicstarter
Ik ben een beetje aan het klooien met PIC's, ik ben er nieuw mee.

Ik gebruik MPLAB met de simulator. Ik heb een simpel programma geschreven:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
           ORG    0x000
           CLRF   PORTA 
           BSF    STATUS,RP0 
           CLRF   TRISA  
           BCF    STATUS,RP0 

           MOVLW    7 
           MOVWF    CMCON         ; Comparators off, all pins digital I/O 

Main    MOVLW 00H       
           MOVWF    Count
           MOVWF    PORTA   
           INCF Count,1
           INCF Count,1
           INCF Count,1
           INCF Count,1
           INCF Count,1
           INCF Count,1
           MOVLW    Count
           MOVWF    PORTA
           NOP
           GOTO Main

Vraag even niet om het nut van het programma wat dat is er niet :P Via de simulator kan ik de waarden van de variabele Count en PORTA volgen. Na de reeks INCF-codes is de waarde van Count 0x06, dit is juist. Vervolgens wordt deze waarde geplaatst via W in PORTA geplaatst. Maar na het commando " MOVWF PORTA" bevat PORTA de waarde 0x02, en niet 0x06. Waarom??

Patreon | Main Youtube | Work In Progress Youtube


  • Sprite_tm
  • Registratie: September 2002
  • Laatst online: 29-10 06:07

Sprite_tm

Semi-Chinees

Als ik mij de pic-architectuur een beetje herinner (jaaaaren terug) bevat PORTA niet de waarde die je er zojuist heengeschreven hebt, maar de fysieke waarde van de pinnetjes van poort A. Als je daar dus iets aan hebt hangen (virtueel dus) of niet alle pinnetjes op die pic aanwezig zijn, kan het best zijn dat je daar inderdaad niet 0x06 uit leest.

Relaxen und watchen das blinkenlichten. | Laatste project: Ikea Frekvens oog


  • Theuno
  • Registratie: Juni 2001
  • Laatst online: 23:37

Theuno

Da Devil Crew

Schrijf eens naar LATA

(latch, zie manual voor de rest van de uitleg)

Ohja, en zet PORTA als output. De uitleg van Sprite is volgens mij verder correct.

[ Voor 37% gewijzigd door Theuno op 17-12-2008 22:32 ]

Theuno - Da Devil Crew - Een programmeur is iemand die koffie omzet in software...
Nu nog betere koffie...


  • almightyarjen
  • Registratie: Maart 2002
  • Laatst online: 22:31

almightyarjen

When does the hurting stop?

Topicstarter
Sprite_tm schreef op woensdag 17 december 2008 @ 22:00:
Als ik mij de pic-architectuur een beetje herinner (jaaaaren terug) bevat PORTA niet de waarde die je er zojuist heengeschreven hebt, maar de fysieke waarde van de pinnetjes van poort A. Als je daar dus iets aan hebt hangen (virtueel dus) of niet alle pinnetjes op die pic aanwezig zijn, kan het best zijn dat je daar inderdaad niet 0x06 uit leest.
PORTA had ik al als uitgang gedefinieerd:
code:
1
2
3
4
5
        ORG    0x000           ; Program starts at 0x000 
        CLRF   PORTA           ; Initialize port A 
        BSF    STATUS,RP0      ; RAM bank 1 
        CLRF   TRISA           ; All pins port A output 
        BCF    STATUS,RP0      ; RAM bank 0


Het heeft met het schrijven naar het W-register te maken ofzo, in combinatie met het INCF-commando. De volgende code werkt namelijk wel gewoon, als ik direct de waarde in W zet en daarna naar PORTA zet:

code:
1
2
3
4
5
6
7
8
9
10
Main    MOVLW 00H       
        MOVWF   PORTA
        MOVLW 01H
        MOVWF   PORTA
        MOVLW 02H
        MOVWF   PORTA
        MOVLW 03H
        MOVWF   PORTA   
        NOP
        GOTO    Main

Patreon | Main Youtube | Work In Progress Youtube


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 17-11 12:21
Je doet MOVLW (Move Literal -> Working Register, dus een hardcoded getal in W plaatsen). Dit zou betekenen dat Count op plaats 0x02 van het geheugen staat waardoor hij dus het adres van Count in W plaatst, alhoewel me dat sterk lijkt want de onderste geheugenadressen zijn gereserveerd. Maar ik weet niet welke PIC je gebruikt en misschien is dat anders bij die van jou.

Wat je wil doen is:
code:
1
2
           MOVF     Count, W
           MOVWF    PORTA


MOVF (Move File Register) plaatst de inhoud van een file register (Count in jouw geval) in het opgegeven doel (in jouw geval W).

Kan best zijn dat ik het fout heb, heb al een tijdje niet geprutst met de PIC. :)

[ Voor 22% gewijzigd door Oguz286 op 17-12-2008 23:12 ]


  • Onbekend
  • Registratie: Juni 2005
  • Laatst online: 00:05

Onbekend

...

Is poort A niet met een andere functie gecombineerd zoals een adc of pwm? En is deze wel 8 bits?

Met PORTA lees je de fysieke status van de pinnen, en met LATA schrijf je er data naar toe.
LATA is eigenlijk een gewoon register die je kan lezen en schrijven.

Speel ook Balls Connect en Repeat


  • Theuno
  • Registratie: Juni 2001
  • Laatst online: 23:37

Theuno

Da Devil Crew

almightyarjen schreef op woensdag 17 december 2008 @ 22:46:
[...]

PORTA had ik al als uitgang gedefinieerd:
code:
1
2
3
4
5
        ORG    0x000           ; Program starts at 0x000 
        CLRF   PORTA           ; Initialize port A 
        BSF    STATUS,RP0      ; RAM bank 1 
        CLRF   TRISA           ; All pins port A output 
        BCF    STATUS,RP0      ; RAM bank 0
Dit kon ik helaas niet zo uit de assembler code lezen. Doe het meeste in C, maar had het inderdaad kunnen zien ;)
Het heeft met het schrijven naar het W-register te maken ofzo, in combinatie met het INCF-commando. De volgende code werkt namelijk wel gewoon, als ik direct de waarde in W zet en daarna naar PORTA zet:

code:
1
2
3
4
5
6
7
8
9
10
Main    MOVLW 00H       
        MOVWF   PORTA
        MOVLW 01H
        MOVWF   PORTA
        MOVLW 02H
        MOVWF   PORTA
        MOVLW 03H
        MOVWF   PORTA   
        NOP
        GOTO    Main
Dan wil je eigenlijk nog steeds altijd naar een LAT register schrijven, deze heeft meteen de waarde die je erin stopt. Een PORT wil nog wel eens net iets achter lopen doordat je daar echt de hardware poort leest.

Verder zou het dan moeten werken met de fix van Oguz verwacht ik.

Theuno - Da Devil Crew - Een programmeur is iemand die koffie omzet in software...
Nu nog betere koffie...


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 17-11 12:21
Theuno schreef op woensdag 17 december 2008 @ 23:05:
Dan wil je eigenlijk nog steeds altijd naar een LAT register schrijven, deze heeft meteen de waarde die je erin stopt. Een PORT wil nog wel eens net iets achter lopen doordat je daar echt de hardware poort leest.

Verder zou het dan moeten werken met de fix van Oguz verwacht ik.
V.z.i.w. hebben de nieuwe PIC's geen LATCH register en het gebruik ervan was deprecated. Als ik het me goed herrinner had de PIC16F84 die wel maar de 16F628 die niet meer. Je hoeft het ook helemaal niet te gebruiken omdat het schrijven naar de PORTX naar een intern LATCH register schrijft. Bij het lezen en schrijven naar een poort gebruik je alleen maar PORTX. Maar het is een tijdje geleden dus het kan ook onzin zijn die ik uitkraam :P

[ Voor 4% gewijzigd door Oguz286 op 17-12-2008 23:11 ]


  • almightyarjen
  • Registratie: Maart 2002
  • Laatst online: 22:31

almightyarjen

When does the hurting stop?

Topicstarter
Oguz286 schreef op woensdag 17 december 2008 @ 23:00:
[...]
Je doet MOVLW (Move Literal -> Working Register, dus een hardcoded getal in W plaatsen). Dit zou betekenen dat Count op plaats 0x02 van het geheugen staat waardoor hij dus het adres van Count in W plaatst, alhoewel me dat sterk lijkt want de onderste geheugenadressen zijn gereserveerd. Maar ik weet niet welke PIC je gebruikt en misschien is dat anders bij die van jou.

Wat je wil doen is:
code:
1
2
           MOVF     Count, W
           MOVWF    PORTA


MOVF (Move File Register) plaatst de inhoud van een file register (Count in jouw geval) in het opgegeven doel (in jouw geval W).
Ik snap wat je bedoelt. Maar als ik MOV F Count, W doe, dan gebeurt er niets (Count verandert niet van waarde). En MOVWF Count werkt op dit moment wel zoals het moet (vraag me niet waarom).
Onbekend schreef op woensdag 17 december 2008 @ 23:04:
Is poort A niet met een andere functie gecombineerd zoals een adc of pwm? En is deze wel 8 bits?

Met PORTA lees je de fysieke status van de pinnen, en met LATA schrijf je er data naar toe.
LATA is eigenlijk een gewoon register die je kan lezen en schrijven.
LATA is no more. Ik gebruik de 16F628. PORTA is inderdaad gecombineerd met een ADC maar die staat uitgeschakeld. Echter als ik PORTB gebruik, verandert de waarde van PORTB aan het einde van het programma in 0x22H, wat het adres is van Count. Dit kan te maken hebben met de bovenstaande opmerking van Oguzz.
Oguz286 schreef op woensdag 17 december 2008 @ 23:10:
[...]


V.z.i.w. hebben de nieuwe PIC's geen LATCH register en het gebruik ervan was deprecated. Als ik het me goed herrinner had de PIC16F84 die wel maar de 16F628 die niet meer. Je hoeft het ook helemaal niet te gebruiken omdat het schrijven naar de PORTX naar een intern LATCH register schrijft. Bij het lezen en schrijven naar een poort gebruik je alleen maar PORTX. Maar het is een tijdje geleden dus het kan ook onzin zijn die ik uitkraam :P
Klopt. LATCH register zit er niet meer in. Ik gebruik de 16F628.

Met de volgende code neemt PORTB aan het einde de waarde van het adres van Count aan (0x22H). Dit heeft waarschijnlijk ermee te maken dat ik Move Literal gebruik. Hoe formuleer ik het MOV commando dat PORTB de waarde van Count (0x6H) krijgt??

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Main    MOVLW 00H        
        MOVWF     Count
        MOVWF     PORTB    
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        MOVLW    Count
        MOVWF    PORTB
        NOP
        GOTO    Main

Patreon | Main Youtube | Work In Progress Youtube


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 17-11 12:21
almightyarjen schreef op woensdag 17 december 2008 @ 23:31:
[...]

Ik snap wat je bedoelt. Maar als ik MOV F Count, W doe, dan gebeurt er niets (Count verandert niet van waarde). En MOVWF Count werkt op dit moment wel zoals het moet (vraag me niet waarom).

[...]


LATA is no more. Ik gebruik de 16F628. PORTA is inderdaad gecombineerd met een ADC maar die staat uitgeschakeld. Echter als ik PORTB gebruik, verandert de waarde van PORTB aan het einde van het programma in 0x22H, wat het adres is van Count. Dit kan te maken hebben met de bovenstaande opmerking van Oguzz.

[...]

Klopt. LATCH register zit er niet meer in. Ik gebruik de 16F628.

Met de volgende code neemt PORTB aan het einde de waarde van het adres van Count aan (0x22H). Dit heeft waarschijnlijk ermee te maken dat ik Move Literal gebruik. Hoe formuleer ik het MOV commando dat PORTB de waarde van Count (0x6H) krijgt??

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
Main    MOVLW 00H        
        MOVWF     Count
        MOVWF     PORTB    
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        INCF    Count,1
        MOVLW    Count
        MOVWF    PORTB
        NOP
        GOTO    Main
Je moet wel "MOVF Count, W" gebruiken, maar volgens mij heb je geen standaard include gebruikt. Maak er "MOVF Count, 0" van en als het goed is werkt het dan wel. 'W' is in de standaard include gedefinieerd als '0'.

Die destination kan of 0 of 1 zijn. Als het 0 is, dan is de destination 'W' en als die 1 is dan is de destination de file register zelf. Voor het geval je denkt "Waarom zou ik het register naar zichzelf kopieren?": bij het kopieren worden de status bits gezet, dus je zou het kunnen gebruiken om te kijken of de waarde bijv. 0 is (zero-bit in status wordt dan geset).

Trouwens dit staat allemaal duidelijk in de datasheet, dus misschien een gevalletje RTFM :P Ik gebruik zelf ook de 16F628(A), leuk dingetje :)

[ Voor 4% gewijzigd door Oguz286 op 17-12-2008 23:49 ]


  • Cassettebandje
  • Registratie: Juli 2002
  • Laatst online: 20-11 16:21

Cassettebandje

SA-C90 TDK

Met de volgende code neemt PORTB aan het einde de waarde van het adres van Count aan (0x22H). Dit heeft waarschijnlijk ermee te maken dat ik Move Literal gebruik. Hoe formuleer ik het MOV commando dat PORTB de waarde van Count (0x6H) krijgt??
De pic18F heeft een movff instructie, maar de 16f helaas niet. Daar doe je het als volg (van hier:
In 16F series, to move a byte from REGA to REGB,

MOVF REGA,W
MOWF REGB
or
MOVF REGA,W
MOVWF PORTB

Verwijderd

De fout ligt idd in het gebruik van movlw.

Ik prog al jaren pic's in asm, maar als ik even snel snel iets wil testen betrap ik mezelf er nog steeds op om deze fout te maken :)

zoals al eerder gezegd zal movlw count gewoon het adres van count in W plaatsen.

On a sidenote; maak er een gewoonte van om schaduwregisters te gebruiken, kwestie van geen read-modify-write problemen tegen te komen.

iets als:
code:
1
2
3
4
5
6
7
8
9
10
11
sPORTA  equ 0x3F   ;schaduwregister poort A
sPORTB  equ 0x3E   ;schaduwregister poort B

.
.
.

Movf   Count,W
Movwf sPORTA
Movf   sPORTA,W
Movwf PORTA


In dit geval lijkt het helemaal niet zinnig, en is het ook niet, aangezien je een volledige poort schrijft.

De reden waarom je schaduw registers gebruikt is wanneer je bv het volgende doet:

code:
1
2
3
bsf PORTA,0
bsf PORTA,1
bsf PORTA,2


Wat er gebeurt is, omwille van 'read-modify-write' : poorta word volledig uitgelezen, bit 0 word geset, en de volledige poort word terug weggeschreven.
Poort a word weer uitgelezen, bit 1 geset, en de volledige poort terug weggeschreven etc. etc.

Nu, omwille van de architectuur van de pic zit het uitlezen van de poort al in de pipeline terwijl de vorige instructie nog aan het wegschrijven is.

En daar zit nu net de catch; stel dat poortA,0 een capacitieve belasting heeft, en dus niet onmiddelijk hoog getrokken word, word deze uitgelezen als 0, en dus ook weer weggeschreven als nul!

Op zich zal je dit probleem niet al te vaak tegenkomen, maar met hogere clockfrequenties en ingewikkelder belastingen dan een ledje zou je je al eens kunnen verschieten van hoelang je hierop te debuggen zit.. Ik spreek uit ervaring! :+

  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 17-11 12:21
Hey weer wat geleerd :) Ik wist dat de PIC een poort eerst uitlas en daarna een waarde ernaar schreef, maar heb daar verder nooit bij stil gestaan. Zo'n schaduwregister is dan best handig. Misschien dat daarom sommige projecten opeens raar deden :+

Maargoed, heeft de TS ons advies nu opgevolgd en werkt het allemaal? :P

  • almightyarjen
  • Registratie: Maart 2002
  • Laatst online: 22:31

almightyarjen

When does the hurting stop?

Topicstarter
Oguz286 schreef op donderdag 18 december 2008 @ 13:19:
[...]

Maargoed, heeft de TS ons advies nu opgevolgd en werkt het allemaal? :P
Ik ga hier waarschijnlijk zondag op terugkomen ;)

Patreon | Main Youtube | Work In Progress Youtube


  • almightyarjen
  • Registratie: Maart 2002
  • Laatst online: 22:31

almightyarjen

When does the hurting stop?

Topicstarter
Oguz286 schreef op woensdag 17 december 2008 @ 23:47:
[...]

Je moet wel "MOVF Count, W" gebruiken, maar volgens mij heb je geen standaard include gebruikt. Maak er "MOVF Count, 0" van en als het goed is werkt het dan wel. 'W' is in de standaard include gedefinieerd als '0'.

Die destination kan of 0 of 1 zijn. Als het 0 is, dan is de destination 'W' en als die 1 is dan is de destination de file register zelf. Voor het geval je denkt "Waarom zou ik het register naar zichzelf kopieren?": bij het kopieren worden de status bits gezet, dus je zou het kunnen gebruiken om te kijken of de waarde bijv. 0 is (zero-bit in status wordt dan geset).

Trouwens dit staat allemaal duidelijk in de datasheet, dus misschien een gevalletje RTFM :P Ik gebruik zelf ook de 16F628(A), leuk dingetje :)
Thanks! Dit was het probleem, werkt nu perfect...

En BTW: de manual heeft 170 pagina's, na 10 pagina's had ik het wel gezien... Maar je hebt wel gelijk :P
Thanks, erg zinvol verhaal, ga ik voortaan toepassen :)

Patreon | Main Youtube | Work In Progress Youtube


  • Oguz286
  • Registratie: Juni 2002
  • Laatst online: 17-11 12:21
almightyarjen schreef op zondag 21 december 2008 @ 13:56:
[...]
Thanks! Dit was het probleem, werkt nu perfect...
Mooi dat het werkt :)
En BTW: de manual heeft 170 pagina's, na 10 pagina's had ik het wel gezien... Maar je hebt wel gelijk :P
Je had eigenlijk alleen "Instruction Set Summary" (H15) en dan alleen de eerste pagina ervan hoeven lezen en dan had je het ook geweten :P
Pagina: 1