CPU Funktions Register wie "Array" behandeln möglich?
-
Hallo,
ist es möglich ein CPU Funktions Register ähnlich wie ein Array zu behandeln?
Beispiel, es gibt 16 PWM Generatoren in den Registern (16Bit) PERIOD0 - PERIOD15 und DUTY0 - DUTY15.
Die Register sind im Controller so vorgegeben und liegen immer 8 Bytes auseinander!PWM = Registernummer
Anstatt nur für alle 16 PWM umständlich mit:
if (PWM==0) { PERIOD0 = Wert1; DUTY0 = Wert2; } else if (PWM==1) { PERIOD1 = Wert1; DUTY1 = Wert2; } else if (PWM==2) { usw...
möchte ich sowas wie:
PERIOD[PWM] = Wert1; DUTY[PWM] = Wert2;
Geht so natürlich nicht, aber es muss doch einen Trick geben oder?
Gruß
Jackson
-
würde damit gehen - und hat auch keinen overhead
http://www.learncpp.com/cpp-tutorial/98-overloading-the-subscript-operator/
-
Kannst du bitte mal genauer beschreiben wie das bei meinem Problem helfen soll? Zur Info: Ich schreibe in C nicht c++
-
Sorry ich habe zu spät gesehen das ich im C Forum bin - mit C kannst
in C++ kann du einfach irgeneine Klasse schreiben und dann den []-Operator überladen und damit alles anstellen was du willst - passt hier ja aber nicht
wie sind denn die PERIODx und DUTYx überhaupt definiert?
warum nicht
volatile unsigned char* PERIODs = zeiger auf Periods 0;
volatile unsigned char* DUTYs = zeiger auf Duty 0;
-
geht wohl auch nicht weil das kein "Speicher" ist - also zeig mal die definition
-
und was für eine Hardware? nur um den Detailgrad ein wenig zu erhöhen
void set_period(register,wert) { //mir fehlt die Definition von PERIOD0-15? } void set_duty(register,wert) { //mir fehlt die Definition von DUTY0-15? } void set_period_and_duty(register, period_wert,duty_wert) { set_period(register, duty_wert); set_duty(register, duty_wert); }
und dann
if (PWM==0) { PERIOD0 = Wert1; DUTY0 = Wert2; } else if (PWM==1) { PERIOD1 = Wert1; DUTY1 = Wert2; } else if (PWM==2) {
wird ersetzt durch
set_period_and_duty(PWM, wert1, wert2);
ein Array-Artiger Zugriff wuerde sich so auch mit C++ realisieren lassen - aber
so sieht man deutlicher das man etwas setzt - und nicht nur im Speicher rumorgelt - kurz und tricky ist selten gut
-
Es ist ein Mikrocontroller (Cypress 16FX-Series)
Hier ein Ausschnitt vom IO-MAP HEADER FILE:__pcsr0 .res.b 2 ;00007A PCSR0 .equ 0x007A __pdut0 .res.b 2 ;00007C PDUT0 .equ 0x007C __pcn0 ; overlay symbol ;00007E PCN0 .equ 0x007E __pcnl0 .res.b 1 ;00007E PCNL0 .equ 0x007E __pcnh0 .res.b 1 ;00007F PCNH0 .equ 0x007F __ptmr1 .res.b 2 ;000080 PTMR1 .equ 0x0080 __pcsr1 .res.b 2 ;000082 PCSR1 .equ 0x0082 __pdut1 .res.b 2 ;000084 PDUT1 .equ 0x0084 __pcn1 ; overlay symbol ;000086 PCN1 .equ 0x0086 __pcnl1 .res.b 1 ;000086 PCNL1 .equ 0x0086 __pcnh1 .res.b 1 ;000087 PCNH1 .equ 0x0087 .org 0x000090
-
ich sehe kein PERIOD0 oder DUTY0... nur andere Dinge
kenne diese IO-MAP header file nicht - aber sind das Speicheraddressen
die eben von deinem Kontroller auf CPU-Register gemappt werden oder
wie habe ich das zu verstehenist deine PERIOD Definition indirekt sowas wie?
volatile unsigned short* PERIOD0 = (volatile unsigned short*)0x12345+0;
volatile unsigned short* PERIOD1 = (volatile unsigned short*)0x12345+1;wie sieht die Definition von PERIOD0 aus?
-
PERIOD0 und DUTY0 hatte ich der Einfachheit gewählt, in Wirklichkeit sind es PCSR0 und PDUT0.
PCSR0 und PDUT0 , PCSR1 und PDUT1 , PCSR2 und PDUT2 , usw. sind immer um 8 Bytes verschoben
-
__pcsr0 .res.b 2 ;00007A PCSR0 .equ 0x007A __pdut0 .res.b 2 ;00007C PDUT0 .equ 0x007C
bedeutet wohl das der Linker die 2 byte PCSR0 2 bytes and Stelle 0x7A legt - oder?
ist das dann identisch zu solch einer Definition?
volatile unsigned short* PCSR0_test = (volatile unsigned short*)0x7A;
?
ich hab keine Ahnung ob deine (.res.b 2 + .equ 0x007A) diese Bedeutung hat - oder wird dann besonderer Code generiert wenn du auf PCSR0 zugreifst?
ansonsten kannst du doch einfach eine set_-Routine schreiben die Register-Nr und Wert bekommt und dann den Offset selber ausrechnen und die Zuweisung machen - oder?
oder du machst einen vollstaendigen Struct und mappst das mit einem Array auf den Speicher
-
Jackson0 schrieb:
Geht so natürlich nicht, aber es muss doch einen Trick geben oder?
Der Trick heißt: Makro
wobei "Trick" nur eine verharmlosendere Bezeichnung für unwartbaren Code ist.
enum{PCSR0=0x70, PDUT0=0x78, PCSR1=0x80, PDUT1=0x88, PCSR2=0x90, PDUT2=0x98}; #define f(a,i,x,y) { a[PCSR##i]=x; a[PDUT##i]=y; } int main(void) { int i,a[0x98+1]={0}; f(a,0,11,22); f(a,1,22,33); f(a,2,44,55); for(i=0;i<=0x98;++i) printf("\na[%#04x]=%d",i,a[i]); return 0; }
-
Es würde auch schon helfen wenn du mal sagen würdest ob man den Zugriff auch so schreiben kann - oder das du es einfach nicht weisst
volatile unsigned short* PCSR0_test = (volatile unsigned short*)0x7A;
wenn es so funktioniert ist es trivial
falls nicht könntest du noch ein Pointer Array machen
volatile unsigned short* PCSR_array[]= { &PCSR0, &PCSR1, &PCSR2, ... }; *PCSR_array[0] = 10; // ==> PCSR0 = 10;