Forum: Mikrocontroller und Digitale Elektronik PIC Probleme mit Programm BIN zu BCD


von Hans S. (mannibs)


Lesenswert?

Hallo,
habe mit MPLAP versucht einen bin zu bcd wandler zu programmieren. Es 
sieht folgendermaßen aus:

Loda:   CLRF  PONE
    CLRF  PTWO

  SUBTWO  MOVLW B'00001010'
    SUBWF   INBIN,F
        BTFSC   STATUS,0
              GOTO  INCTWO
      GOTO  ADDTWO
INCTWO  INCF  PTWO,F
     GOTO  SUBTWO
ADDTWO  MOVLW B'00001010'
       ADDWF INBIN,F

SUBONE  MOVLW B'00000001'
   SUBWF   INBIN,F
        BTFSC  STATUS,0
                GOTO  INCONE
      GOTO  FINISH
INCONE   INCF  PONE,F
          GOTO  SUBONE
FINISH     RETURN

das umwandeln soll im unterprogramm Loda ablaufen. Wenn inbin z.b. 23 
ist wird ptwo bis auf 2 erhöht alles soweit so gut aber beim nächsten 
schritt wäre ja inbin -7 und somit carry bit auf 0 und damit müsste er 
zu addtwo springen. Das passiert aber nicht und ich lande ganz oben in 
CFIG in der initialisation. Habe ich irgendwo einen denkfehler?
Habe das programm mehrmals mit MPLAP SIM getestet und immer das selbe.
Keine ahnung wo das problem ist.

Viel dank für die Hilfe und frohe Weihnachten

von holger (Gast)


Lesenswert?

Unterprogramme ruft man mit CALL auf, nicht mit GOTO.

von John B. (johnbauer)


Lesenswert?

Das sollte eigentlich funktionieren.
Welchen Controller benutzt Du?

Noch ein Tipp: die Einer-Stelle brauchst Du nicht herunter zählen. Du 
kannst den Rest-Wert von INBIN direkt übernehmen.
1
Loda:   CLRF   PONE
2
        CLRF   PTWO
3
SUBTWO  MOVLW  B'00001010'
4
        SUBWF  INBIN,F
5
        BTFSS  STATUS,C
6
        GOTO   ADDTWO
7
        INCF   PTWO,F
8
        GOTO   SUBTWO
9
ADDTWO  ADDWF  INBIN,F
10
        MOVF   INBIN,W
11
        MOVWF  PONE
12
        RETURN

Gruß
John

von Hans S. (mannibs)


Lesenswert?

holger schrieb:
> Unterprogramme ruft man mit CALL auf, nicht mit GOTO.

Das programm wird ja mit call im mainprogramm aufgerufen. Goto befehle 
sind im unterprogramm drin.


@john Ich habe versucht das Programm mit MPLAP sim zu simulieren habe 
aber leider das problem was ich oben beschrieben habe. Habe es noch 
nicht auf einen PIC überspielt. Habe soeben dein Programm übernommen die 
zweier stellen klappen wunderbar aber wenn der carry bit 1 sein soll 
dein spring MPLAP SIM zu CFIG also zum anfang des programms wo alle 
bank1 variablen deklariert werden etc.

von John B. (johnbauer)


Lesenswert?

Ich vermute, dass Du den Watchdog-Timer oder irgend einen Interrupt 
(Timer?) aktiviert hast, der an der Stelle einen Reset, bzw einen 
Interrupt auslöst.

von Hans S. (mannibs)


Angehängte Dateien:

Lesenswert?

Der watchdog timer ist deaktiviert das problem habe ich immer noch. 
Finde keine lösung zu meinem Problem.
Habe im anhang das Programm eingefügt.

Als Controller habe ich PIC16F84A

von GroberKlotz (Gast)


Angehängte Dateien:

Lesenswert?

Hallo

Jetzt geht das Programm, ob es so stimmt wie du willst habe ich nicht 
geprüft.
Hast wohl einige grundlegende Fehler gemacht:
WICHTIG: DATENBLATT immer LESEN!
1. Die Configurations-Bits fehlen. Vgl. Datenblatt 16F84 "6.1 
Configuration Bits"

2. MPLAB enthält für jeden PIC das entsprechende "INC"-File. In diesem 
sind alle vom verwendeten typabhängigen Variablen-Deklarationen 
enthalten - einfach mal im Ordner MPLAB(MPASM Suite mal nachlesen
Dieses File wird mit der Anweisung "  #include <P16F84A.INC>" ins 
ASM-File eingebunden.

3. Man vermeindet Fehler wenn man die CBLOCK 0x20- ENDC Anweisung 
verwendet um Variable zu deklarieren, die Variablen werden ab Register 
0x20 in Folge automatisch angelegt.

4. Bitte beachten, Datenblatt "5.0 TIMER0 MODULE"
 Der TMR0 läuft nur im Timer-Mode wenn man im Option-Register das 
TOCS-Bit löscht.

Ich habe mal in den Text reingeschrieben was mir im ersten Anflug so 
aufgefallen ist.
Für Dich bleibt auch noch ein wenig übrig.

Verwende bitte die Tools welche MPLAB zum Debuggen zur Verfügung stellt. 
Ganz wichtig ist hier das Menü "View/Watch. Zieh einfach die zu 
überwachenden Variablen in das Watchfenster, ist danach selbsterklärend.

....und noch: Wenn es nicht geht alles in Teilmengen zerlegen und 
testen, testen......

Leider:
Hättest Du gleich zu BEGINN den VOLLEN ASM-Text mitgeliefert, wäre Dir 
wohl schon längst geholfen worden!


Gruß GroberKlotz

von GroberKlotz (Gast)


Angehängte Dateien:

Lesenswert?

Hall Hans S.!

War gestern doch nicht mehr so recht fit, und so habe ich mich heute 
nochmals mit Deinem Lottogenerator beschäftigt.

ABER:
ICH HABE JETZT NICHT JEDEN EINZELNEN BEFEHL UND ALLES IM ZUSAMMENHANG
GEPRÜFT. SO ABER MÜSSTES DU WEITER KOMMEN.

(Bei dieser Hitze hier (+30Grad, schwül) schwitzt man ja schon beim
Schreiben :-). Hoffe nicht, dass sich bei mir Flüchtigkeitsfehler 
eingeschlichen haben. Im Debugger läuft das Programm ohne zu halten 
durch.


 ICH HABE JETZT NICHT JEDEN EINZELNEN BEFEHL UND ALLES IM ZUSAMMENHANG
 GEPRÜFT. SO ABER MÜSSTES DU WEITER KOMMEN !!!

 "RÜCKSPRUNG DES PROGRAMMS zu CFIG":
 Mir ist aufgefallen, dass öfters der falsche Befehl
 MOVFW B'xxxxxxx' verwendet wurde!
 MOVFW bedeutet: "Kopiere Register "F" in das WREG"
 wird aber korrekt als MOVF FILE,w verwendet
 Also:  MOVF PONE, w dann ist PONE im WREG.
 Du versuchtest also eine BINÄRZAHL ALS REGISTER anzusprechen
 Das muss schief gehen!
 RICHTIG ist:
 MOVLW B'xxxxxxx'
 Das "L" bedeutet: Kopiere LITERAL (=Ganzzahl. Zeichenkette usw)
 ins WREGister
 Dieser Fehler hat den Debugger "fassungslos" gemacht!

 SYSTEMTAKT?
 Quarz (Frequenz?), RC-Oscillator?
 siehe Datenblatt 6.0 SPECIAL FEATURES OF THE CPU
                  6.2 Oscillator Configurations
 _XT_OSC = verwenden von Quarz- oder Resonatoroszillator
 _RC_OSC = verwenden von RC-Oszillator (Beschaltung vgl. Datenblatt)
 ein RC-Oscillator oder 455kHz-Resonator wäre wohl die einfachste und
 ausreichende Wahl. Ich habe mal im Debugger 256kHz eingestellt.

 NUR INFO:
 Es besteht die Möglichkeit einen Interrupt einbinden
 PORTA-RB0/INT - Bit0 - kann wahlweise mit dort ansteigender/fallender
 Flanke einen Interrupt auslösen (z.B.Tastendruck)
 Muss aber über Register INTCON und OPTION_REG vorbereitet werden.

TESTEN (nur Info):
Watch-Fenster und Stimulus verwenden!
Watch:
       Register überwachen:
       MPLAB Menue View/Watch
       einfach Variable aus dem ASM-Text ins Watchfenster ziehen
Taster simulieren:
       MPLAB Menue Debugger/Stimulus
       Pin wählen, Action-wählen

 LESBARKEIT DES ASM-TEXTES
 Wenn möglich keine kryptischen Kürzel verwenden.
 Man könnte eine Unterprogramm zum Würfeln
 z.B. RANDOM oder RNDM nennen. Klar wird es aber für jeden der Aufruf
 "CALL  WUERFELN"
 oder
 anstatt PONE  besser: DIGIT_1 usw...
 auch lassen sich Ports und PortPins SO einfacher im Programm behandeln
 Beispiele:
 #define LED_ANZEIGE PORTB   ; Segmente a-g (h)
 #define DIGITS      PORTA   ; Bit 0-3
 #define TASTER      PORTA,0 ; Bit 0
 Abfrage:
 btfsc   TASTER  ; skip next wenn Taster offen
                 ; liest sich einfacher wie
 btfsc   PORTA,0
 oder
 #define  DIGIT1_AUS    bcf  LED_ANZEIGE,3 ; -> Digit3 AUS
 #define  DIGIT1 EIN    bcf  LED_ANZEIGE,3 ; -> DIGIT3 EIN
 im Programm lässt sich so einfach die 7segment-Anzeige 3 ansprechen:
   DIGIT1_EIN ; Anzeige ist aktiv
   DIGIT1_AUS ; Anzeige ist abgeschaltet

 wir wollen hier aber keinen PIC-Programmierlehrgang starten :-) :-)
 es lässt sich im Netz bestimmt ein grundlegender Lehrgang aufspüren
 ansonsten empfehle ich "sprut":

 [http://www.sprut.de/electronic/pic/assemble/assembler.html]

Grüße
GroberKlotz

von GroberKlotz (Gast)


Lesenswert?

Hi
...arrg.. hab doch gemurkst....

ZUVIEL mit Strichpunkt auskommentiert:
falsch
     ; MOVLW  B'00000000';Configure Port B
     ; MOVWF  TRISB      ;Bit 0-7 of Port B is now Output

richtig OHNE Strichpunkt
       MOVLW  B'00000000';Configure Port B
       MOVWF  TRISB      ;Bit 0-7 of Port B is now Output

mfg GroberKlotz

von GroberKlotz (Gast)


Lesenswert?

...mann o mann - und nochmal gemurkst!


FALSCH             RICHTIG
   CBLOCK 0x00     CBLOCK 0x20
        .....
   ENDC

FALSCH
  ORG     0x0004    ;Set the reset vector  NICHT 0x000!
  GOTO    CFIG
  ;ORG     0x06    ;Jump over the interrupt vector


RICHTIG
  ORG    0x0000    ;set the RESET-vector!
  GOTO   CFIG
  ;ORG     0x06    ;Jump over the interrupt vector
;----------------------
  ; ORG    0x0004   ; set the INTERRUPT-Vector (nur wenn benötigt)
  ; hier befindet sich dann auch nachfolgend die
  ; Interrupt-Service-Routine (ISR)
;----------------------

mfg GroberKlotz

von Hans S. (mannibs)


Lesenswert?

Vielen dank für die Hilfe GroberKlotz.
Dein Programm funktioniert einwandfrei. Ich weiß das ich kein #include 
habe, da der Herr Vorleser es nicht so möchte. Also muss ich meine 
Register im Programm deklarieren.

Ich hasse microcontroller von daher will ich es nur zum laufen bringen 
:D

Der Delay funktioniert nur in deinem Programm. In meiner version ohne 
#include habe ich einen unterprogramm von wait von unendlich. Ich will 
doch eigentlich nur paar sekunden pause damit ich nach der reihe die 
Zahlen auf das Display übertragen kann.

Hoffe das ich die tage das problem mit uneldich wait lösen kann.

von John B. (johnbauer)


Lesenswert?

Hallo Hans,
hast Du, wie GroberKlotz in seinem Programm, den Vorteiler dem Timer0 
zugeordnet?
(Bit 3 von OPTION_REG auf 0)

Gruß
John

von Hans S. (mannibs)


Lesenswert?

John Bauer schrieb:
> Hallo Hans,
> hast Du, wie GroberKlotz in seinem Programm, den Vorteiler dem Timer0
> zugeordnet?
> (Bit 3 von OPTION_REG auf 0)
>
> Gruß
> John

Ich habe sein Programm 1zu1 übernommen. Alles von Test.asm herauskopiert 
und in Lottogeneratorled.asm eingefügt.
Include befehle etc auskommentiert und bei der variablen deklaration ; 
weg gemacht.

TMR0 wird auf 25 gesetzt zählt aber nicht wie in seinem programm bis 65 
hoch.

Ja habe clrf  OPTION_REG drin somit ist bit3 auf 0.

von Hans S. (mannibs)


Lesenswert?

Nachtrag:

Fehler gefunden.

Hatte clrf  OPTION_REG nachdem es auf BANK0 war und nicht bei bank1.

Danke nochmals für eure Hilfe. Bin sehr froh das ich es dieses jahr noch 
hinter mir haben. Guten Rutsch

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.