Last updated: 28/03/2016
Objectives 1.Read a microcontroller datasheet; 2.Program your board to do something, with as many different programming languages and programming environments as possible;avrdude -c usbtiny -p t44
//importing the necessary libraries (avr/io, avr/delay)
#include < avr/io.h>
#include < avr/delay.h>
int main (void)
{
//Set PORTB to all outputs
DDRB = 0xFF;
//create an infinite loop
while(1)
{
//turns B2 HIGH
PORTB |=(1<<2);
_delay_ms(20);
//turns B2 LOW
PORTB &= ~(1 << 2);
_delay_ms(20);
};
}
The second sketch that I made included both an input and an output setup [2]. The main structural difference with the previous sketch is that, if before I did set up all the PORTB as outputs, this time I only set specific pins. Nothing much changed.
//importing the necessary libraries (avr/io, avr/delay)
#include
#include
int main(void)
{
//Button pin A7 as input
DDRA &= (1 << PA7);
PORTA |= (1 << PA7);
//LED pin B2 as output
DDRB |= (1 << PB2);
PORTB |= (1 << PB2);
//create an infinite loop
while (1)
{
//if the button is not pressed, LED is low
if (PINA & (1 << PA7))
{
PORTB &= ~(1 << PB2);
}
//if the button is pressed, LED is high
else
{
PORTB |= (1 << PB2);
}
}
}
The result is shown in the picture below.
-c usbtiny -p m328p -v -v -v -U flash:w:$(TargetDir)$(TargetName).hex:i
6.Build
8.Tools --> programmer
The sketch got successfully uploaded!
; Simple Blink in ASM
; Editing the work of Fiore Basile - FabAcademy 2014
; Public Domain
2.section with hardware information
; the file tn44def.inc needs to be included within the same project folder
; I have tried to make sense of that file, but I honestly can not understand what goes on there
.include "tn44def.inc"
3.ports and pins definition with symbolic names
; ports are gates from the internal CPU to the external hardware/software
; the amount of ports depends on the type of microcontroller
; ports have a fixed address to establish communication with the CPU
.equ led_pin = PB2; led pin is PB2
.equ led_port = PORTB; comm port
.equ led_dir = DDRB; comm direction
.equ led_pins = PINB; comm pins
4.constants that can be configured
; defining the variable delay
.equ delay_time = 20;
5.registers definition
; registers are storages with 8-bits capacity. In AVR registers go from R0 to R31
; registers can be renamed, which is what happens in the next 6 lines
.def bitcnt = R16; bit counter
.def temp = R17; temporary storage
.def temp1 = R18; temporary storage
.def counter1 = R20;
.def counter2 = R22;
.def counter3 = R21;
6.interrupt service routines
; CSEG and ORG are statements that I did not fully understand.
; However, I figured that the following three lines reset the interrupts handlers
.cseg
.org 0
rjmp reset
7.reset
reset:
;
; set fuse low byte to 0x7E for 20 MHz resonator
; set clock divider to /1
; CLKPR is the clock prescale register, as described on the datasheet at page 31.
ldi temp, (1 << CLKPCE)
ldi temp1, (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0)
; store register I/O location
out CLKPR, temp
out CLKPR, temp1
8.memory definitions
; set stack pointer to top of RAM
;
ldi temp, high(RAMEND)
out SPH, temp
ldi temp, low(RAMEND)
; store register I/O location
out SPL, temp
9.main program init
; clear Bit in I/O Register
sbi led_port, led_pin
sbi led_dir, led_pin
10.program loop
loop:
; the SBI (Set Bit in I/O) instruction can be used to toggle one single bit in a port
sbi led_pins, led_pin ; toggle led pin
rcall delay
; the CBI (Clear Bit in I/O) instruction can be used to toggle one single bit in a port
cbi led_pins, led_pin
rcall delay
rjmp loop
; loads the value in delay_time on register 21
delay: ldi counter3, delay_time
;
delay1: rcall counta
dec counter3
; BRNE is branch if not equal
brne delay1
; RET is retourn from subroutine
ret
; loads the value 0 on register 20
counta: ldi counter1, 0
; the fact that the function calls itself does not make sense to me, just like it happens later with pauseb
pausea: rcall countb
dec counter1
brne pausea
ret
; loads the value 0 on register 22
countb: ldi counter2, 0
pauseb: dec counter2
brne pauseb
ret
When I had a basic understanding of what the code was doing, I proceeded with uploading it to the board. I found this tutorial where an Arduino board is used as programmer. Later I also run into Scott's repository that better helped me. The steps that I followed are:
1.Create a folder where to put the assembler file, together with the set of definitions for the ATtiny44;
2.Install the assembler AVRA
sudo apt-get install avra
3.Open the terminal and go to the directory of the .s file;
4.Simply launch the assembler
avra NAMEFILE.s
5.With the compiler AVRDUDE do the fuses and flash
sudo avrdude -p t44 -P usb -c usbtiny -U lfuse:w:0x5E:m
sudo avrdude -p t44 -P usb -c usbtiny -U flash:w:led.s.hex
Before I got point 5 to work, I failed in making the flashes a couple of times, as shown in the picture below. Appearently it was not necessary to write the full name of the COM where the board was listed.
After removing that part, the sequence of action was successful and the sketch got loaded.