1. Lab preparation
Reminder to watch the videos linked in day06 - §1. Preparation
Become familiar with the content available at RJHcoding.com - AVR Assembly Tutorials.
Notice that we’ve effectively looked at Example Programs #1 and #3 already, though those are intended for the ATmega328P
MCU.
Part of the Lab 1 activity has to do with how you create “functions” in assembly, which are called subroutines.
2. Blink differences
Compare the two different toggle-a-pin implementations:
Some major differences to note are
-
16-bit versus 8-bit down counter for the inner loop.
-
Exclusive-OR two registers, then store to
PORTB
with a single delay block versus
Set and clear register bit with two functionally identical delay blocks. -
RJH uses assembly for the
ATmega328P
while we are using theATtiny85
.
→ Are there any instructions that the 'mega
can execute that are not available in the 'tiny
?
Figure this out by studying the AVR-instruction-set-manual_2021.pdf.
Section 7.1 Core Descriptions on page 149 and the following Device Tables provide the information about the specific AVR instruction set variants each of these MCUs use.
3. Another branch
sbi
/cbi
“slow-blink” day06 code to use a different branch instruction (BR__
) instead of BREQ
.
To better understand what branch instructions do and when they jump versus when they fall through, please read
SR bits
C
,
Z
, and
S
, are especially useful for decision making.
Detecting any result other than zero requires some more work with the CPU.
Changing from the BREQ
to a different branch condition requires first setting the appropriate status register bits, then branching on its value.
Instructions for setting SR bits with the result a comparison operation:
-
CP
-
CPI
An idea to consider:
-
Setting a register to (256 - x) and then incrementing the register via
inc
will overflow in x steps.
4. Subroutines
delay
subroutine twice.
From the excellent site RJHcoding.com - AVR Assembly Tutorials, please read:
Instead of using hard-coded constants, use the .equ
assembler directive to define symbols for the inner and outer loop iteration counts:
.equ INNER_COUNT = 0xFF ; 8b unsigned
.equ OUTER_COUNT = 0xFF ; 8b unsigned
...
Main:
; set pin high
sbi ...
rcall Delay
;set pin low
cbi ...
rcall Delay
rjmp Main
Delay:
; <delay code here>
ret ;return from subroutine
5. blinkfast

Before you think that the code that pulls off the blistering speed of Figure 1 is perfect, understand that it has one flaw — a glitch every once in a while. The exact periodic interval remains a trade secret since it would give away the solution.
5.1. Special oscilloscope triggering modes
Because the glitch happens less than 0.1% of the time, it can be difficult to actually see or capture.
Enter the many other triggering modes of the Scope in Waveforms (and other nice oscilloscopes).
Consider Figure 2 and see that the low time of PB3
is indeed low for 4 μs, double of the normal 2 μs for a 50% duty-cycle 250 kHz waveform.
The trigger settings are all of the dropdown boxes from Mode: to HoldOff:. Clicking tiny green up-arrow on the right side of this area will collapse the advanced settings, as per the mouse-over text hint.
This particular trigger condition was set up to look for a low (negative) pulse whose duration was more than 3 μs. Determining what is "low" or "high" is set by the level of 2 V with a hysteresis of ±100 mV.
