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

[Avr][C] Optymalizacja kodu

oskar777 09 Sty 2011 01:36 1641 4
  • #1 8979820
    oskar777

    Poziom 26  
    Witam Was, mam takie pytanie.
    otóż stworzyłem sobie kod mówiąc ogólnie, kod działa prawidłowo i tak jak zakładałem, ale ponieważ pisze w C od nie dawna to podejrzewam, że można to napisać ładniej i tak by mniej procka to zajmowało.

    Przykłady:...
    
    switch (pozycja_menu) {
    
    case 1:
    	LCD_Clear();	  
    	LCD_GoTo(0,0);
    	LCD_WriteText("D-A: D-temp"); 
    	
    	stan = eeprom_read_byte((uint8_t *)0x34);
    	if(stan != 0) {
    		LCD_WriteText(" Zal"); 
    		} else {
    		LCD_WriteText(" Wyl"); 
    	}
    	
    	//temp = Display_Temperature(temp_ds[0]);
    	//LCD_WriteText(temp);
    	
    	
    	
    	LCD_GoTo(0,1);
    	temp_dsp_dol = Display_Temperature(licznik);
    	LCD_WriteText(temp_dsp_dol); 	
    	
    	LCD_WriteText(" Z:"); 
    	value_read_one = eeprom_read_word((uint16_t*)0x01);
    	temp_dsp_dol = Display_Temperature(value_read_one);
    	LCD_WriteText(temp_dsp_dol); 
    	
    	
    			if(numer == 4) {
    			_delay_ms(450);		
    			save_value_eeprom(0x01,licznik);
    			licznik = 0;
    			}
    			
    			if(numer == 5) {
    			_delay_ms(450);		
    				char stan;
    				stan = eeprom_read_byte((uint8_t *)0x34);
    				if(stan == 0) {
    				eeprom_write_byte((uint8_t *)0x34, 1);
    				} else {
    				eeprom_write_byte((uint8_t *)0x34, 0);
    				}
    			}
    			
    	
    	
    break;	
    	
    case 2:
    	LCD_GoTo(0,0);
    	LCD_WriteText("D-B: D-temp"); 
    	
    	stan = eeprom_read_byte((uint8_t *)0x34);
    	if(stan != 0) {
    		LCD_WriteText(" Zal"); 
    		} else {
    		LCD_WriteText(" Wyl"); 
    	}
    
    	LCD_GoTo(0,1);
    	temp_dsp_dol = Display_Temperature(licznik);
    	LCD_WriteText(temp_dsp_dol); 	
    			if(numer == 4) {
    			_delay_ms(450);
    			save_value_eeprom(0x03,licznik);
    			licznik = 0;
    			}
    			
    			if(numer == 5) {
    			_delay_ms(450);		
    				char stan;
    				stan = eeprom_read_byte((uint8_t *)0x34);
    				if(stan == 0) {
    				eeprom_write_byte((uint8_t *)0x34, 1);
    				} else {
    				eeprom_write_byte((uint8_t *)0x34, 0);
    				}			
    			}
    	LCD_WriteText(" Z:"); 
    	value_read_one = eeprom_read_word((uint16_t*)0x03);
    	temp_dsp_dol = Display_Temperature(value_read_one);
    	LCD_WriteText(temp_dsp_dol); 	
    
    break;
    
    



    
    n0_eeprom_1_dol = eeprom_read_word((uint16_t*)0x01);
    n0_eeprom_2_dol = eeprom_read_word((uint16_t*)0x03);
    
    if((int16_t) temp_ds[0] <= (int16_t) n0_eeprom_1_dol || (int16_t) temp_ds[1] <= (int16_t) n0_eeprom_2_dol) {
    alarm_lcd_1_dol = 1;
    		
    		// alarm do buzera
    		if(wyczisz_namiot_1_dol == 1) {
    			PORTB |= 1<<2;
    		} else 	{
    			PORTB &= ~(1<<2);		
    		}
    
    		if(numer == 2) {
    			// wyciszenie alarmu
    			_delay_ms(500);
    			wyczisz_namiot_1_dol = 1;
    			PORTB |= 1<<2;
    		}
    } else if((int16_t) temp_ds[0] > (int16_t) n0_eeprom_1_dol && (int16_t) temp_ds[1] > (int16_t) n0_eeprom_2_dol) {
    // wylacz alarm
    wyczisz_namiot_1_dol = 0;
    alarm_lcd_1_dol = 0;
    PORTB |= 1<<2;
    
    }
    
    


    W pierwszym przypadku mam kilkanaście takich pozycji w case, jedynie niektóre dane się zmieniają, w drugim w sumie też ta sama bajka jest kilka takich sekcji.

    Ma ktoś jakieś pomysły ?
    Ps. pisałem tak jak potrafię najlepiej, więc proszę o darowanie sobie komentarzy w stylu co to k.. jest.

    Pozdrawiam
  • #2 8980052
    tmf
    VIP Zasłużony dla elektroda
    Zastosować wskaźniki do funkcji. Czyli w strukturze odzwierciedlającej menu na każdej pozycji umieszczasz związaną z nią funkcję. Wtedy zamiast case będziesz miał po prostu wywołanie związanej z daną pozycją funkcji. O wskaźnikach na funkcje sobie pogoogluj.
  • #3 8980289
    Fredy
    Poziom 27  
    Jeśli masz w obu warunkach powtarzające się fragmenty to wywal je na początek przed switcha. Będzie ładniej, bardziej przejrzyście i napewno mniejszy kod.
    Chodzi mi o ten fragment :
    LCD_Clear();    
       LCD_GoTo(0,0);
       
       
       stan = eeprom_read_byte((uint8_t *)0x34);
       if(stan != 0) {
          LCD_WriteText(" Zal");
          } else {
          LCD_WriteText(" Wyl"); 


    Nie rozumiem jeszcze jednego, jeśli piszesz zaraz po sobie dwie instrukcje wyświetlające różne napisy na LCD to jaki to ma sens? Przecież procek zrobi to tak szybko że i tak zauważysz tylko ten drugi napis.
  • #4 8980321
    oskar777

    Poziom 26  
    Cytat:
    Nie rozumiem jeszcze jednego, jeśli piszesz zaraz po sobie dwie instrukcje wyświetlające różne napisy na LCD to jaki to ma sens?


    Tam masz LCD_GoTo(0,0); / LCD_GoTo(0,1); więc jest to na różnych wierszach.

    tmf mam się o to opierać >> https://www.elektroda.pl/rtvforum/topic1516455.html bo średnio rozumiem co chcesz mi przekazać jak zawsze zresztą.
  • #5 8980577
    tmf
    VIP Zasłużony dla elektroda
    Po prostu wpisz w google function pointers i poczytaj co to takiego. Jak załapiesz to zrozumiesz, że te wszystkie switch/case są niepotrzebne, bo sama pozycja menu może zawierać wskaźnik do funkcji, która ma przez tą pozycję być wykonywana.
REKLAMA