mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik PIC Inline Assembler Problem


Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, ich hoffe ich bin hier richtig... Ich habe folgendes Problem:

Ich bin BA Student, habe gerade eine Praxisphase (soweit noch nicht 
schlimm) und schreibe gerade an einer Funktion, die eine Prüfsumme eine 
UART Kommunikation berechnen soll. Da das ganze einiermaßen schnell sein 
sollte und C keinen Rotate befehl kennt, mein PIC18F452 aber schon 
wollte ich Inline Assembler verwenden:

************************************************************************ 
***

_asm

RRNCF checksum_help_high,1,1    // checksum_help_high 2 Bit 
Rechtsschieben
RRNCF checksum_help_high,1,1

RLNCF checksum_help,1,1         // checksum_help 2 Bit Linksschieben
RLNCF checksum_help,1,1

_endasm

************************************************************************ 
***

Danach geht der C-Code weiter. Das Programm wird anstandslos kompiliert, 
aber die Befehle werden scheinbar nicht ausgeführt, die Variablen sind 
vor und nach dem Inline Assembler Code gleich... Könnt Ihr mir 
vielleicht helfen? Schon mal danke im vorraus

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst entweder mit einem Debugger (ICD2 oder PICkit2) nachschauen, 
was da passiert, oder Du lässt das Ganze im Simulator laufen.
Vielleicht zuerst mal das Assemblerlisting anschauen, insbesondere ob 
die Parameter checksum_help_high und checksum_help richtig aufgelöst 
werden.
In welcher Bank liegen die Variablen?

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Da das ganze einiermaßen schnell sein
>sollte und C keinen Rotate befehl kennt, mein PIC18F452 aber schon
>wollte ich Inline Assembler verwenden:

C kann sehr gut rotieren. Dazu gibt es << oder >>.
Versuch es doch mal damit.

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger wrote:

> C kann sehr gut rotieren. Dazu gibt es << oder >>.
> Versuch es doch mal damit.

Diese Operatoren rotieren nicht, sie schieben.
Vielleicht spielt das für Manuel keine Rolle, vielleicht aber doch!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Diese Operatoren rotieren nicht, sie schieben.

Ok, schlechtes Beispiel. Er rotiert aber ohne Carry.
Vieleicht ist das sein Problem.

Autor: Severino R. (severino)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
holger wrote:

> Ok, schlechtes Beispiel. Er rotiert aber ohne Carry.
> Vieleicht ist das sein Problem.

Wenn Du meinst:

Manuel wrote:
> ... die Variablen sind vor und nach dem Inline Assembler Code gleich...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Ok, schlechtes Beispiel. Er rotiert aber ohne Carry.
>> Vieleicht ist das sein Problem.

>Wenn Du meinst:

Naja, ich habs nicht so mit Assembler.

>Manuel wrote:
>> ... die Variablen sind vor und nach dem Inline Assembler Code gleich...

Aber du hast recht: Das Banking könnte schon ein Problem
sein. Wer weiss was er da ohne Banking rotiert.

Da er ohne Carry rotiert entspricht das doch schieben!?

checksum_help_high=checksum_help_high>>2;
checksum_help=checksum_help<<2;

Da muss er sich um das Banking nicht kümmern.
Das macht der Compiler.

Aber ohne weitere Zusammenhänge zu kennen ist es kaum möglich
weitere (unqualifizierte ;) Aussagen zu machen.

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>C kann sehr gut rotieren. Dazu gibt es << oder >>.
>Versuch es doch mal damit.

">>" rotiert tatsächlich? in meinem C-Buch ist es als shift beschrieben, 
also die Bits werden über den Rand geschoben und sind verloren... 
Rotieren ohne Carry wäre natürlcih traumhaft, das will ich ja.... muss 
ich gleich mal testen...

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
<< und >> verlieren leider die Bit, ich bräuchte was, was beim schieben 
Bit 0 in Bit 7 rettet oder umgekehrt... Für mich Rotate ohne Carry, da 
das gerettete Bit ja gleich wieder im Byte ankommt und nicht durch das 
Carrybit geschoben wird... Ich habe mal mein Programm angehägt, 
vielleicht hilft es ja:

/*********************************************************************** 
**********
** Algorithmus zu der Brechnung des Check/Type und Check/Stat Bytes für 
IO-Link  **
**                                        **
** Autor:   Manuel Walz                            **
** Version:   0.1                                **
** Datum:   22.01.2009                              **
**                                        **
************************************************************************ 
*********/

#include <p18f452.h>
#include <stdio.h>

unsigned char Checksum(unsigned char telegram[], unsigned char n);
unsigned char Rotate_Right (unsigned char checksum_help_high);
unsigned char Rotate_Left (unsigned char checksum_help);

void main (void)
{
  unsigned char n = 1;
  unsigned char telegram[4];
  unsigned char ergebniss;

  telegram[0] = 0xA4;
  ergebniss=Checksum(telegram, n);

  //printf("Die Pruefsumme lautet:");
  //printf("%s",Checksum(telegram, n));

  while(1);
}

unsigned char Checksum(unsigned char telegram [],unsigned char n)
{
  unsigned char checksum = 0x52, checksum_help, checksum_help_high;

  while(n != 0)
  {
    n--;
    checksum = checksum^telegram[n];
  }

  checksum_help_high = checksum;

/*********************** Berechnung Low-Half-Byte 
*******************************************/

  checksum_help = (checksum >> 1)^checksum;    // zu ver-XOR-ende Bits 
übereinander schieben
                          // und ver-XOR-en
  checksum    = (checksum_help & 0x01);      // Bit 0 schon korrekt, 
Rest auf Null setzen
  checksum_help >>= 1;              // Bit 1 an richtige Position 
schieben
  checksum    = (checksum_help & 0x02)|checksum;// Bit 1 in Checksum 
einfügen
  checksum_help >>= 1;              // Bit 2 an richtige Position 
schieben
  checksum    = (checksum_help & 0x04)|checksum;// Bit 2 in Checksum 
einfügen
  checksum_help >>= 1;              // Bit 3 an richtige Position 
scheiben
  checksum    = (checksum_help & 0x08)|checksum;// Bit 3 in Checksum 
einfügen


/********************** Berechnung High-Half-Byte 
*******************************************/

  checksum_help = Rotate_Left(checksum_help_high);
  checksum_help_high = Rotate_Right(checksum_help_high);

  checksum_help_high = checksum_help ^ checksum_help_high;  // XOR mit 
ersten 4 Bitpaaren
  checksum_help = (checksum_help_high >> 2);          // Bitpaare in 
richtige Position

  // Positionierte Bitpaare verXOR-en, Bits 4 und 5 maskieren und in 
checksum einfügen
  checksum = ((checksum_help ^ checksum_help_high) & 0x30)| checksum;


  return checksum;
}


unsigned char Rotate_Right (unsigned char checksum_help_high)
{
  _asm  // Inline Assembler Code

  RRNCF checksum_help_high,1,1     // Checksum_help_high 2 Byte nach 
rechts rotieren
  RRNCF checksum_help_high,1,1
  _endasm
  return checksum_help_high;
}

unsigned char Rotate_Left(unsigned char checksum_help)
{
  _asm
  RLNCF checksum_help,1,1        // Checksum_help 2 Byte nach links 
rotieren
  RLNCF checksum_help,1,1
  _endasm
  return checksum_help;
}

Autor: Manuel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Du kannst entweder mit einem Debugger (ICD2 oder PICkit2) nachschauen,
>was da passiert, oder Du lässt das Ganze im Simulator laufen.
>Vielleicht zuerst mal das Assemblerlisting anschauen, insbesondere ob
>die Parameter checksum_help_high und checksum_help richtig aufgelöst
>werden.
>In welcher Bank liegen die Variablen?

Ok, das hab ich vor lauter Shift und Rotate übersehen Wie bekomm ich 
denn die Bank raus un ordne sie richtig zu? Im Disassembly scheit es 
nämlich nicht zu stimmen, Da werden, wenn ich das richtig lese, die 
Rotates auf andere Adressen ausgeführt, als die, wo die Variablen 
liegen:

zB funktioniert:

     Checksum_help = ((checksum_help >> 1) ^ checksum;

RRNCF 0xfdf, W, ACCESS  // fdf sollte checksum_help sein

und es funktioniert nicht:

     RLNCF checksum_help,1,0

RLNCF 0xffe, F, ACCESS

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.