This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| en:multiasm:exercisesbook:avr:sut:scenarios:avr2 [2026/05/03 18:54] – pczekalski | en:multiasm:exercisesbook:avr:sut:scenarios:avr2 [2026/05/03 19:35] (current) – pczekalski | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== AVR2: Create | + | ====== AVR2: Create |
| - | In this scenario, you will implement a pattern using multiple LEDS. There are 4 LEDs connected to GPIOs 13, 12, 11, and 10 (D1 on top is GPIO 13; D4 at the bottom is GPIO 10). In this scenario, you will use blocking nested loops and manual calculation of the ticks needed to run them, to obtain precise '' | + | In this scenario, you will implement a pattern using multiple LEDS. There are 4 LEDs connected to GPIOs 13, 12, 11, and 10 (D1 on top is GPIO 13; D4 at the bottom is GPIO 10). In this scenario, you will use blocking nested loops and manual calculation of the ticks needed to run them, to obtain precise '' |
| ** Prerequisites **\\ | ** Prerequisites **\\ | ||
| Line 19: | Line 19: | ||
| < | < | ||
| </ | </ | ||
| + | |||
| ** Result **\\ | ** Result **\\ | ||
| Observe the LED sequence via the video stream. | Observe the LED sequence via the video stream. | ||
| - | |||
| - | ** Start **\\ | ||
| - | Use AVR GCC syntax (as in the instruction): | ||
| - | There are multiple approaches possible here. One interesting approach is to create binary masks representing the state of the LEDs at subsequent time-discrete steps, store them in memory, and then iterate over this array to control the GPIO. Another option is to explicitly set and reset bits using LED IDs and bitshift operations. This approach does not require memory. | ||
| <note important> | <note important> | ||
| + | |||
| + | ** Start **\\ | ||
| + | Use AVR GCC syntax (as in the instruction): | ||
| + | There are multiple approaches to solving the problem. One interesting approach is to create binary masks representing the state of the LEDs at subsequent time-discrete steps, store them in memory, and then iterate over this array to control the GPIO. Another option is to explicitly set and reset bits using LED IDs and bit-shift operations or constant-defined patterns (as we present); this approach requires no RAM.\\ | ||
| + | Also note you need to define a stack to use '' | ||
| ** Step 1 **\\ | ** Step 1 **\\ | ||
| - | Compose | + | Compose application |
| <code asm> | <code asm> | ||
| + | ; --- IO Register Addresses --- | ||
| + | .equ SPH, 0x3E | ||
| + | .equ SPL, 0x3D | ||
| + | .equ DDRB, | ||
| + | .equ PORTB, | ||
| + | ; --- Single .equ for RAM End --- | ||
| + | .equ RAM_END, | ||
| + | |||
| + | ; --- Bitmask & Pattern Definitions --- | ||
| + | .equ LED_MASK, | ||
| + | |||
| + | ; Active-Low Logic (0=ON, 1=OFF) | ||
| + | ; Pattern 1 (Image Left): D2 & D4 ON -> 11101011 | ||
| + | .equ PATTERN_A, | ||
| + | ; Pattern 2 (Image Right): D1 & D3 ON -> 11010111 | ||
| + | .equ PATTERN_B, | ||
| + | |||
| + | .org 0x0000 | ||
| + | rjmp reset | ||
| + | |||
| + | reset: | ||
| + | ; Initialise Stack Pointer using hi8 and lo8 functions | ||
| + | ldi r16, lo8(RAM_END) | ||
| + | out SPL, r16 | ||
| + | ldi r16, hi8(RAM_END) | ||
| + | out SPH, r16 | ||
| </ | </ | ||
| ** Step 2 **\\ | ** Step 2 **\\ | ||
| + | Configure GPIO13 <-> GPIO10 as outputs. Note, we do it in a bunch, not individually, | ||
| + | <code asm> | ||
| + | ; Configure GPIO: Set PB2-PB5 as outputs | ||
| + | ldi r16, LED_MASK | ||
| + | out DDRB, r16 | ||
| + | </ | ||
| ** Step 3 **\\ | ** Step 3 **\\ | ||
| + | Implement pattern logic. Here are just two steps, repeatedly executed in a loop. Note, code won't compile, because you will need to implement a '' | ||
| + | <code asm> | ||
| + | main_loop: | ||
| + | ; Display Pattern A (D2, D4 ON) | ||
| + | ldi r16, PATTERN_A | ||
| + | out PORTB, r16 | ||
| + | rcall delay_2s | ||
| + | ; Display Pattern B (D1, D3 ON) | ||
| + | ldi r16, PATTERN_B | ||
| + | out PORTB, r16 | ||
| + | rcall delay_2s | ||
| + | |||
| + | rjmp main_loop | ||
| + | </ | ||
| + | |||
| + | **Step 4 **\\ | ||
| + | Implement a delay function as shown in other examples (here, it is named '' | ||
| + | You may want to use '' | ||
| + | <note tip> A good approach is to run the outer loop 208 times and two inner, nested loops 255 times each. ; | ||
| Line 45: | Line 97: | ||
| ** FAQ **\\ | ** FAQ **\\ | ||
| - | When using the printed version of this manual, please refer to the latest online version | + | When using the printed version of this manual, please refer to the latest online version |
| **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 " | **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 " | ||
| - | // | ||
| + | **I need a longer delay**: To obtain a delay function with a period of about 2.5s, you need to introduce a fourth loop (an outer loop) in the delay; 3 will not provide you enough ticks. Eventually, you can switch to 16-bit counters. | ||
| + | // | ||