Pins an Soft-Microcontroller - was macht der code?
-
Hallo,
habe folgenden code:#include <stdio.h> int main() { unsigned char * Switches; unsigned char * LEDs; Switches = (unsigned char *)0x0000800; LEDs = (unsigned char *)0x0000810; printf("Beginning.\n"); while(1){ *LEDs = *Switches; } return 0; }
der bewirkt, dass wenn ich auf Switch1 drückt LED1 leuchter bei Switch2 LED2 usw..
Allerdings verstehe ich die schreibweise nicht.
Was bewirkt*LEDs = *Switches;
denn?
oder anders gefragt, wie kann ich zum beispiel Schreiben
[pseudocode]if(switch1 && switch2)Led4 = 1;[/pseudocode]Das ganze läuft in einem NiosII auf einem FPGA..
-
goaran schrieb:
Allerdings verstehe ich die schreibweise nicht.
Was bewirkt*LEDs = *Switches;
denn?
oder anders gefragt, wie kann ich zum beispiel Schreiben
[pseudocode]if(switch1 && switch2)Led4 = 1;[/pseudocode]Das ganze läuft in einem NiosII auf einem FPGA..
Die Schreibweise heiß nur, Inhalt des Registers mit der Adresse von Switches auf das Register der Adresse von LED kopieren. LED bzw. Switches sind nur Zeiger auf Speicherstellen.
Probier mal, *LED mit 1, 2, 4, 8 usw. zu beschreiben (also einzelne Binärstellen) und guck' mal, welche Lämpchen angehen.
Dann printest Du mal aus, was sich an *Switches rührt, wenn Du verschiedene Tasten drückst.
War das nicht erhellend, mußt Du noch nach "Binärsystem" googeln.
-
Danke für die schnelle Antwort. Ok, wenn das einfach nur Zeiger auf die Register sind macht das sinn..
Kann ich auf die Register auch noch irgendwie anders zugreifen? Weil wenn ich zum Beispiel einen Pin lesen will muss ich bei dieser Methode ja immer das komplette Register lesen, und dann schauen ob an Stelle 5 z.B ein 1/0 steht.
-
Die Zeiger sollten noch volatile sein...
Und bei NiosII habe ich dunkel in Erinnerung, dass man nie "magic number" Addressen auf Peripherie nutzen sollte, weil sie sich bei der nächsten Konfiguration mit einem Mausklick ändern können...
-
goaran schrieb:
Kann ich auf die Register auch noch irgendwie anders zugreifen? Weil wenn ich zum Beispiel einen Pin lesen will muss ich bei dieser Methode ja immer das komplette Register lesen, und dann schauen ob an Stelle 5 z.B ein 1/0 steht.
Ein ganz klares "Jein". Unter C gibt es offiziell keine Bitmanipulationen, ANSI- konformer Code wird mittels Bitshifting erzeugt:
unsigned char a = 255; char bit = 4; // Achtung! es wird von Bit0 bis BitX numeriert! if (a & (1 << bit)) printf("TRUE\n"); else printf("FALSE\n"); a = 0; if (a & (1 << bit)) printf("TRUE\n"); else printf("FALSE\n");
Allerdings kann es sein, daß Dein Compiler Bitfields tatsächlich auf Bits abbilden kann:
#ifndef BITBYTE #define BITBYTE /******************************************************** * declare SFR bit * ********************************************************/ #pragma pack(1); typedef struct _bit_def_ { char b0:1; char b1:1; char b2:1; char b3:1; char b4:1; char b5:1; char b6:1; char b7:1; } bit_def; typedef union _byte_def_{ bit_def bit; char byte; } byte_def; #pragma pack #endif
Dann kannst Du ganz einfach per defines bitvariable anlegen:
#define attribute attributes.byte #define vz_x attributes.bit.b0 #define vz_y attributes.bit.b1 #define vz_z attributes.bit.b2 // jetzt Var anlegen: byte_def attributes; // und Hineinschreiben attribute = 0; // Registerzugriff vz_z = 1; // Bitzugriff
Das große ABER: #pragmas sind compilerspezifische Extensions und es ist nicht gesichert, daß alle Compiler Bitfiels wirklich auf Bits abbilden, manche nehmen stur char her, heißt die Codeebene ist nicht mehr ANSI- konform und daher nicht mehr portabel. Ob man damit leben kann, muß jeder für sich selbst entscheiden.
Edit: Upps, Registerzugriff war falsch.