ATtiny13 – Hello World! :)

Finally managed to get into AVR programming. Using OSX, which I found as the worst platform for doing any kind of embed programming :( Sad. Anyway, there’s my first ATtiny schematics and code. I’m using AVR Dragon to flash code into the MCU.

tiny13-spi

The circuit is quite simple. I just confirm SPI flashing works and I’m able to turn the LED on. So here’s some code (using avr-gcc to compile and avrdure to upload). Create new project using avr-project and add this to main.c file:

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
    const int msDelay = 50;

    // PortB pin4 to output (set bit to 1 using SHL)
    DDRB = 1<<DDB4;

    // PortB to low
    PORTB = 0;

    while (1) {
        // XOR on pin 4
        PORTB ^= 1<<PB4;
        _delay_ms(msDelay);
    }

    return 0;
}

Now we can compile the firmware and upload to our MCU.

$ make
avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=attiny13 -c main.c -o main.o
avr-gcc -Wall -Os -DF_CPU=8000000 -mmcu=attiny13 -o main.elf main.o
rm -f main.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-size --format=avr --mcu=attiny13 main.elf
AVR Memory Usage
----------------
Device: attiny13

Program:      72 bytes (7.0% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)

No errors. Great. Connect AVR Dragon and upload our new firmware:

$ make flash
avrdude -c dragon_isp -P usb -p attiny13 -U flash:w:main.hex:i

avrdude: AVR device initialized and ready to accept instructions

Reading | ################################################## | 100% 0.15s

avrdude: Device signature = 0x1e9007
avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed
         To disable this feature, specify the -D option.
avrdude: erasing chip
avrdude: reading input file "main.hex"
avrdude: writing flash (110 bytes):

Writing | ################################################## | 100% 0.46s

avrdude: 110 bytes of flash written
avrdude: verifying flash memory against main.hex:
avrdude: load data flash data from input file main.hex:
avrdude: input file main.hex contains 110 bytes
avrdude: reading on-chip flash data:

Reading | ################################################## | 100% 0.47s

avrdude: verifying ...
avrdude: 110 bytes of flash verified

avrdude: safemode: Fuses OK (H:FF, E:FF, L:6A)

avrdude done.  Thank you.

tiny13-spi-foto

For those, interested in .hex file – this is how it looks like:

$ cat main.hex
:1000000009C00EC00DC00CC00BC00AC009C008C09A
:1000100007C006C011241FBECFE9CDBF02D012C059
:10002000EFCF80E187BB18BA90E188B3892788BBFE
:100030002FE738E381E0215030408040E1F700C0F5
:080040000000F3CFF894FFCF9C
:00000001FF

and I made some commented assembler output (base is taken from avr-objdump -S main.elf).

 cat main.S

main.elf:     file format elf32-avr


Disassembly of section .text:

00000000 <__vectors>:
   0:	09 c0       	rjmp	.+18     	; 0x14 <__ctors_end>
   2:	0e c0       	rjmp	.+28     	; 0x20 <__bad_interrupt>
   4:	0d c0       	rjmp	.+26     	; 0x20 <__bad_interrupt>
   6:	0c c0       	rjmp	.+24     	; 0x20 <__bad_interrupt>
   8:	0b c0       	rjmp	.+22     	; 0x20 <__bad_interrupt>
   a:	0a c0       	rjmp	.+20     	; 0x20 <__bad_interrupt>
   c:	09 c0       	rjmp	.+18     	; 0x20 <__bad_interrupt>
   e:	08 c0       	rjmp	.+16     	; 0x20 <__bad_interrupt>
  10:	07 c0       	rjmp	.+14     	; 0x20 <__bad_interrupt>
  12:	06 c0       	rjmp	.+12     	; 0x20 <__bad_interrupt>

00000014 <__ctors_end>:             ; set stack to SRAM
  14:	11 24       	eor	r1, r1      ; set 0 to r1
  16:	1f be       	out	0x3f, r1	  ; 0 -> SPH
  18:	cf e9       	ldi	r28, 0x9F	  ; RAMEND
  1a:	cd bf       	out	0x3d, r28	  ; r28 -> SPL
  1c:	02 d0       	rcall	.+4      	; call main loop at 0x22
  1e:	12 c0       	rjmp	.+36     	; then call exit at 0x44

00000020 <__bad_interrupt>:
  20:	ef cf       	rjmp	.-34     	; 0x0 <__vectors>

00000022 <main>:
  22:	80 e1       	ldi	r24, 0x10	  ; 1<<DDB4 (0x10) -> r24
  24:	87 bb       	out	0x17, r24	  ; set r24 -> DDRB
  26:	18 ba       	out	0x18, r1	  ; set r1 (0) -> PORTB
  28:	90 e1       	ldi	r25, 0x10	  ; 1<<DDB4
  2a:	88 b3       	in	r24, 0x18	  ; read PORTB -> r24 to XOR
  2c:	89 27       	eor	r24, r25    ; XOR pin 4
  2e:	88 bb       	out	0x18, r24	  ; set r24 -> PORTB
  30:	2f e7       	ldi	r18, 0x7F	  ; 0x01387f = wait 79999 ticks (50ms at 4MHz)
  32:	38 e3       	ldi	r19, 0x38	  ;
  34:	81 e0       	ldi	r24, 0x01	  ;
  36:	21 50       	subi	r18, 0x01	; decrease r18 by 1
  38:	30 40       	sbci	r19, 0x00	; and decrease other by carry bit
  3a:	80 40       	sbci	r24, 0x00	;
  3c:	e1 f7       	brne	.-8      	; repeat until zero set - jump to 0x36
  3e:	00 c0       	rjmp	.+0      	; relative jump to 0x40
  40:	00 00       	nop             ; do nothing
  42:	f3 cf       	rjmp	.-26     	; jump back to 0x2a (loop)

00000044 <_exit>:
  44:	f8 94       	cli

00000046 <__stop_program>:
  46:	ff cf       	rjmp	.-2      	; 0x46 <__stop_program>

 

Posted in MCU

Leave a Reply

Your email address will not be published. Required fields are marked *

3 + 1 =