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

[C][atmega8] czyżby za długa tablica char??

hessuss 30 Cze 2009 19:55 2037 9
REKLAMA
  • #1 6723132
    hessuss
    Poziom 13  
    Witajcie.
    Bawię się matryca 8x8
    napisałem sobie multiplexowanie i procedurkę wyświetlającą napis po kolei po literce, wszystko fajnie jest niestety do kiedy długość mojego napisu nie przekroczy 48znaków, wtedy zaczynają sie dziać cuda, niektóre litery wyświetla normalnie a zamiast innych takie krzaki których nie mam w tablicy znaków ascii w ogóle zapisanych, najgorsze że te krzaki wyświetla nie po 48znaku dopiero ale czasem w środku, czasem na początku, normalnie jak się bestii chce. Piszę w AVRStudio, proszę o pomoc.

    
    #include <avr/io.h>     
    #include <string.h>
    
    #define F_CPU 2000000 //2MHz zegar procesora 
    #define CYCLES_PER_US ((F_CPU+500000)/2000000) //cpu cycles per microsecond  
    
    #include <util/delay.h> 
    
    (...)
    char FontTable[97][8] = 
       { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // (blank) //0 
    (...)
    };
    
    void pojednej(char napis[])
    {
    int j = 0;
    int litera = 0;
    int aktznak = 0;
    	// weź znak z komunikatu
    	while(aktznak<strlen(napis))
    	{
    		litera = (napis[aktznak])-32;
    		//litera = clitera-32;
    		aktznak++;
    		ekran[0][0]=FontTable[litera][0];
    		ekran[1][0]=FontTable[litera][1];
    		ekran[2][0]=FontTable[litera][2];
    		ekran[3][0]=FontTable[litera][3];
    		ekran[4][0]=FontTable[litera][4];
    		ekran[5][0]=FontTable[litera][5];
    		ekran[6][0]=FontTable[litera][6];
    		ekran[7][0]=FontTable[litera][7];
    		
    		for (j=0;j<=4;j++)
    		{
    			wyswietl();
    		}
    	}	
    }
    
    (...)
    
    int main () 
    { 
    	/* Wszystkie linie portu B będą wyjściami */
    	DDRB = 0xFF;  /* 0xFF binarnie 1111 1111 */
    	/* Wszystkie linie portu D będą wyjściami */
    	DDRD = 0xFF;  /* 0xFF binarnie 1111 1111 */
    	PORTB = 0b00000000;    /* 0xaa binarnie 0000 0000 */
    	PORTD = 0b00000000;    
    
    	char napis[] = "abcdefghijklmnoprstuvw1234567890abcdefghijklmnoprstuvw1234567890ABCDEFGHIJKLMNOPRSTUVWabcdefghijklmnoprstuvw1234567890a_teraz_znaki_!@#$%^&*()_i_KONIEC_i_Kropka.";
    	while(1)
    	{	
    		pojednej(napis);
    	}	
    //return 0; 
    }
    }
  • REKLAMA
  • Pomocny post
    #2 6723326
    arrevalk
    Poziom 25  
    Raczej za długa. ATMega8 ma 1kB RAM. A Ty do niego ładujesz dwie wielkie tablice:
    FontTable[97][8] czyli 776B
    napis[161] czyli 161B
    razem: 937B tylko na te dwie tablice!!!. Zostaje 87B na pozostałe zmienne i stos.
    Jeżeli dobrze pamiętam stos w ATMegach zajmuje pamięć od "góry" więc pewnie nadpisuje ci tablice napis. A z tego co widzę to jeszcze w programie masz trzecią tablicę ekran o nieznanym rozmiarze (niema jej definicji w kodzie).
  • REKLAMA
  • #3 6724527
    hessuss
    Poziom 13  
    No tak, i sprawa się rypsła :)
    Jak zwykle mądrego to dobrze posłuchać :)
    jest jakiś patent na to? obiło mi się o oczy coś pod tytułem progmem, da się tym to ugryźć? a może trzymać te tablice w zewnętrznej pamięci? jakiś eeprom typu 24cxx czy najprościej kupić większą atmegę? W planach chcę mieć na stałe dwie tablice ze znakami ASCII zwykłe litery i pogrubione oraz tablicę bufor i ekran o wymiarach 8x8 bitów do tego możliwość wprowadzenia przynajmniej kilku-kilkunastu napisów takich po 150 znaków.
  • REKLAMA
  • Pomocny post
    #4 6724915
    markosik20
    Poziom 33  
    char FontTable[97][8] PROGMEM =
       { { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },   // (blank) //0
    (...)
    }; 



    i RAM będzie wolny :wink:. I pamiętaj że do czytania takiej tablicy musisz wykorzystać wbudowane w winAVR
    pgm_read_byte(address_short); 
  • REKLAMA
  • #7 6725744
    maly_elektronik
    Poziom 23  
    Aha :) Najwyraźniej źle zrozumiałęm twojego posta :)
  • #8 7330986
    greg_001
    Poziom 12  
    Tez chciałem korzystać z arrybytu PROGMEM, do pojedynczych zmiennych to działa i nie kopiuje danych do ramu, jednak do tablicy to nie chce działać.

    
    #include <avr/io.h>
    #include <avr/iom16.h>
    #include <avr/pgmspace.h>
    
    volatile int a PROGMEM =0x57;
    
    //int FontTable[8] PROGMEM =   {  0x40, 0x50, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00 };
    
    int main(void)
    {
    	while(1)
    	{
    		int x=pgm_read_byte(&a);	
    		x++;
    		
    	}
    	return 0;
    }
    


    Kiedy odznacze tablice to wyskakuje błąd FOntTable causes a section type conflict.
    Miał ktoś z tym do czynienia?
  • #9 7331083
    Konto nie istnieje
    Poziom 1  
  • #10 7331103
    greg_001
    Poziom 12  
    Dziękuje:)

    Głupi błąd
REKLAMA