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

[ATMega32][C] Wywołanie funkcji w Main nie działa

Piotrek_P 19 Paź 2010 21:04 1799 2
REKLAMA
  • #1 8640000
    Piotrek_P
    Poziom 18  
    Witam,

    Piszę od jakiegoś czasu mój pierwszy ambitniejszy program w C na AVR, i przy okazji sukcesywnie poznaję ten język. Ostatnio zabrałem się za projektowanie prostego menu i utknąłem. Na początek przejrzałem projekty takie jak MicroMenu, TinyMenu itp., ale stwierdziłem że wskaźniki do struktur i funkcji to jeszcze nie mój czas, chociaż wydaje mi się że to mogło by rozwiązać problemy z którymi się aktualnie borykam (kwestia opanowania wskaźników). Co do sedna problemu to mam taki kod programu głównego:

    
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/pgmspace.h>
    #include <inttypes.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #include "SPI_routines.h"
    #include "SD_routines.h"
    #include "UART_routines.h"
    #include "FAT32.h"
    #include "HD44780.h"
    
    
    
    
    #define key_ESC   2
    #define key_UP 	  3
    #define key_DOWN  4
    #define key_ENTER 5
    #define beeper    7
    
    const uint8_t max_menu_idx = 2;
    uint8_t menu_idx = 0;
    uint8_t func_idx = 0;
    
    
    const uint8_t MN100[] PROGMEM="Start logu";
    const uint8_t MN200[] PROGMEM="Kalibracja";
    const uint8_t MN300[] PROGMEM="Ustawienia";
    
    
    
    void Init_devices(void)
    {
    	_delay_ms(100);  //delay for VCC stabilization
    	MCUCR = 0x00;
    	GICR  = 0x00;
    	TIMSK = 0x00;
    	 
    	PORTB = 0xEF;
    	DDRB  = 0xBF; //MISO line i/p, rest o/p
    
    	DDRD  = 0xFF;
    	DDRD&=~ (_BV(2) | _BV(3) | _BV(4) | _BV(5));//set PORTD pins to zero as input
    	PORTD = 0x00;  
    	PORTD|= (_BV(2) | _BV(3) | _BV(4) | _BV(5));//Enable pull up's
    
    	LCD_Init();
    	LCD_Clear();
    
    	spi_init();
    
    	SD_init();
    	//SPI_HIGH_SPEED;	//SCK - 4 MHz
    
    
    }
    
    
    void splash_scr(void)
    {
    
    	LCD_GoTo(0,0);
    	LCD_WriteText("Loger v2.1");
    	LCD_GoTo(0,1);
    	LCD_WriteText("Press any key...");
    
    }
    
    
    void Kalibracja(void)
    {
    
    	LCD_GoTo(4,1);
    	LCD_WriteText("Obliczanie");
    	
    
    }
    
    
    void Menu(uint8_t idx)
    {
    
    	
    	LCD_GoTo(0,0);
    	LCD_WriteText("Menu:");
    	LCD_GoTo(6,0);
    	
    	switch (menu_idx)
    
    	{
    	case 0 : LCD_WriteTextP(MN100);
    			 break;
    			 
    	case 1 : LCD_WriteTextP(MN200);
    			 break;
    
    	case 2 : LCD_WriteTextP(MN300);
    			 break;
    	}
    }
    
    
    uint8_t Wait_for_key(void)
    {
    	
    	uint8_t key_id = 0;
    	
    
    	while(1)
    	{
    
    		if (bit_is_clear(PIND, 2))//if button is pressed		
    		{			
    
    			_delay_ms(10);
    			loop_until_bit_is_set(PIND, key_ESC);
    			key_id = key_ESC;
    			func_idx = 0;
    			break;						
    		}
    
    		if (bit_is_clear(PIND, 3))//if button is pressed		
    		{			
    
    			_delay_ms(10);
    			loop_until_bit_is_set(PIND, key_UP);
    			key_id = key_UP;
    			if (menu_idx > 0)
    				menu_idx--;
    			else
    				menu_idx = max_menu_idx;
    
    			break;
    
    		}
    
    		if (bit_is_clear(PIND, 4))//if button is pressed		
    		{			
    
    			_delay_ms(10);
    			loop_until_bit_is_set(PIND, key_DOWN);
    			key_id = key_DOWN;
    			if (menu_idx < max_menu_idx)
    				menu_idx++;
    			else
    				menu_idx = 0;
    			break;
    
    		}
    
    		if (bit_is_clear(PIND, 5))		
    		{			
    
    			_delay_ms(10);
    			loop_until_bit_is_set(PIND, key_ENTER);
    			key_id = key_ENTER;
    			switch (menu_idx)
    			{
    			case 0 : ;
    					
    			case 1 : func_idx = 1;
    			case 2 :; 
    			}
    
    
    			break;
    		}
    
    
    
    	}
    	return(key_id);
    
    }
    
    
    
    
    
    
    // PROGRAM GLOWNY
    
    int main(void)
    {
    	
    	unsigned char s[2];
    	uint8_t idx;
    
    
    	Init_devices();
    	splash_scr();
    	Wait_for_key();
    	LCD_Clear();
    
    	menu_idx = 0;
    	func_idx = 0;
    
    	while(1)
    	{
    		Menu(menu_idx);
    
    		dtostrf(menu_idx,1,0,s);
    		LCD_GoTo(0,1);
    		LCD_WriteText(s);
    		dtostrf(func_idx,1,0,s);
    		LCD_GoTo(1,1);
    		LCD_WriteText(s);
    
    		switch (func_idx)
    		{
    		case 0 : ;
    		case 1 : Kalibracja;	
    		case 2 : ;
    		}	
    		idx = Wait_for_key();
    
    
    	}
    
    	return(0);
    }
    


    Kod jest w wersji roboczej i ogólnie działa, ale jest jedno "ale". W głównej pętli programu, w sekcji "switch -> case 1" funkcja "Kalibracja" nie jest wywoływana. Już na etapie kompilacji pojawia się komunikat iż :
    "../Loger_v2_1.c:215: warning: statement with no effect"

    Nie bardzo rozumiem dla czego tak jest. W funkcji Kalibracja, na początek dałem tylko funkcje wyświetlające komunikat na LCD, żeby widzieć co się dzieje. Co ciekawe, jak w "Case 1 : " wywołam od razu funkcje LCD_xxxx to te są wykonywane bez problemu.
    Zastanawiam się czy ze stosem jest wszystko OK, ale nie umiem jak na razie tego sprawdzić.

    Proszę o jakąś podpowiedź

    Pozdrawiam
    Piotrek_P

    inventco.eu - tytuł poprawiłem. Regulamin p.11.1
  • REKLAMA
  • Pomocny post
    #2 8640026
    gdL
    Poziom 27  
    case 1 : Kalibracja; 


    a nie

    ?? :)
  • #3 8640164
    Piotrek_P
    Poziom 18  
    No racja, wielkie dzięki. Ciekawe że w "nie swoich" funkcjach o nawiasach pamiętałem a co do moich to jakaś "pomroczność jasna" mnie dopadła :oops:

    Dzięki
    Pozdrawiam
    Piotrek
REKLAMA