A wystarczyło napisać
PORTB ^= 0x08; By się koledzy może jakiś operatorów pouczyli? Dziś 1 września, zatem najwyższy czas.
c4r0 pisze:Czym sie te dwie formy roznia po kompilacji?
c4v2 pisze:Podobno ?: jest operatorem porównania w c ale czym się obie formy różnią po kompilacji to nie wiem.
Symulator i debugger prawdę Ci powie.
if(PORTB) PORTB = 0x00; else PORTB = 0x08; //po prostu miganie diodą
Kod: Zaznacz cały
+00000061: B185 IN R24,0x05 In from I/O location
+00000062: 2388 TST R24 Test for Zero or Minus
+00000063: F011 BREQ PC+0x03 Branch if equal
+00000064: B815 OUT 0x05,R1 Out to I/O location
+00000065: C002 RJMP PC+0x0003 Relative jump
+00000066: E088 LDI R24,0x08 Load immediate
+00000067: B985 OUT 0x05,R24 Out to I/O location
PORTB = PORTB ? 0x00 : 0x08;
Kod: Zaznacz cały
+00000061: B185 IN R24,0x05 In from I/O location
+00000062: 2388 TST R24 Test for Zero or Minus
+00000063: F411 BRNE PC+0x03 Branch if not equal
+00000064: E088 LDI R24,0x08 Load immediate
+00000065: C001 RJMP PC+0x0002 Relative jump
+00000066: E080 LDI R24,0x00 Load immediate
+00000067: B985 OUT 0x05,R24 Out to I/O location
PORTB ^= 0x08;
Kod: Zaznacz cały
+00000061: B185 IN R24,0x05 In from I/O location
+00000062: E098 LDI R25,0x08 Load immediate
+00000063: 2789 EOR R24,R25 Exclusive OR
+00000064: B985 OUT 0x05,R24 Out to I/O location
A teraz pytanie. Która wersja jest najbardziej efektywna?
---
Baj de wej.
Kulpina:
- SIGNAL() zastąp przez ISR(), bo SIGNAL() może znienacka zniknąć (jak sławne cbi, sbi);
- Licznik w CTC sam liczy i nie trzeba przeładowywać, jak chcesz uzyskać odpowiednią dokładność to tego trybu użyj;
- Nie pisz tak: TCCR1B = 0x04; bo to nie ładnie. Lepiej TCCR1B = (1<<CS12); Przynajmniej wiadomo co masz ustawione.
Teraz czas na poprawną wersję:
Kod: Zaznacz cały
#include <avr\io.h>
#include <avr\interrupt.h>
ISR(TIMER1_COMPA_vect)
{
PORTB ^= 0x08;
}
int main(void)
{
DDRB = 0xFF; //jako wyjscia
DDRC = 0xFF;
DDRD = 0xFF;
TCCR1B = (1<<CS12)|(1<<WGM12); //prescale = 256, jako CTC
TIMSK1 = (1<<OCIE1A); //przerwanie z zerowania timera (tu)
OCR1A = 499; //skracamy licznika
sei(); //globalne zezwolenie na przerwania
while(1){
}
return 0;
}