Forum: Mikrocontroller und Digitale Elektronik ASM-Code in C einbinden


von Christoph H. (obbedair)


Lesenswert?

Hallo
ich benutzte einen PIC18F448 und C18 von Microchip
Mein Problem ist das ich diese Zeilen einbinden möchte

{
_asm
movf   Zahl,w
addwf  PCL, f
bsf    R_4
bsf    R_3
bsf    R_2
bsf    R_1
...
...
bsf    G_1
_endasm
}



die Variable Zahl ist ein unsigned Char
funktioniert das mit dem PCL mit den Pic18f und C18 denn noch?

er zeigt mir den Fehler "constant operand expected" ab der Zeile "bsf 
R_3" an. das bedeutet doch so viel wie constanter Operator erwartet> 
aber ich kann damit nichts anfangen:-(
Was ist denn damit gemeint?

vielen dank

von Wegstaben V. (wegstabenverbuchsler)


Lesenswert?

beschreib doch mal ein wenig mehr von deiner Programmier-Umgebung außer 
dem Codeschnipsel ...

von John (Gast)


Lesenswert?

BSF [register],[bit]

[register] 0..255
[bit]      0..7

von Christoph H. (obbedair)


Lesenswert?

/** I N C L U D E S 
**********************************************************/
#include <p18cxxx.h>
....

void main (void);

/** D E C L A R A T I O N S 
**************************************************/
#pragma code

#define   Schaltblitz    LATBbits.LATB7
#define    G_1    LATEbits.LATE2
#define    G_2    LATEbits.LATE1
...
...
#define    R_3    LATCbits.LATC6
#define    R_4    LATBbits.LATB6
#define    Zuendunterbrecher  LATDbits.LATD3
#define   Schaltblitz_Toggle()     Schaltblitz = !Schaltblitz;

  unsigned int    Ergebnis;
  unsigned int  OEL_TEMP;
  unsigned int   WERT;
  unsigned char  Merker;
  unsigned char  Zahl;


void main(void)
  {



    TRISA = 0x41;  //RA0:Öltemp RA6:Ozillator
    TRISB = 0x0D;  //PB1:Fussschalter RB2/RB3:Can-Bus
    TRISC = 0x00;  //RC2:PWM
    TRISD = 0x18;  //PD4:Frequenzzähler PD3:Zündunterbrecher
    TRISE = 0x00;  //


while(1)
   {
   while(Merker==1)
      {

      ZAHL = WERT;
        if(...)
          {....}


        else
          {
          _asm
          movf  Zahl,w
          addwf  PCL, f
          bsf    R_4
          bsf    R_3   hier kommt der Fehler
          bsf    R_2   "constant operand expected"
          bsf    R_1
          ...
          ...
          bsf    G_2
          bsf    G_1
          _endasm
          }
        Merker = 0;

        }//while(Merker==1)-Schleife
    }//while(1)-Schleife
  }// Main-Schleife

der bsf-Befehl ist richitg denk ich , R_4 ist ja mit #define... 
deklariert.
ist der code oki?
ich hoffe jemand kann mir helfen:-)

von Lehrmann M. (ubimbo)


Lesenswert?

Christoph Herzog schrieb:
> der bsf-Befehl ist richitg denk ich

dann denkst du falsch

Christoph Herzog schrieb:
> R_4 ist ja mit #define...
> deklariert.

wenn dann ist es definiert und nicht deklariert.

Christoph Herzog schrieb:
> #define    R_4    LATBbits.LATB6

heißt: ersetzte im Code alles was R_4 ist zu  LATBbits.LATB6

Christoph Herzog schrieb:
> bsf    R_4

heißt dann also: bsf LATBbits.LATB6

und das ist falsch. BSF heißt "bit set f". Man beachte das f!


BSF   Ein Bit (das Bit Nr. b) in einer Speicherzelle f  setzen
Syntax:   BSF  f,b
Bedeutung:   In der Speicherzelle f wird das Bit b auf 1 gesetzt
Beispiel:   BSF PORTA,3  ; Im Register PORTA wird das Bit Nr.3 auf 1 
gesetzt


Du kannst BSF kein einzelnes Bit zum setzen geben, sondern nur ein 
Register und ein Bit (0-7) in diesem Register.

von Lehrmann M. (ubimbo)


Lesenswert?

Christoph Herzog schrieb:
> else
>           {
>           _asm
>           movf  Zahl,w
>           addwf  PCL, f
>           bsf    R_4
>           bsf    R_3   hier kommt der Fehler
>           bsf    R_2   "constant operand expected"
>           bsf    R_1
>           ...
>           ...
>           bsf    G_2
>           bsf    G_1
>           _endasm
>           }

So mal weiter: Inlineassembler ist eigentlich grundsätzlich unnötig. Mir 
ist absolut schleierhaft, warum du an dieser Stelle Inline-assembler 
(also asm in C) einsetzt. Mir kommt es so vor, als fehlten dir die 
nötigen Grundlagen, um in C bits zu setzen. Du kannst doch einfach nach 
dem Muster: REGISTERbits.bit (wie in deinen #defines) auf jedes bit 
Zugreifen. Warum dieser schreckliche Umweg? Wenn das nicht gehen sollte 
(warum auch immer, nehme man Bitmanipulation: 
http://www.mikrocontroller.net/articles/Bitmanipulation)

Ich rate dir dringendst von Inlineassembler ab. Es gibt minimalste 
Anwendungsgebiete, aber mit denen hat ein Anfänger nichts zu tun. Wenn 
dein Programm nicht funktioniert, dann brauchst du dich nicht zu 
wundern. Du greifst mitten im Programm auf PCL zu und veränderst da 
Daten. So kannst du das ganze vom C Compiler erdachte Programm 
zerstören. Ganz zu schweigen von interruptsicherem Programmieren 
(atomarer Code). Ich würde mir das gut überlegen. Was man in ASM machen 
kannt, geht in C genauso.

Vielleicht erklärst du uns, warum du Inlineassembler verwenden möchtest 
?!

von Christoph H. (obbedair)


Lesenswert?

das mit dem inlineassembler hat sich erledigt ich hab das ganze durch 
eine switch case funktion ersetzt.

du hast mit sicherheit recht recht, mir fehlen die grundlagen,da werd 
ich mich jetzt wohl mal ransetzten müssen und noch bissel lesen...

von John (Gast)


Lesenswert?

Christoph Herzog schrieb:
> #define    G_1    LATEbits.LATE2

Ist LATCbits dein Register (Variable) und LATC6 das Bit (0..7)?
Dann versuchs mal mit einem Komma dazwischen.

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.