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

[AVR][C] Przekazanie double pointera do funkcji.

vcd_a 19 Wrz 2009 23:22 1571 2
REKLAMA
  • #1 7036487
    vcd_a
    Poziom 18  
    Witam serdecznie,

    mam pewien problem z kategorii tych najbardziej żenujących, czyli problem z wyklepaniem kodu w C. Pracuję teraz nad funkcją, która będzie pobierała wskaźnik do dwuwymiarowej tablicy zapisanej w pamięci programu.

    Cały problem polega na tym jak wskaźnik do tej tablicy przekazać do funkcji? Przekazanie jako **pointer nie działa.

    Zamieszczam kawałki kodu:

    Fragment tablicy:
    
    //BitMap1 - sample
    uint8_t PROGMEM bitmap1 [][6] =
    {
    	{ 0xFF, 0x81, 0xBD, 0xBD, 0x81, 0xFF },   // 0
    	{ 0xFF, 0x81, 0xBD, 0xBD, 0x81, 0xFF },   // 1
    	{ 0xFF, 0x81, 0xBD, 0xBD, 0x81, 0xFF },   // 2
    	{ 0xFF, 0x81, 0xBD, 0xBD, 0x81, 0xFF },   // 3
    	{ 0xFF, 0x81, 0xBD, 0xBD, 0x81, 0xFF },   // 4
    	{ 0xFF, 0x81, 0xBD, 0xBD, 0x81, 0xFF },   // 5
    
            itd.
    
    }
    



    Funkcja:

    
    void lcd_ShowBitMap(void) // Tutaj musi być ten "magiczny" wskaźnik
    {
    	uint8_t i = 0, j = 0;
    	lcdCacheIdx = 0;
    
    	for(; i < RAM_BLOCKS; i++)
    	{
    		lcd_base_addr(lcdCacheIdx);
    		
    		// 1 block drawing
    		for(j = 0; j < 6 ; j++)
    		{
    			lcd_send(pgm_read_byte(&bitmap2[i][j]), LCD_DATA); // i tutaj także
    		}
    			
    		lcdCacheIdx += 6;
    	}	
    }
    

    Pozdrawiam serdecznie
    Krzysiek

    Usunąłem "problem", z tytułu.
    [zumek]
  • REKLAMA
  • #2 7036541
    Freddie Chopin
    Specjalista - Mikrokontrolery
    Zasadniczo po pierwsze, do funkcji można przekazywać nie tylko wskaźniki, ale i tablice:

    void func(uint8_t array[][6])
    { ... }

    Podobnie jak przy deklaracji samej tablicy - można pominąć "skrajnie lewy" wymiar.

    Spróbuj czy takie coś by nie działało jeśli dodasz atrybut PROGMEM do tego parametru.

    Po drugie zaś - parametr PROGMEM musisz podać również do funkcji, więc jej prototyp powinien wyglądać mniej więcej tak:

    void func(uint8_t * PROGMEM * PROGMEM array)
    { ... }

    Poexperymentuj z różnymi kombinacjami [;

    W ostateczności zawsze możesz po prostu sprawdzić jaki rozmiar ma taki wskaźnik (przez sizeof(), choć pewnie zajmuje on 4 bajty) i wysyłać do funkcji daną o odpowiednim rozmiarze, a następnie rzutować ją sobie na dowolny typ, albo wprost podać tą zmienną do pgm_read_...()

    4\/3!!
  • #3 7036589
    michalko12
    Specjalista - Mikrokontrolery
    
    #define pgm_read_byte(address_short) pgm_read_byte_near(address_short)
    
    
    #define pgm_read_byte_near(address_short) __LPM((uint16_t)(address_short))
    
    
    #define __LPM(addr) __LPM_classic__(addr)
    
    
    #define __LPM_classic__(addr)   \
    (__extension__({                \
        uint16_t __addr16 = (uint16_t)(addr); \
        uint8_t __result;           \
        __asm__                     \
        (                           \
            "lpm" "\n\t"            \
            "mov %0, r0" "\n\t"     \
            : "=r" (__result)       \
            : "z" (__addr16)        \
            : "r0"                  \
        );                          \
        __result;                   \
    }))
    
    
    
    #define PROGMEM __ATTR_PROGMEM__
    
    
    #define __ATTR_PROGMEM__ __attribute__((__progmem__))
    
    




    Przeanalizuj dokładnie definicję makra pgm_read_byte(address_short).
    Do tego makra podajesz liczbę która jest adresem czyli nie wskaźnik do wskaźnika
    a sam wskaźnik.

    lcd_ShowBitMap(&(bitmap1[i][j]))



    void lcd_ShowBitMap(void *p) // Tutaj musi być ten "magiczny" wskaźnik
    {
       uint8_t i = 0, j = 0;
       lcdCacheIdx = 0;
    
       for(; i < RAM_BLOCKS; i++)
       {
          lcd_base_addr(lcdCacheIdx);
          
          // 1 block drawing
          for(j = 0; j < 6 ; j++)
          {
             lcd_send(pgm_read_byte(p), LCD_DATA); // i tutaj także
          }
             
          lcdCacheIdx += 6;
       }   
    } 
    
    


    Spróbuj ;)
REKLAMA