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

[ASM] Microchip 16F877a krijg de INDF functie niet goed

Pagina: 1
Acties:

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 18-11 12:42
(jarig!)
Dit is mijn eerste post over een project met een Microcontroller dus probeer het zo uitgebreid mogelijk te doen.

Voor een schoolproject zijn we bezig met een rotordisplay. Voor diegene die niet weten waar ik het over heb. Dit is een scherm dat opgebouwd is uit een enkele rij leds die als je deze zeer snel roteerd een beeld kunnen vormen.


Nu ben ik al een behoorlijke tijd bezig met het programmeren van de MicroChip (16F877a) en heb het programma gedeeltelijk werkend. Alleen loop ik tegen 2 problemen aan en kom er niet uit met de informatie die ik op internet kan vinden.

Het eerste probleem.

We hebben afgesproken met het team dat de woord lengte maximaal 10 is. Nu heb ik dus met behulp van de FSR en INDF functies een stukje code in elkaar gezet dat naar mijn mening ;) zou moeten werken.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
letterladen     MOVLW 0x21          ;eerste letter plaats initialiseren LET OP 21h wordt zelf niet gebruikt!!
                MOVWF FSR
                MOVLW 0x0A          ;De hoeveeleid letters aangeven  0A = 10
                MOVWF letteraantal



nieuweLetter1   INCF     FSR, f
                MOVF     PORTC, w               ;Staat er een nieuwe letter klaar?
             MOVWF    PORTD
             SUBLW    0x9D
                BTFSC    STATUS, 2
                GOTO     Beginnieuweronde
                MOVF     PORTC, w
             SUBLW    0xB8
                BTFSS    STATUS, 2              ;ja? dan gaan we deze ontvangen
                GOTO     nieuweLetter1
ontvangen1      MOVF     PORTC, w               ;Staat de nieuwe letter op de ontvangst pinnen?
                SUBLW    0xB8
                BTFSC    STATUS, 2              ;nog niks verandert? dan loop-en we hem nog een keer
                GOTO     ontvangen1
                MOVF     PORTC, 0
             MOVWF    PORTD
             MOVWF    INDF                    ; De opgehaalde waarde opslaan in de adreswaarde die in FSR staat     
                DECFSZ   letteraantal, f
                GOTO     nieuweLetter1


Echter als ik nu het programma draai dan komt er op de uitgang de code te staan die in de INDF staat. Dit gebeurt als mijn selectie diagram een waarde krijgt die hij niet herkend. De waade die ik dus krijg is 0x00. Dit omdat ik in het begin van het programma de geheugenplaatsen clear (wat dus wel goed werkt :?).

Mijn vraag
Moet er nog meer ingesteld worden om de INDF functie te gebruiken(lezen)?


Mijn 2e probleem
Ik krijg de interrupts niet goed aan het werk.

We detecteren met een lichtsluis of de roterende arm langs een vast punt komt. Echter als ik nu de code overneem zoals ik die op andere sites tegenkom dan reageerd de chip er totaal niet op.


code:
1
2
3
4
5
6
7
;-----Interrupt instellingen---------------------------------------

            BCF   OPTION_REG, INTEDG        ;Interrupt bij negatief
            BSF   OPTION_REG, NOT_RBPU
            BCF   INTCON, INTF      ;Clear interrrupt vlag
            BSF   INTCON, INTE      ;mask for external interrupts
            BSF   INTCON, GIE


In het begin van het programma staat dus ook zoals aangegeven in de DataSheet

ORG 0x00
GOTO MAIN
ORG 0x04
GOTO ISR

En de Interrupt ziet er als volgt uit
code:
1
2
3
4
5
6
7
;----Interrupts----------------------------------

ISR        BCF     INTCON,INTF
           BSF   INTCON, GIE
           BTFSS   POORT, 0
           GOTO    pauzetelling
           GOTO    Beginnieuweronde


De waarde poort wordt door beide delen (Programma bestaat uit 2 hoofd gedeeltes)
verandert. De ene Cleart en de andere zet er 0xFF in.

Voor diegene die zeggen ik wil graag de hele code hebben dan kun je Hier klikken.

en als je intresse hebt in mijn alfabet of je afvraagt hoe heeft hij dat nou weer gedaan dan kun je Hier klikken Let wel op ik stuur de leds geinverteerd aan (0=aan 1=uit).

[ Voor 4% gewijzigd door Steefph op 12-01-2005 19:44 ]

Alles is terug te redeneren naar 4


  • F_J_K
  • Registratie: Juni 2001
  • Niet online

F_J_K

Moderator CSA/PB

Front verplichte underscores

Op verzoek SA -> PW :)

'Multiple exclamation marks,' he went on, shaking his head, 'are a sure sign of a diseased mind' (Terry Pratchett, Eric)


  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 23-11 17:12
Over je tweede probleem:
Doe je wel een RETFIE aan het einde van de interrupt? Zodat de chip weer terug gaat naar de plek daar waar ie was net voordat de interrupt begon. Ik weet zo 123 niet of je ook nog rekening moet houden met het swappen van de verschillende Bank's, die heb je bij een F84 en F628 wel.

Hmm ik zat nog even mijn stage code door te kijken, maar de assembly syntax is toch her en der even anders, dan vergelijk ik mijn F628a code met jouw opgegeven code. Ben bang dan als ik code sample's post dat die helemaal niet gaan werken op jouw chip.

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 18-11 12:42
(jarig!)
Ja maar die RETFIE(Return from Interrupt) kan ik dus niet toepassen omdat hij vanuit de ISR(interrupt Service Routine) naar een punt in het programma moet springen. Afhankelijk aan de waarde die in POORT staat.
Dit is volgens mij op te lossen door een SET te geven aan de GIE (General Interrupt Enable) bit voordat hij gaat springen.

Zet het gelijk erin (kan helaas niet testen :( exhibit staat op school).

[ Voor 12% gewijzigd door Steefph op 09-01-2005 00:00 ]

Alles is terug te redeneren naar 4


  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 18-11 12:42
(jarig!)
*Subtiele schop*

Alles is terug te redeneren naar 4


  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 23-11 17:12
Ik ben bang dat je hier in PW weinig reacties zult krijgen, in CME zullen waarschijnlijk wat meer microcontroller programmeurs rond lopen. De meeste PIC/AVR/microcontroller related vragen vind je daar. Misschien heb je wat aan de forums van Circuits Online.

  • moto-moi
  • Registratie: Juli 2001
  • Laatst online: 09-06-2011

moto-moi

Ja, ik haat jou ook :w

Tikje richting Casemodding & Elektronica dan maar, als Frankie dat nou gelijk had gedaan, was er niets aan de hand geweest :/ :+

God, root, what is difference? | Talga Vassternich | IBM zuigt


  • kippy
  • Registratie: September 2004
  • Laatst online: 22:17
meschien moet je eens op het forum van http://www.avrfreaks.com posten en kijken. dit is wel in het engels maar dat zal niet zo'n groot probleem moeten zijn. hier heb ik een hoop dingen voor mijn micro controller projecten kunnen vinden.

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

Sprite_tm

Semi-Chinees

Kippy: Da's afaik een beetje schelden in de kerk, om op een AVR-gebaseerd forum te gaan vragen naar een probleem met PICs :)

Anyway, voor de topicstarter: Het is al jaren geleden dat ik wat met PICs gedaan heb (ben nu AVR fanaat) maar:
• Enable je je interrupts wel?
• Een interrupt dient idd als je het netjes doet afgesloten te worden met een RETFIE, zoniet dan moet je iig je globale interrupt enable weer aanzetten, die worden namelijk met get springen naar een interrupt uitgezet.
Ow, nm, dat doe je al :)

Edit: Zeker met het advies van m'n mede-ELler hieronder meegenomen, denk ik dat het handiger is om je interrupt-routine om te schrijven: laat die een bitje in een bepaald register op 1 zetten en laat je main programma daarop checken, da's denk ik makkelijker dan wat je nu gedaan hebt.

[ Voor 88% gewijzigd door Sprite_tm op 11-01-2005 20:18 ]

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


  • Fox2
  • Registratie: Juni 2003
  • Laatst online: 29-06 19:47

Fox2

Spanning!

Het is op een Microchip niet mogelijk om de interrupt service routine (ISR) te verlaten op een andere manier dan via de RETFIE. Natuurlijk kun je wel gewoon een GOTO doen, en dat werkt ook wel, maar het probleem zit hem in de stack. Hierop staat nl nog steeds het return-adres die er op is gezet bij het jumpen naar de ISR. De enige manier om de stack weer op te ruimen is door een RETFIE te doen.

NB1: als je RETFIE gebruikt, moet je in de ISR niet zelf al GIE weer aanzetten.

NB2: wanneer je in je programma exact nul keer de instructie 'CALL' gebruikt, dan kun je ook zonder RETFIE... Je gebruikt dan gewoon de hele stack niet...

FSR/INDF zou altijd moeten werken. Ik vraag me alleen af of je in de regel 'MOVF PORTC, 0' niet een denkfoutje hebt zitten. Op de plek van de 0 staat normaalgesproken een 'W' of een 'f' (al zal een 0 of 1 zeker wel werken, maar waarschijnlijk bedoel je wat anders...).

Verder zie ik niet helemaal wat je met 0x9D en 0xB8 moet...

[ Voor 12% gewijzigd door Fox2 op 11-01-2005 20:14 ]


  • Robindev
  • Registratie: Januari 2005
  • Laatst online: 30-11-2023
je moet altijd een retfie doen als je een interupt aanroeps, want deze call zet je pc weer terug naard de oorspronkelijke positie EN zet interupts weer aan!, anders gaan je interupts hierna nooit meer aan. Het lijkt of je het probeert in je interupt routine te omzeilen, maar ik weet niet of dit mag. Je program counter wordt dacht ik namelijk steeds opgeslagen bij een interupt. Dus dan loopt je stack vol, als je deze er nooit vanaf haalt.(k ken alleen jou chip niet zo goed, of dit opgaat voor jou pic)

t is lastig te zien in je code wat er mis is, omdat je (neem ik aan) een library hebt gebruikt met constanten.
Het is mischien goed om eens de datasheet van de pic en de library naast elkaar te leggen.
Ook kan je je programma stap voor stap doorlopen(en registerwaarden bijhouden) in de debugger van MPLAB IDE, te vinden op www.microchip.com. ik heb hier mijn progje uitvoerig in getest voor de code te uploaden naar de pic. Als je denkt dat het zin heeft kan ik je ook nog een ander .asm programmatje sturen dat ik heb geschreven met interupts dat wel werkt. Ook kan ik je helpen met hoe de debugger in mplab werkt... just ask.

Maar mischien is het een idee voor de volgende keer om (bijna) al je regels te commenteren (+ flowchart misschien?) t is veel werk, maar in .asm geen overbodige luxe.(het heeft mij iig veel geholpen)

Verwijderd

Heeft die pic geen POP of iets soortgelijks? Dan kun je gewoon het door de interrupt op de stack neergezette returnadres poppen en wegflikkeren. Anders krijg je in notime een stack overflow.

Je kunt het ook oplossen door je ISR een variabele te laten veranderen, en je 'main code' te laten kijken of die waarde verandert. Dat is ook een veel nettere oplossing. Zo heb je namelijk geen problemen met de stack meer, en je hebt veel meer controle over wanneer hij mag jumpen in de main code. Als je net in een bewerking zit die afgerond moet worden omdat er anders iets slechts gebeurt wil je niet dat hij door die interrupt ergens heen jumpt midden in je code. Als hij bijvoorbeeld net iets op de stack heeft gezet moet dat er eerst weer af voordat hij mag jumpen, want als dat te vaak niet gebeurt heb je weer een stack overflow.

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 18-11 12:42
(jarig!)
Fox2 schreef op dinsdag 11 januari 2005 @ 20:12:
Het is op een Microchip niet mogelijk om de interrupt service routine (ISR) te verlaten op een andere manier dan via de RETFIE. Natuurlijk kun je wel gewoon een GOTO doen, en dat werkt ook wel, maar het probleem zit hem in de stack. Hierop staat nl nog steeds het return-adres die er op is gezet bij het jumpen naar de ISR. De enige manier om de stack weer op te ruimen is door een RETFIE te doen.

NB1: als je RETFIE gebruikt, moet je in de ISR niet zelf al GIE weer aanzetten.

NB2: wanneer je in je programma exact nul keer de instructie 'CALL' gebruikt, dan kun je ook zonder RETFIE... Je gebruikt dan gewoon de hele stack niet...

FSR/INDF zou altijd moeten werken. Ik vraag me alleen af of je in de regel 'MOVF PORTC, 0' niet een denkfoutje hebt zitten. Op de plek van de 0 staat normaalgesproken een 'W' of een 'f' (al zal een 0 of 1 zeker wel werken, maar waarschijnlijk bedoel je wat anders...).

Verder zie ik niet helemaal wat je met 0x9D en 0xB8 moet...
Die Codes 9D en B8 zijn er zodat het JAVA programma kan aangeven dat er of een nieuwe letter aankomt of dat het verzenden is afgerond.

Die 0 staat voor W ik wil de waarde van PORTC opslaan/kopieren in het werkregister en opslaan in door FSR aangewezen register. Ik weet bijna zeker dat dit ophalen goed gaat omdat ik de waarde die op C staat doorstuur naar PORTD waar de LEDs aan zijn verbonden. Ik kan dus zo het verzend proces volgen.

Dit gaat opzich goed behalve dan dat de waardes niet worden opgeslagen.

Ik kan zien dat het goed gaat omdat het programma na het verzenden overgaat in de uitsturing (als ik de interrupt deactiveer en een vaste knipper waarde laad) Echter komt nu bij rotatie enkel vraagtekens inbeeld (Dit is de waarde die ontstaat als mijn selectie diagram de ontvangen code (uit FSR) niet begrijpt). Ik zie ook welke waarde hij uit INDF krijgt namelijk 0x00. Het Clearen gaat dus wel goed.

De RETFIE kan ik naar mijn mening niet gebruiken.

Wat er gebeurt is dat het RotorDisplay in zijn ronde 2 flapjes passeert die een lichtsluisje onderbreken. Dit veroorzaakt de externe interrupt.
Ik wil dus de ene helft de snelheid berekenen en de andere helft het beeld tonen.

Als ik dan een RETFIE gebruik dan zal het programma teruggaan naar waar hij vandaan is gesprongen en dit is dus niet de bedoeling. Hij moet dus ongeacht de toestand naar het ene of het andere gaan.
Verwijderd schreef op dinsdag 11 januari 2005 @ 21:39:
Heeft die pic geen POP of iets soortgelijks? Dan kun je gewoon het door de interrupt op de stack neergezette returnadres poppen en wegflikkeren. Anders krijg je in notime een stack overflow.

..........
Dit haal ik uit de DATASheet
There are no instructions/mnemonics
called PUSH or POP. These are actions
that occur from the execution of the CALL,
RETURN, RETLW and RETFIE instructions
or the vectoring to an interrupt address.
Ik heb hier geen ervaring mee :( Maar zoals ik het lees gebeurt dit dus enkel bij een van de instructie die onderaan staan

[ Voor 35% gewijzigd door Steefph op 11-01-2005 23:07 ]

Alles is terug te redeneren naar 4


  • Robindev
  • Registratie: Januari 2005
  • Laatst online: 30-11-2023
maar de snelheid vna je motor is toch redelijk constand, waarom laat je hem elke rondgang synchroniseren? 1x per seconde is toch al genoeg? dan laat je bijv. een teller lopen in je hoofdprogramma die als hij nul is een sprong maakt naar de code die via een interupt berekent hoe snel de motor draait. is het berkent(of een gemiddelde genomen uit meerdere berekeningen), dan springt hij pas weer terug naar het hoofdprogramma.

ik heb on. hetzelfde probleem gehad als jij, ik moets 2 pwm signalen uitsturen, en infrarood ontvangen, zonder dat ik wist waneer de ir zou binnenkomen. ik heb de 2 pwm signalen toen via een klok interupt laten lopen, en de IR ontvangst via een port interupt(althans het starbit ervan). ik had in dit programma in mijn main lus staan:

Main_loop
GOTO Main_loop

alles dus via interupts, zo blijven ze synchroon. maar dan moet je wel een zooi omschrijven,

  • Steefph
  • Registratie: Juli 2002
  • Laatst online: 18-11 12:42
(jarig!)
Nee dat is juist de bedoeling dat het toerental niet constant is. Dit is variabel van 0 tot ongeveer 1500RPM.

En aangezien we de tekst breedte hebben gelimiteerd kan ik gewoon de andere helft gebruiken als snelheidmeter.

[ Voor 35% gewijzigd door Steefph op 12-01-2005 13:04 ]

Alles is terug te redeneren naar 4

Pagina: 1