This shows you the differences between two versions of the page.
| en:multiasm:exercisesbook:avr:sut:scenarios:avr4 [2026/05/02 10:36] – created pczekalski | en:multiasm:exercisesbook:avr:sut:scenarios:avr4 [2026/05/04 12:10] (current) – pczekalski | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| ====== AVR4: Blinking LED, Timer-based ====== | ====== AVR4: Blinking LED, Timer-based ====== | ||
| + | |||
| + | In this scenario, you will implement a classical "Hello World" application, | ||
| + | |||
| + | ** 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): | ||
| + | |||
| + | ** 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, | ||
| + | .equ SPL, | ||
| + | |||
| + | .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, | ||
| + | ; --- Timer1 Register Mapping --- | ||
| + | .equ TCCR1A, | ||
| + | .equ TCCR1B, | ||
| + | .equ OCR1AH, | ||
| + | .equ OCR1AL, | ||
| + | .equ TIMSK1, | ||
| + | .equ TOP_VAL, 0x3D08 | ||
| + | |||
| + | .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 | ||
| + | rjmp TIMER_ISR | ||
| + | .org 0x0034 | ||
| + | |||
| + | |||
| + | RESET: | ||
| + | |||
| + | ; --- Idle Main Loop --- | ||
| + | LOOP: | ||
| + | rjmp LOOP | ||
| + | </ | ||
| + | |||
| + | ** Step 2 **\\ | ||
| + | Initialise stack (obligatory, | ||
| + | <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 | ||
| + | ... | ||
| + | </ | ||
| + | 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) | ||
| + | ; Bit 0 (CS10) | ||
| + | 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 | ||
| + | ... | ||
| + | |||
| + | </ | ||
| + | |||
| + | ** Step 4 **\\ | ||
| + | Your loop function remains idle, but you need an ISR implementation, | ||
| + | <code asm> | ||
| + | TIMER_ISR: | ||
| + | ; Toggle LED using the PINB write trick. | ||
| + | ; Since ' | ||
| + | ; to save/ | ||
| + | sbi PINB, LED_PIN | ||
| + | reti | ||
| + | </ | ||
| + | |||
| + | ** 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 " | ||
| + | |||
| + | // | ||
| + | |||
| + | |||