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 verstehen

    ist 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;
    }
    

    http://ideone.com/tx8zHq



  • 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;
    

Log in to reply