spatna funkce switch case

Zdravim, pokousel jsem se napsat kod pro maticovou klavesnici 4x4, problem nastal se switch casem, do jednoho z 16 casu to skoci bez problemu, za jednotlivymi “casy” mam if, kdyz se nesplni, tak to skoci az na posledni else z 16. Cast kodu je zde

[code]
void klavesnice_cteni(void)

{
while(1)
{
portef = PINF;
switch (portef)
{
case 0b11101110: if (osetreno)
{
pom_znak+=0b00000001;
lcd_gotoxy (0,2);
lcd_puts("1 “);
posun_radku();
}
else
{
lcd_gotoxy (0,2);
lcd_puts(”- ");
zakmit();
}
break;

	case 0b11011110: if (osetreno) 
						{
						pom_znak+=0b00000010;
						lcd_gotoxy (0,2);
						lcd_puts("2    ");		
						posun_radku();
						}				
					  else 
					       {
						lcd_gotoxy (0,2);
						lcd_puts("-    ");
						zakmit();
						}
					  break;


     default:  lcd_gotoxy (0,2);
	      lcd_puts("-");
	      break;
	}
}

}[/code]

:arrow_right: administrator: přesunuto z "Ostatní"

Zkusil bych přidat závorky takto :

void klavesnice_cteni(void)

{      
   while(1)
   {      
      portef = PINF;
      switch (portef)
      {
      case 0b11101110:
                      {  
                           if (osetreno)
                           {
                           pom_znak+=0b00000001;
                           lcd_gotoxy (0,2);
                           lcd_puts("1    ");      
                           posun_radku();   
                           }            
                          else
                             {
                           lcd_gotoxy (0,2);
                           lcd_puts("-    ");
                           zakmit();
                           }
                      }
                    break;

      case 0b11011110:
                      { 
                           if (osetreno)
                           {
                           pom_znak+=0b00000010;
                           lcd_gotoxy (0,2);
                           lcd_puts("2    ");      
                           posun_radku();
                           }            
                          else
                               {
                           lcd_gotoxy (0,2);
                           lcd_puts("-    ");
                           zakmit();
                           }
                      }
                    break;


         default:  lcd_gotoxy (0,2);
            lcd_puts("-");
            break;
      }
   }
}

Nevím, jestli to pomůže a teoreticky by to mělo být jedno, ale za zkoušku nic nedáš …

Za dvojbotkou zatvorku a za breakom tiez, v kazdoma case

Nemělo by se projevit, na závorky to bylo v pořádku (pokud překladač funguje správně).

Nevím jaký to je MCU - nepřeteče zásobník, že by to pak skočilo kam nemá?

Nebo chyba úvahy - protože jsou všechny else stejné. Jestli to zjišťuješ v debuggeru, tak pak je pravděpodobné, že to takto optimalizuje překladač a spojí stejné větve.

zavorky nepomohly, delam to v debuggeru v avr studiu 4, ale i kdyz to nahraju do procesoru (ATmega128), tak to stale vypisuje “-”

opravdu, kdyz zmenim obsah za else, tak se vykona spravne, jen me nenapada jak to obejit

Bez znalosti ostatního kódu (kde se bere “osetreno”) se radit nedá.

omlouvam se…

[code]

void posun_radku(void)
{
if ((n>0) && (n<5)) {
PORTF |= _BV(n-1);}

if (n == 4) {n=0;}			// po n=3 radku pokracuje od nulteho

	PORTF &= ~(_BV(n));		//naeguje n-ty radek, obdoba clear bit
	n++;
	osetreno = false;
	klavesnice_cteni();

}

void zakmit(void)
{
_delay_ms(20);
osetreno = true;
klavesnice_cteni();
}[/code]

a jeste definice osetrena…

typedef enum {false,true}boolean;
boolean osetreno = false;

To máš celé nějaké zmatené:

  • z funkce klavesnice_cteni se Ti to nikdy nevrátí, ty příkazy “break” platí jen pro přerušení větví switche

  • Voláš s nekonečnou rekurzí funkce posun_radku/zakmit s klavesnice_cteni, takže po pár průchodech se Ti zahltí stack a program se zblázní

  • “osetreno” nemá vlastně žádný význam, to nemáš dobře promyšlené. V jednom okamžiku přečteš a zobrazíš klávesu, hned to zas smažeš, počkáš 20 ms a znovu testuješ - to není ošetření zákmitů, díky tomu vidíš trvale že nic nebylo stisknuto

Možná jsi zvyklý z BASICu nebo assembleru že se skáče na labely. Ale funkce v C jsou podprogramy do kterých se vleze (uloží se návratová adresa do zásobníku) a ze kterých se to po ukončení vrátí (obnoví se ze zásobníku původní adresa programu).

Dekuji za pripominky, pravda, nejvic jsem delal v assemberu a basicu :confused: program jsem opravil :smiley: