Differences

This shows you the differences between two versions of the page.

Link to this comparison view

en:multiasm:exercisesbook:avr:sut:scenarios:avr4 [2026/05/02 10:36] – created pczekalskien:multiasm:exercisesbook:avr:sut:scenarios:avr4 [2026/05/04 12:10] (current) pczekalski
Line 1: Line 1:
 +====== AVR4: Blinking LED, Timer-based ======
 +
 +In this scenario, you will implement a classical "Hello World" application, but this time, instead of using the tick-counting method, we will use a timer to precisely tick the delay. 
 +
 +** Prerequisites **\\
 +You need to book one of the AVR laboratory nodes and ensure the video stream is live.\\
 +Get familiar with the scenario: [[avr1|]].
 +
 +** Scenario **\\
 +Create an application that toggles the built-in LED on and off 1 time per 2 seconds (the full cycle is then 4s). There are 4 LEDs on the shield you can observe; use GPIO 13 (the built-in LED on the Arduino Uno).
 +
 +** Result **\\
 +Flashing LED, observable via video stream.
 +
 +** Start **\\
 +Mind to use AVR GCC syntax (as in the instruction): node compilation facilities are preconfigured, and you do not need to build a Makefile; still, it is necessary to follow the exact AVR GCC syntax, e.g., in the case of ''.equ''.
 +
 +** Step 1 **\\
 +Compose a template for your application that includes declarations for GPIO and a timer. We use Timer1 (16-bit) in CTC mode:
 +<code asm>
 +; --- Register Address Mapping ---
 +.equ SREG,    0x3F      ; Status Register
 +.equ SPH,     0x3E      ; Stack Pointer High
 +.equ SPL,     0x3D      ; Stack Pointer Low
 +
 +.equ DDRB,    0x04      ; Data Direction Port B
 +.equ PINB,    0x03      ; Input Pins Port B (Toggle Shortcut)
 +.equ LED_PIN, 5         ; Built-in LED (Digital 13 / PB5)
 +
 +.equ RAMEND,  0x08FF
 +; --- Timer1 Register Mapping ---
 +.equ TCCR1A,  0x80      ; Timer1 Control A
 +.equ TCCR1B,  0x81      ; Timer1 Control B
 +.equ OCR1AH,  0x89      ; Output Compare High
 +.equ OCR1AL,  0x88      ; Output Compare Low
 +.equ TIMSK1,  0x6F      ; Timer1 Interrupt Mask
 +.equ TOP_VAL, 0x3D08    ; It is for 1s, adjust for 2s
 +
 +.equ WGM12, 3           ; WGM12 is on bit 3 of the TCCR1B
 +.equ CS12,  2            ; CS12 is on bit 2 of the TCCR1B
 +.equ CS10,  0            ; CS10 is on bit 0 of the TCCR1B
 +
 +.section .text
 +.org 0x0000
 +    rjmp RESET          
 +.org 0x002C             ; Assembler treats .org as bytes, use 0x002C
 +    rjmp TIMER_ISR
 +.org 0x0034             ; Jump past vectors to start logic
 +
 +
 +RESET:
 +
 +; --- Idle Main Loop ---
 +LOOP:
 +    rjmp LOOP
 +</code>
 +
 +** Step 2 **\\
 +Initialise stack (obligatory, we use ISR function calls) and configure BP5 (GPIO 13) as output:
 +<code asm>
 +...
 +    ; Prepare stack
 +   ldi r16, hi8(RAMEND)
 +   out SPH, r16
 +   ldi r16, lo8(RAMEND)
 +   out SPL, r16
 +
 +    ; Configure PB5 (built-in LED, GPIO 13) as Output
 +    sbi DDRB, LED_PIN
 +...
 +</code>
 +Note the different method for setting GPIO 13 as an output compared to the [[avr1|]] scenario.\\
 +
 +** Step 3 **\\
 +Configure timer and enable interrupts:
 +<code asm>
 +...
 +    ; Set Timer1 in CTC Mode
 +    ; Load the compare value for 1 second
 +    ldi r16, hi8(TOP_VAL)
 +    sts OCR1AH, r16
 +    ldi r16, lo8(TOP_VAL)
 +    sts OCR1AL, r16
 +
 +    ; TCCR1A: Default (0x00)
 +    ldi r16, 0x00
 +    sts TCCR1A, r16
 +
 +    ; TCCR1B: 
 +    ; Bit 3 (WGM12) = 1 (CTC Mode)
 +    ; Bit 2 (CS12)  = 1 (Prescaler 1024)
 +    ; Bit 0 (CS10)  = 1 (Prescaler 1024)
 +    ldi r16, (1 << WGM12) | (1 << CS12) | (1 << CS10)
 +    sts TCCR1B, r16
 +
 +    ; 4. Enable Compare Match A Interrupt
 +    ldi r16, (1 << 1)   ; OCIE1A bit
 +    sts TIMSK1, r16
 +
 +    ; 5. Global Interrupt Enable
 +    sei
 +...
 +
 +</code>
 +
 +** Step 4 **\\
 +Your loop function remains idle, but you need an ISR implementation, e.g. like this:
 +<code asm>
 +TIMER_ISR:
 +    ; Toggle LED using the PINB write trick.
 +    ; Since 'sbi' does not modify SREG flags, we do not need 
 +    ; to save/restore context (push/pop r16, etc).
 +    sbi PINB, LED_PIN
 +    reti
 +</code>
 +
 +** Result validation **\\
 +The LED should be flashing on an implemented time basis. Note that some irregularity may is observed due to the nature of video streaming over the network. It is natural and OK. If you want to measure more precise timing, increase the period, e.g. to 3s.
 +
 +** FAQ **\\
 +When using the printed version of this manual, please refer to the latest online version for the most up-to-date list of FAQs.\\
 +
 +**It does not flash**: Did you compile and upload to the device? Those are separate steps: it is not enough to just compile, but you also need to "flash" the MCU. Also, check your video stream if it "ticks" - the time embedded into the video stream should change. Your code may be working OK, but the video stream can be frozen, so you cannot see it working properly!
 +
 +//
 +
  
CC Attribution-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0