logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Tablica wskaźników na rejestry I/O, AVR

djmdp 26 Sie 2010 12:33 1721 6
  • #1 8440395
    djmdp
    Poziom 16  
    Witam, jest do zrobienia poniższe zagadnienie, chciałbym podstawiać do jakiejś określonej funkcji adresy rejestrów np. PORTÓW, po to aby znacznie skrócić kod, gdy obsługuję dla przykładu 10 czujników temperatury na różnych pinach i portach, z pinami nie ma problemu, bo tablica pinów to tablica zwykłych charów, natomiast przy definicji tablicy wskaźników do rejestrów zaczyna się problem z dziwnym ostrzeżeniem : warning: initialization discards qualifiers from pointer target type
    deklaracja wygląda następująco (użycia nie będę poruszał bo wiadomo):
    
    unsigned char *CZUJNIKI_P[3]={&_SFR_IO8(0x1B),&PORTB,&THERM_3_SW_P};
    

    tutaj akurat są adresy 3 rejestrów I/O, po odwołaniu się do któregoś elementu tablicy reakcja jest prawidłowa, zostanie wpisana w rejestr zadana wartość, tylko nie mogę domyślić się dlaczego jest to ostrzeżenie, nie czaje tych kwalifikatorów. Ma ktoś ciekawe wytłumaczenie tej sprawy?? Pozdrawiam, MdP Solutions.
  • #2 8440418
    piti___
    Poziom 23  
    Witam,

    Ja robie to tak:
    
    volatile unsigned char *ddr_reg;
    volatile unsigned char *port_reg; 
    volatile unsigned char *pin_reg;   
    
    
    volatile unsigned char bus_pin;                              
                                  
    void select_bus(unsigned char bus_nr)
    {
       if(bus_nr == 1)
       {
          ddr_reg  = (unsigned char *)0x31;          // DDRD
          bus_pin  = (1<<5);
          port_reg = (unsigned char *)0x32;          // PORTD    
          pin_reg  = (unsigned char *)0x30;          // PIND
       }                   
       else
       {
          ddr_reg  = (unsigned char *)0x34;          // DDRC         
          bus_pin  = (1<<0);
          port_reg = (unsigned char *)0x35;          // PORTC   
          pin_reg  = (unsigned char *)0x33;          // PINC 
       }
    }
    
    #define DDR_DQ_OUT       *ddr_reg |= (bus_pin);
    #define DDR_DQ_IN        *ddr_reg &=~(bus_pin);
    
    #define DQ_OUT_1         *port_reg |= (bus_pin);
    #define DQ_OUT_0         *port_reg &=~(bus_pin);
    #define DQ_IN            ((*pin_reg) & (bus_pin))
    
    
    
  • #3 8440441
    djmdp
    Poziom 16  
    Mniej więcej o to mi chodzi, z tym, że potrzebowałbym mieć gotową tablicę by wpisywać czujniki do kompilacji, tak aby niezależnym było czy jest ich 5 czy 10, u Ciebie w takim podejściu, musiałbym napisać 10 if'ów, jeśli dobrze zrozumiałem, jeżeli nie to popraw mnie.
  • #4 8440459
    piti___
    Poziom 23  
    Tak, 10 if'ow. Ale z tablica nie powinno być problemów. Nie wiem co zwraca makro _SFR_IO8. Spróbuj rzutować wszystkie adresy na (unsigned char *).

    unsigned char *CZUJNIKI_P[3]={(unsigned char *)&_SFR_IO8(0x1B),(unsigned char *)&PORTB,(unsigned char *)&THERM_3_SW_P};

    I jeśli wpisujesz sam adres 0x1B to pewnie wystarczy tak jak u mnie
    (unsigned char *) 0x1B

    EDIT:

    Dodam że to działa na kompilatorze CodeVisionAVR. Nie wiem jak pod gcc.
  • #5 8440478
    djmdp
    Poziom 16  
    Twój kod jest jak najbardziej poprawny, właśnie rozwiązałem ten problem (warning) za pomocą volatile, szczerze mówiąc nie wiem dlaczego wyłączenie optymalizatora (volatile) ma tutaj taką rolę. Czyli:
    
    volatile unsigned char *CZUJNIKI_P[3]={&THERM_1_SW_P,&THERM_2_SW_P,&THERM_3_SW_P};
    

    i teraz mogę korzystać z portów indeksując je w pętli (świetne rozwiązanie do pomiarów temperatury), wywołanie wiadomo *CZUJNIKI_P[i]=wartosc;
  • #6 8440573
    tmf
    VIP Zasłużony dla elektroda
    Dlatego, że wszystkie zasoby IO procesora są zdefiniowane z atrybutem volatile. Zauważ, że zrzucenie volatile z np. PORTB spowoduje nieprawidłową pracę. Optymalizator wywaliłby np. kolejne po sobie zapisy, bo z punktu widzenia zmiennej ważne jest tylko ostatnie przypisanie.
  • #7 8440626
    djmdp
    Poziom 16  
    OOOOO tego właśnie mi brakowało, teraz wszystko jasne, grzebałem w sfr i nie zauważyłem tego, dzięki wielkie i temat zamykamy.
REKLAMA