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] łańcuch, LCD i błąd. Co robię źle? Zamieszczony kod.

figa_miga 07 Lip 2010 20:15 1040 3
REKLAMA
  • #1 8271422
    figa_miga
    Poziom 19  
    Mam problem z takim programikiem, nie wiem co robię źle. Patrzyłem po innych programach i jakoś nie widziałem żeby ktoś definiował łańcuchy przed ich wywołaniem.

    AVR studio daje taki komunikat: error: 'tx_dupa' undeclared (first use in this function)tyczy się on tego polecenia w pętli while LCD_TXT((prog_char*)tx_dupa)

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <inttypes.h>
    #include <avr/pgmspace.h>
    
    #define F_CPU 11059200
    #include <util/delay.h>
    
    
        
    
    
    #define toggle(PORT, BIT) (_SFR_BYTE(PORT) ^= _BV(BIT)) 
    
    #define LCD_DDR DDRA
    #define LCD_PORT PORTA
    #define RS 0
    #define EN 1
    #define D4 2
    #define D5 3
    #define D6 4
    #define D7 5
    
    
    
    
    char zwloka= 0; 
    volatile uint8_t dsp_1=1; 
    volatile uint8_t dsp_2=2; 
    volatile uint8_t dsp_3=3; 
    volatile uint8_t dsp_4=4; 
    volatile uint8_t dsp_5=5;
    
    
    unsigned int val=1234;
    
    
    void LCD_INT(void); 
    void LCD_HOME(void); 
    void LCD_1000(unsigned int x); 
    void LCD_TXT();
    
    
    int main()
    {	
    	_delay_ms  (50);
    	DDRD=255;
    
    	DDRD=255;
    	LCD_PORT= 255;
    	LCD_DDR=1<<RS|1<<EN|1<<D4|1<<D5|1<<D6|1<<D7; 		//LINIE LCD JAKO WYJSCIA
    
    	ADMUX=0b01000111;
    	ADCSRA=0b10001111;
    
    
    
     
    	LCD_INT();
    
    //======================================================== TIMER0 dla 12MHz, czestotliwosc 560Hz dla LED
    TCCR0 |= (1<<CS02 |1<<CS00);    	//preskalesr na 1024
    TCNT0 = 0;							//wartosc licznika
    TIMSK = (1<<TOIE1 | 1<<TOIE0);		//odblokuj przerwania od przepelnien
    TIFR = 0;							//flagi przerwan
    sei();	
    
    
    	while(1)
    		{
    	
    		LCD_HOME();
    		LCD_1000(val);
    		LCD_TXT((prog_char*)tx_dupa);
    	
    
    		}
    		
    return 0;
    }
    
    
    void LCD_OUT(char x)
    	{
    		LCD_PORT &=~(1<<D4|1<<D5|1<<D6|1<<D7);
    		if(x & (1 << 4)) LCD_PORT |=1<<D4;
    		if(x & (1 << 5)) LCD_PORT |=1<<D5;
    		if(x & (1 << 6)) LCD_PORT |=1<<D6;
    		if(x & (1 << 7)) LCD_PORT |=1<<D7;
    		_delay_ms  (1) ; 
    		LCD_PORT |=1<<EN;
    		LCD_PORT &=~(1<<EN|1<<D4|1<<D5|1<<D6|1<<D7);
    		if(x & (1 << 0)) LCD_PORT |=1<<D4;
    		if(x & (1 << 1)) LCD_PORT |=1<<D5;
    		if(x & (1 << 2)) LCD_PORT |=1<<D6;
    		if(x & (1 << 3)) LCD_PORT |=1<<D7;
    		LCD_PORT |=1<<EN;
    		LCD_PORT &=~(1<<EN);
    	}
    void LCD_INT(void)
    	{	
    		LCD_PORT =~(1<<RS|1<<EN);	//4x 0011 z pierwsza zwloka
    		LCD_OUT (50);
    		LCD_OUT (50);
    		LCD_OUT (40);		//function set 2 linie 5x7 znakow
    		LCD_OUT (8);		//function set dispaly off
    		LCD_OUT (1);		//function set display on	
    		LCD_OUT (6);		//entry mode set inkrementcaja, ram statyczny
    		LCD_OUT (12);		//
    		LCD_PORT |=1<<RS;
    	}
    
    void LCD_1000(unsigned int x)
    	{
    		LCD_PORT |=1<<RS;
    	
    		
    		dsp_1 =x%10+48;
    		x = x/10;
    		dsp_2 =x%10+48;
    		x =x/10;
    		dsp_3 =x%10+48;
    		dsp_4 =x/10+48;
    	
    
    		LCD_OUT (dsp_4);
    		LCD_OUT (dsp_3);
    		LCD_OUT (dsp_2);
    		LCD_OUT (dsp_1);
    	}
    
    
    void LCD_HOME(void)
    	{
    	LCD_PORT &=~(1<<RS);
    	LCD_OUT (2);
    	_delay_ms  (5) ;
    	
    	}
    
    void LCD_TXT(char* str)
    {
    	unsigned char znak;
    	while (0 !=(znak=*(str++)))
    	LCD_PORT |=1<<RS;
    	LCD_OUT(znak);
    	
    }
    
    SIGNAL(SIG_OVERFLOW0)
    {
    
    	zwloka++;
    		if (zwloka==20)
    	 	{
    		zwloka=0; 
    		ADCSRA=0b11001111;
    		toggle (PORTD,1);
    		}
    			
    }
    
    SIGNAL(SIG_ADC)                        // przerwanie z przetwornika ADC
    {
      val = ADCW/2;                        // czytaj wartość z przetwornika ADC
     toggle (PORTD,0);
    }
    
    const unsigned char tx_dupa[] PROGMEM = "dupa";
    


    Jeśli są w ogóle jakieś krytyczne uwagi co do tego kodu to chętnie się zapoznam.
  • REKLAMA
  • #2 8271540
    Dr.Vee
    VIP Zasłużony dla elektroda
    Musisz zadeklarować tablicę zanim jej użyjesz (czyli przed funkcją main()).
  • REKLAMA
  • #3 8271547
    gaskoin
    Poziom 38  
    SIGNAL(SIG_OVERFLOW0) 


    staroć

    SIGNAL(SIG_ADC)


    staroć

    TIMSK = (1<<TOIE1 | 1<<TOIE0);      //odblokuj przerwania od przepelnien


    włączasz przerwania od TC1 a nigdzie ich nie obsługujesz, jak takowe wystąpi µC się zresetuje

    const unsigned char tx_dupa[] PROGMEM = "dupa";
    przenieś to na sam początek programu (gdziekolwiek przed maina) i problem zniknie...
  • #4 8272665
    Andrzej__S
    Poziom 28  
    figa_miga napisał:

    
    ...
    
    void LCD_TXT(char* str) 
    { 
       unsigned char znak; 
       while (0 !=(znak=*(str++))) 
       LCD_PORT |=1<<RS; // te dwie instrukcje
       LCD_OUT(znak);     // powinny być w nawiasach {}
        
    }
    
    ...
    



    Nie analizowałem dokładnie całości, ale zauważyłem co następuje:
    Kiedy do funkcji "LCD_TXT" jako argument przekażesz wskaźnik do ciągu we flash, nie będzie działać znak=*(str++). Np. w WinAvr do odczytu z flash należy użyć funkcji pgm_read_byte (<avr/pgmspace.h>). Jeśli chcesz wyświetlać ciągi z flash'a powinieneś zmodyfikować funkcję "LCD_TXT" lub najpierw skopiować dane z flash do jakiegoś bufora w RAM (za pomocą funkcji "strcpy_P") i później przekazać wskaźnik do tego bufora do swojej funkcji.

    Szczegóły w avr-libc-user-manual "Storing and Retrieving Strings in the Program Space".
REKLAMA