Mikroprozessoren Grundlagen Aufbau, Blockschaltbild Grundlegende Datentypen AVR-Controller Anatomie Befehlssatz Assembler Speicherzugriff Adressierungsarten Kontrollstrukturen Stack Input / Output (I/O) Parallel I/O Seriell I/O Timer Zusammenfassung I/O Interrupt Mathematische Operationen
Kontrollstrukturen goto while if do for switch
Programmspeicher ATMEGA128 0x0000 LPM 0x0004 Reset... Vektoren... Interrupt Vektoren 0x0048 variabel Konstante Programm Rest von 128k Bytes Pgmend=0xffff 2 Byte Worte 2 Byte
Sprungbefehl jmp PC k 0 k < 4M.cseg.org 0 jmp main ;reset vector ;Nach Int. Vektoren.org 0x50 main: ;summe = 1+1 ldi R16,1 ;summand 1 ldi R17,1 ;summand 2 add R16,R17 ;addieren catch: jmp catch ;Endlosschleife...
Sprungbefehl rjmp PC PC + k + 1-2048 k < 2048.org 0 rjmp main ;reset vector.org 0x50 ;Nach Int. Vektoren main: ;summe = 1+1 ldi R16,1 ;summand 1 ldi R17,1 ;summand 2 add R16,R17 ;addieren catch: rjmp catch ;Endlosschleife...
Bedingte Sprünge Relative Sprünge abhängig vom Wert der Flags Sprungweite -64/+63 bezogen auf PC + 1 (Befehl danach) Beispiel BRNE Operation: if (Z-Flag!= 1) {PC PC + 1 + k} else {PC PC + 1} Programmbeispiel: inc r17 brne weiter inc r18 brne weiter inc r19 weiter:
Bedingte Sprünge (mit einem Flag-Bit als Bedingung) Branch if flag set: yes no Carry: brcs brcc Negative: brmi brpl Overflow: brvs brvc Zero: breq brne
Bedingte Sprünge Signed: größer gleich kleiner Unsigned: größer gleich brge brlt brsh brcc Less equal greater Lower same kleiner brlo brcs higher
Bedingte Sprünge
Nachbildung von 'if' If (R0!= 0) { /* TRUE */ } else { /* FALSE */ } if: tst R0 ;Mit Umkehrbedingung breq else ;über Fall 'TRUE' springen then: ;kommt hier an bei R0!= 0... ; case TRUE rjmp endif;über Fall 'FALSE' springen else:... ; case FALSE endif:
if then else tst R0 brne no_null if( R0 == 0) aktion1(); else aktion2(); call aktion1 jmp endif no_null: call aktion2 endif: nop
while while: tst R0 breq endwhile while( R0!= 0) { aktion(); } call aktion jmp while endwhile:...
do while doloop: do { aktion(); } while( R0!= 0) call aktion tst R0 brne doloop
FOR = While? for (short int i=0;i<50;i++) {... } { short int i; While (i<50) {... i++; }
for in Assembler signed char cnt; for( cnt=0; cnt<10; ++cnt ) aktion( cnt); clr r1 loop:cpi r1,10 brge exit call inc jmp aktion r1 loop exit:
IJMP Indirect Jump Sprung = Lade Program Counter mit neuem Wert aus R31:R30 (Z-Register) ziel:nop ldi ldi ijmp nop r31,high (ziel) r30,low (ziel) GNU-Asm: lo8(),hi8()
ICALL Indirect Call icall = call (Z) main: mov R31, high(sub1) mov R30, low (sub1) icall rjmp main sub1: ret
Anwendung: Switch #include <stdio.h> void uart_init(); void sub10() {printf("hello 10\n");} void sub11() {printf("hello 11\n");} void sub12() {printf("hello 12\n");} void toswitch(int index); int main(int arg, char *arv[]) { uart_init(); printf("pgm starts\n"); to_switch(11); }
ICALL Teil 1 #include <avr/io.h>.global to_switch to_switch: ;Parameter is passed in r25:r24 cpi r24,10 ;kleiner als brlo default ;10 ergibt default-fall cpi r24,13 ;grösser gleich brsh default ;13 ergibt default Fall subi r24,10 ;relativiert auf 0 lsl r24 ;*2, da Adressen 16 Bit lang ldi ZL,lo8(Liste) ;low Byte von Listenldi ZH,hi8(Liste) ;adr. und high nach Z
ICALL, Teil 2 clr r16 ;Null für adc add ZL,r24 ;Offset für Liste addieren adc ZH,r16 ;mögliches Carry zu High Byte lpm r0,z+ ;r0 Low Byte der Fct-Adresse lpm r1,z ;r1:r0 -> Fct-Adresse movw r30,r0 :Fct-Adr. Nach Z kopieren default: icall ret ;UP aufrufen (Adr. in Z) ;zum Aufrufer zurück Liste:.word sub10,sub11,sub12 ;Liste der Funktionen-Adressen
Mikroprozessoren Grundlagen Aufbau, Blockschaltbild Grundlegende Datentypen AVR-Controller Anatomie Befehlssatz Assembler Speicherzugriff Adressierungsarten Kontrollstrukturen Stack Input / Output (I/O) Parallel I/O Seriell I/O Timer Zusammenfassung I/O Interrupt Mathematische Operationen