Problem med if-sats

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Glattnos
Inlägg: 2984
Blev medlem: 29 oktober 2009, 20:01:18

Problem med if-sats

Inlägg av Glattnos »

Vad är problemet här:

Kod: Markera allt

int x;

while (1) 
{
   if(x > 2)
   {
      PORTB ^= 1 << STEP_PIN; //Toggle STEP-pin
      x = 0;
   }
}
Borde det inte betyda att om värdet av x är större än 2 så ska if-koden köras?

Hela koden:

Kod: Markera allt

#include <avr/io.h>
#include <avr/interrupt.h>

#define STEP_PIN 1

int x;

ISR (TIM0_OVF_vect) //Timer0 OverFlow vector
{
	x++;
}

int main(void)
{
    DDRB = (1<<DDB1)|(1<<DDB0); //Set pin 0(DIR) and 1(STEP) as outputs
	
	TCCR0B = (0<<CS02)|(1<<CS01)|(0<<CS00); //Start Timer0
	TIMSK0 = (1<<TOIE0); //TimerOverflowInterruptEnable
	
	sei(); //EnableGlobalInterrupt
	
    while (1) 
    {
		if(x > 2)
		{
			PORTB ^= 1 << STEP_PIN; //Toggle STEP-pin
			x = 0;
		}	
    }
}
x ökar med 1 varje gång timern ger overflow men den går aldrig in i if-koden och nollställer x :humm:
Shimonu
Inlägg: 295
Blev medlem: 21 oktober 2015, 22:44:33

Re: Problem med if-sats

Inlägg av Shimonu »

X var inte definierad första gången det kördes

.
Glattnos
Inlägg: 2984
Blev medlem: 29 oktober 2009, 20:01:18

Re: Problem med if-sats

Inlägg av Glattnos »

Jag är inte helt med på hur du menar. Om man kollar på hela koden, borde inte det funka då?
I Atmel Studios simulator ser jag att x bara ökar och ökar men den hoppar över if-koden varje gång. Har kört koden på en uC också och det är samma resultat. Skriver jag "if(1)" så går den in och skapar en fyrkantsvåg ut :humm:
metric
Inlägg: 766
Blev medlem: 16 maj 2010, 11:04:52

Re: Problem med if-sats

Inlägg av metric »

Ska det inte vara int x=0;
Annars kan väl x vara vad som helst från början?
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4694
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: Problem med if-sats

Inlägg av Swech »

kompilatorn tycker att x inte ändrar sig.
Du pillar ju på den i en interrupt
Kan inte C men det är väl volatile eller liknande som X skall definieras som
Swech
Glattnos
Inlägg: 2984
Blev medlem: 29 oktober 2009, 20:01:18

Re: Problem med if-sats

Inlägg av Glattnos »

Absolut, så ska det ju vara!

Kod: Markera allt

volatile int x;
kodar-holger
EF Sponsor
Inlägg: 920
Blev medlem: 26 maj 2014, 12:54:35
Ort: Karlskoga

Re: Problem med if-sats

Inlägg av kodar-holger »

Du behöver volatile-deklarera x till att börja med. Optimeraren jobbar väldigt närsynt och ser att ingen gör något med x i main så den kan ta bort saker bäst den vill eftersom x aldrig kommer att bli >0. Och även om den inte tar bort saker kommer den nog att lägga den i ett register som din interruptrutin inte kommer åt. Volatile löser detta.

Sen vet du inte vad x är när programmet startar. Minnet kan innehålla vad som helst. Du måste alltså själv initialt sätta x till 0 (eller något annat värde), annars vet du inte vad som händer. Kanske är x 0, kanske 4711, kanske -2^32.
Glattnos
Inlägg: 2984
Blev medlem: 29 oktober 2009, 20:01:18

Re: Problem med if-sats

Inlägg av Glattnos »

Tackar för svaren :)
Att x inte gavs något värde var mest för att jag hade tagit bort det i felsöknings-syfte. Om x var någonting annat än 0,1 eller 2 vid programstart så skulle den ju ändå nollställas direkt :) Eller ja, kunde ju varit negativt tal också så helt rätt :)
Mr Andersson
Inlägg: 1397
Blev medlem: 29 januari 2011, 21:06:30
Ort: Lapplandet

Re: Problem med if-sats

Inlägg av Mr Andersson »

kodar-holger skrev:Sen vet du inte vad x är när programmet startar. Minnet kan innehålla vad som helst. Du måste alltså själv initialt sätta x till 0 (eller något annat värde), annars vet du inte vad som händer. Kanske är x 0, kanske 4711, kanske -2^32.
Hur många gånger har vi inte behandlat detta här på forumet?
Globala variabler är garanterade att initialiseras till 0.
Användarvisningsbild
Icecap
Inlägg: 26147
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Problem med if-sats

Inlägg av Icecap »

Svaret är (som det redan står) att då x inkrementeras av en INTERRUPT-rutin måste deklareras som volatile.

Annars kommer optimeringen att anse att x inte ändras varför det optimeras bort.

Detta skriver jag för förtydliga förandra, det är ju en icke-ovanlig situation som uppstår lite då o då (fast då aldrig för mig :vissla:).
Polyene
Inlägg: 20
Blev medlem: 29 juli 2018, 09:31:40

Re: Problem med if-sats

Inlägg av Polyene »

Utöver att x ska vara volatile så kommer du att få andra problem med koden som du nog inte tänkt på. Vad händer om interruptet sker på den rad som modifierar PORTB? Jo interruptet kommer att öka x, men sedan nollas x direkt när man återvänder från interruptet, så du tappar den ökningen.

Ett annat potentiellt problem är om int skulle vara större än ett dataord för processorn (beror på processor och kompilator), då riskerar man andra konstigheter.

Man brukar se till att stänga av interruptet i mainkoden under den tid man behandlar variabler som är gemensamma för main och interrupt, då undviker man båda dessa problem.
Glattnos
Inlägg: 2984
Blev medlem: 29 oktober 2009, 20:01:18

Re: Problem med if-sats

Inlägg av Glattnos »

Om interruptet händer på raden som modifierar PORTB så skulle x bli 4 och ska ändå nollställas eftersom det ska nollställas varje gång det blir över 2.

Det här med volatile brukar jag ju fråga ungefär en gång per år :)
Polyene
Inlägg: 20
Blev medlem: 29 juli 2018, 09:31:40

Re: Problem med if-sats

Inlägg av Polyene »

Jag trodde nog att du ville att det skulle togglas på PORTB efter var tredje interrupt, men om x räknas upp till 4 och sen nollas så missar du ett interrupt så att det kommer att bli fyra interrupt mellan de två togglingarna. Men det kanske är så du vill ha det, även om det känns ovanligt?
Glattnos
Inlägg: 2984
Blev medlem: 29 oktober 2009, 20:01:18

Re: Problem med if-sats

Inlägg av Glattnos »

Precis så var det jag ville ha det, x var bara en räknare som kollades i programmet för att toggla när ett visst värde nåddes :) Egentligen så var det när x var över 150 men jag ändrade till 2 i felsöknings-syfte. Jag har gjort om nu så att det inte räknas utan istället togglar direkt i avbrottsrutinen och så har jag större prescaler på timern istället :)
Kör på en Attiny13 så det gäller att hålla nere kod-storleken :mrgreen:
Skriv svar