Stap 3: Blink.asm
Hier is de code die we vandaag bespreken:
;************************************ ; written by: 1o_o7 ; date: <2014|10|29> ; version: 1.0 ; file saved as: blink.asm ; for AVR: atmega328p ; clock frequency: 16MHz (optional) ;************************************ ; Program funcion:--------------------- ; counts off seconds by blinking an LED ; ; PD4 ---> LED ---> R(330 ohm) ---> GND ; ;-------------------------------------- .nolist .include "./m328Pdef.inc" .list ;============== ; Declarations: .def temp = r16 .def overflows = r17 .org 0x0000 ; memory (PC) location of reset handler rjmp Reset ; jmp costs 2 cpu cycles and rjmp costs only 1 ; so unless you need to jump more than 8k bytes ; you only need rjmp. Some microcontrollers therefore only ; have rjmp and not jmp .org 0x0020 ; memory location of Timer0 overflow handler rjmp overflow_handler ; go here if a timer0 overflow interrupt occurs ;============ Reset: ldi temp, 0b00000101 out TCCR0B, temp ; set the Clock Selector Bits CS00, CS01, CS02 to 101 ; this puts Timer Counter0, TCNT0 in to FCPU/1024 mode ; so it ticks at the CPU freq/1024 ldi temp, 0b00000001 sts TIMSK0, temp ; set the Timer Overflow Interrupt Enable (TOIE0) bit ; of the Timer Interrupt Mask Register (TIMSK0) sei ; enable global interrupts -- equivalent to "sbi SREG, I" clr temp out TCNT0, temp ; initialize the Timer/Counter to 0 sbi DDRD, 4 ; set PD4 to output ;====================== ; Main body of program: blink: sbi PORTD, 4 ; turn on LED on PD4 rcall delay ; delay will be 1/2 second cbi PORTD, 4 ; turn off LED on PD4 rcall delay ; delay will be 1/2 second rjmp blink ; loop back to the start delay: clr overflows ; set overflows to 0 sec_count: cpi overflows,30 ; compare number of overflows and 30 brne sec_count ; branch to back to sec_count if not equal ret ; if 30 overflows have occured return to blink overflow_handler: inc overflows ; add 1 to the overflows variable cpi overflows, 61 ; compare with 61 brne PC+2 ; Program Counter + 2 (skip next line) if not equal clr overflows ; if 61 overflows occured reset the counter to zero reti ; return from interrupt
Zoals u zien kunt, zijn mijn opmerkingen een beetje meer korte nu. Zodra we weten wat de opdrachten in de instructieset doen hoeven we niet uit te leggen dat in commentaren. We moeten alleen uitleggen wat er gaande is vanuit het oogpunt van het programma.
We zullen bespreken wat dit allemaal stuk voor stuk, maar eerst laten we proberen om een mondiaal perspectief. Het hoofdonderdeel van het programma werkt als volgt.
Eerst ingesteld bit 4 van PORTD met "sbi PORTD, 4" Dit stuurt een 1 naar PD4 waardoor de spanning naar 5V op die pin. Dit zal de LED oplichten. Wij springen aan de "vertraging" subroutine die uit 1/2 telt een tweede (we zullen uitleggen hoe ze dat doet dit later). Vervolgens keren we terug om te knipperen en schakelt u bits 4 op PORTD waarin PD4 te 0V en vandaar uitschakelt als de LED. We dan voor een andere 1/2 seconden vertraging, en vervolgens sprong terug naar het begin van het knipperen weer met "rjmp blink".
U moet deze code uitvoert en ziet dat het doet wat het zou moeten.
En daar heb je het! Dat is alles wat deze code doet fysiek. De interne mechanismen van de microcontroller is doen een beetje meer betrokken zijn en dat is waarom wij doen deze tutorial. Dus laten we bespreken elke sectie op zijn beurt.