Table of Contents

Microcontroller

Using Kanda STK200-X to play around with the Atmel AVR microcontroller. Currently using ATMega16A, which has an internal 1MHz crystal oscillator, but can be outfitted with external clocks of up to 16 MHz. The default supplied with STK200-X is a 8 MHz clock.

The best match for this in Microchip Studio is ATmega16L-8PU for 8 MHz clock in PDIP40 footprint, or ATmega16-16PU for 16 MHz clock.

Lots of new terminology to pick up, including:

This subreddit is a pretty good consolidated resource!

https://www.reddit.com/r/AskElectronics/wiki/soldering/

For soldering, previously was using 225 degC for heating, but this means the board takes a long time to heat up. Tried using 350 degC, and worked like a charm. Notably:

Also remember that lead-free does not mean the smoke dissipated is healthy...

FPGA:

Theory:

Simulators:

Toolchains:

  1. atprogram: Comes with Microchip Studio, best used for Windows
  2. avra: Stand-in replacement for Linux/macOS
  3. simavr: Simulator

.\avrisp-u.exe "C:\...\LED Flash.asmproj"

AVRdude

This looks like a fairly nice resource: https://github.com/kitspace/awesome-electronics


ATMega16A

Note that my background is some basic electronics (digital/analog), a bit of C (memory allocation).

Datasheet

The datasheet shall become my bible. A useful guide is also the Kanda training kit.

Memories are where program and data is stored, in particular there are three such locations:

  1. Code/Flash memory: Stores the program with each instruction stored in 16-bit addresses.
  2. EEPROM memory: Stores long-term data with 8-bit addresses.
  3. SRAM/RAM memory: Stores information during program execution and to access peripherals, with 8-bit addresses.

Note that this chip uses the Harvard architecture, so the 16-bit instruction bus is separate from the 8-bit data bus (the latter implies an 8-bit microcontroller).

The overview page on the datasheet gives a nice summary:

The rest of the details is kinda lost on me.

Flash memory

The main control flow is determined by the Program Control (PC), which holds the address of program memory being executed. Typical flow:

  1. The PC starts from the Reset Address, usually 0x0000 in the AVR family.
  2. For regular program instructions, instruction address is incremented through the program memory.
  3. If Jump (JMP) instruction encountered, the program counter is reloaded with the new address.
  4. If Call instruction encountered, code execution will jump to new address but will return to the previous address later. The previous address is stored on the stack (this is a distinct memory section in SRAM and must be setup/initialized before any CALL instructions)
  5. The PC can also be reloaded with Interrupt Vector addresses, when a hardware interrupt is triggered.
SRAM memory

SRAM in AVR is contiguous, with the following address space - 32 bytes general purpose working registers, 64 bytes I/O registers, then 1024 bytes internal data SRAM. Illustrated below:

Address space (value) Register, if any Section
0x45F (1119) Internal data
...
...
...
0x0061 (97)
0x0060 (96)
0x005F (95) 0x3F IO registers
... ...
0x0021 (33) 0x01
0x0020 (32) 0x00
0x001F (31) R31 General-purpose registers
... ...
0x0001 (1) R1
0x0000 (0) R0

Instruction sets?

Basic Boolean logic applies, using AND, OR, COM (complement/NOT), EOR (exclusive OR). For registers R16 to R31, there exists an alternative ANDI and ORI, not sure what this means.

Using Microchip Studio 7, then passing $(ProjectDir)$(ProjectFileName) as arguments to AVRISP-U software will automatically load it into the ISP.

Assembly code used is here:

; Comments are prefixed with ';', '//', or wrapped '/*...*/'
; Spaces between variables are ignored
 
; Include directive similar to C
; This library for ATMega16
.include "m16def.inc"
 
  ; Label registers for easy reference using define
  .def TEMP=r16    ; temporary (scratch) register
  .def ON=r23      ; store value for LED on
  .def OFF=r24     ; store value for LED off
  .def coarse=r17  ; delay subroutine, has largest effect
  .def medium=r18  ; delay subroutine, has medium effect
  .def fine=r19    ; delay subroutine, has smallesteffect
 
  .cseg       ; indicates this is code and to be stored in Flash
  .org 0      ; switch to address 0x00 (reset address)...
  rjmp INIT   ; ...and add jump instruction to label INIT
  .org 0x60   ; switch to address 0x60  (padding for interrupt vectors)...
INIT:         ; ...and add location of label INIT
 
  ; Up to this point is typically the same assembly boilerplate
  ; Now we define the stack space by populating SPH (Stack Pointer High byte)
  ; and SPL with the high and low address boundaries respectively.
  ; Since we cannot write directly to Special Function Registers (SFR)
  ; nor to bottom 16 registers (R0 to R15), we first load the required
  ; value into a register between R16 and R31 inclusive.
  ;
  ; The end of SRAM is defined in the header file as RAMEND,
  ; which corresponds to 0x045f for ATmega16. This is a 16-bit
  ; address, so we write both the high and low bytes, where
  ; LOW(0x045f) == 0x5f and HIGH(0x045f) == 0x04
 
  ; Set Stack Pointer to top of SRAM
  ldi TEMP, LOW(RAMEND)  ; (load intermediate value)
  out SPL, TEMP          ; (write to SFR)
  ldi TEMP, HIGH(RAMEND)
  out SPH, TEMP
 
  ; Set all pins in Port B as output (instead of input)
  ldi TEMP, 0xff
  out DDRB, TEMP  ; data direction register for Port B
 
  ; Load 1s into all pins in Port B
  ; Dependent on electronic wiring - here it switches LEDs off
  out PORTB, TEMP
 
  ; Store off and on values for LED
  ldi OFF, 0xff
  ldi ON, 0x00
 
MAIN:
  rcall DELAY     ; do (relative) call to subroutine
  out PORTB, ON   ; switch LED ON
  rcall DELAY
  out PORTB, OFF  ; switch LED OFF
  rjmp MAIN       ; repeat main loop
 
DELAY:
  ldi coarse, 0x07
delay1:
  ldi medium, 0xff
delay2:
  ldi fine, 0xff
delay3:
  dec fine
  brne delay3  ; skips only if previous decrement goes to zero
  dec medium
  brne delay2
  dec coarse
  brne delay1
  ret

Note a couple of additional comments:

The subsequent tutorials seem to just introduce other instructions. Worth looking at the decompiled program and the nature of instruction sets instead.

Program counter

On modern PCs, the program counter is more associated with the instruction itself (due to different branches, etc) than in the chip. See this answer.

The corresponding Flash program written to the chip corresponds to:

prog 0x0000  5f c0 ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0010  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0020  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0030  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0040  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0050  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0060  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0070  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0080  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0090  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x00A0  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x00B0  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x00C0  0f e5 0d bf 04 e0 0e bf 0f ef 07 bb 08 bb 8f ef  
prog 0x00D0  70 e0 04 d0 78 bb 02 d0 88 bb fb cf 17 e0 2f ef  
prog 0x00E0  3f ef 3a 95 f1 f7 2a 95 d9 f7 1a 95 c1 f7 08 95  
prog 0x00F0  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0100  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0110  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0120  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0130  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  
prog 0x0140  ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
...

while that of the SRAM is:

data 0x0000  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
data 0x0010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
data 0x0020  00 f8 fe ff 00 00 00 00 00 00 00 20 00 00 00 00  
data 0x0030  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
data 0x0040  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
data 0x0050  00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00  
data 0x0060  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
data 0x0070  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
data 0x0080  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  
... 
data 0x045F  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00