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
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?
>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.
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!
>Diese Operatoren rotieren nicht, sie schieben.
Ok, schlechtes Beispiel. Er rotiert aber ohne Carry.
Vieleicht ist das sein Problem.
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...
>> 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.
>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...
<< 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; }
>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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.