V minulém díle jsme si napsali náš první program v C. Dnes se podívame, jak si tento program odkrokovat v AVR studiu. Může se to hodit když vám něco „nechodí tak, jak má“. Složitější algoritmy je dobré krokovat vždy…
Předně si musíme říci, co budeme potřebovat:
- CodeVision AVR
- AVR Studio (verze 4)
- Projekt z minulého dílu
Jak na to?
- Otevřete projekt z minulého dílu a vytvořte všechny potřebné soubory pomocí Project → MAKE.
- Volbou Settings → Debugger zkontrolujte, zda máte nastaven správný debugger (AVR studio) a správnou cestu. V opačném případě jej nastavte
- Volbou Tools → Debugger spusťte AVR Studio
- Otevřete v něm soubor vašeho projektu s příponou .cof (C object file), generování COF souboru musi být ale nastaveno v nastaveni projektu (záložka C compiler).
- Dále už jen musíte vybrat správný typ procesoru a debugger platform (AVR Studio) a můžete směle krokovat program :-).
C vs ASSEMBLER
Možná vás napadlo, jak vlatně vypadá váš program napsaný v C přeložen do assembleru. Samozřejmě je možné se na to podívat, a to konkrétně v souboru, který se vytvoří s příponou asm. Na první pohled se program nezdá být „tím naším“. Náš překlad se totiž nachází až úplně dole. Zde je výpis části souboru, té, která nás zajímá…
.CSEG
_main:
; 7
; 8
; 9 PORTC=0x01;
LDI R30,LOW(1)
OUT 0x15,R30
; 10 DDRC=0x01;
OUT 0x14,R30
; 11 PORTD=0x40;
LDI R30,LOW(64)
OUT 0x12,R30
; 12 DDRD=0x00;
LDI R30,LOW(0)
OUT 0x11,R30
; 13
; 14 while (1)
_0x3:
; 15 {
; 16 if ((PIND & 0x40) == 0)
SBIC 0x10,6
RJMP _0x6
; 17 PORTC |= 0x01;
SBI 0x15,0
; 18 else PORTC &=0xFE;
RJMP _0x7
_0x6:
CBI 0x15,0
; 19 };
_0x7:
RJMP _0x3
; 20 }
_0x8:
RJMP _0x8
; 21
Nastavení portů nám je asi jasné. Zřejmě Vás může mást, že porty nejsou označovány zástupnými jmény. V tomto případě jsou už použity přímo adresy registrů pro dané porty.
Zajímavější je ale samotná výkonná část programu. Všimněte si inteligence překladače, který smyčku
while (1)
{
...
}
rovnou převedl na nekonečný cyklus
_0x3:
...
RJMP _0x3
Zajímavá je i pasáž s překladem testování stisknutí tlačítka:
; 16 if ((PIND & 0x40) == 0)
SBIC 0x10,6
RJMP _0x6
; 17 PORTC |= 0x01;
SBI 0x15,0
; 18 else PORTC &=0xFE;
RJMP _0x7
_0x6:
CBI 0x15,0
; 19 };
_0x7:
Překladač celou podmínku nahradil podmíněným přeskokem. Je-li bit 6 na portu D nulován, pak se přeskočí instrukce RJMP _0x6 a tím se provede nastavení pinu PORTC,0 a program skočí na konec smyčky…
Tento díl je bohužel kratší. Nechci začínat novou věcí v půli článku. Příští díl bude spíše teoretický (omlouvám se všem praktikům :-)). Řekneme si něco o časovačích/čítačích.