Atmel Mikrocontroller Kickstart

From C4 Wiki
Revision as of 22:28, 17 March 2005 by 212.202.55.254 (talk) (Linkliste)
Jump to: navigation, search

Hardware und Software

Hardware

  • In System Programmer (einfache Schaltung von [1] ):
Pin am ISP Pin am AVR Schutzwiderstand Pin am Parallelport
5 Reset (1) -- Init (16)
4 MOSI (17) 470 Ohm D0 (2)
3 MISO (18) 220 Ohm Busy (11)
2 SCK (19) 470 Ohm Strobe (1)
1 GND -- GND (18)
  • fuer die Schaltung um den Atmel drumrum brauchen wir:
    • einen Widerstand (zb. 10k oder auch 1k8) fuer den Reset Pull-Up
    • einen Kondensator (zb. 10uF) zum entprellen der Reset-Schaltung
    • pro anzuschliessende LED jeweils noch einen Widerstand (zb. 1k8)

Dann kanns eigentlich auch schon losgehen


Software

Notwending ist ein Assembler, der aus dem Ascii-Prosa-Text binaerimages zum direkten Hochladen auf den Controller macht, und ein Programm, welches diese Images dann hochschiebt.

Als Assembler eignet sich zb. "avra" und zum Hochladen verwendet man am einfachsten "uisp".

Schritte, um das in der Datei "test.asm" befindliche Programm zu kompilieren und hochzuladen:

$ avra test.asm
Pass 1...
Pass 2...
Segment usage:
   Code:        88 words (176 bytes)
   Data:         0 bytes
   EEPROM:       0 bytes
Assembly complete with no errors
$ uisp -dprog=dapa --erase
Atmel AVR ATmega8 is found.
Erasing device ...
Reinitializing device
Atmel AVR ATmega8 is found.
$ uisp -dprog=dapa --upload if=test.hex
Atmel AVR ATmega8 is found.
Uploading: flash

Dokumentation

Essentiell:

  • Atmega8 Datenblatt [2]
  • Atmel AVR Instruction Set [3]

Assembler

Um mit dem Assembler einigermassen angenehm arbeiten zu koennen, braucht man die Registerdefinitionen des Atmega8, meistens in der Datei m8def.inc [4] zu finden.

Hallo Welt, ich blinke(einfache Loesung)

.include "m8def.inc"
.ORG 0x0                ; reset vector
        rjmp reset


.ORG 0x13
reset:                       ; reset subprocedure
        ldi r16, low(RAMEND) ; init stack to point to RAMEND
        out SPL, r16
        ldi r16, high(RAMEND)
        out SPH, r16

        ldi r16, 0xff       ; configure PORTB as output
        out DDRB, r16

        rjmp loop           ; start main loop

wait:                       ; wait subprocedure
        ldi r16, 0xff       ; init outer loop counter
outer_loop:
        ldi r17, 0xff       ; init inner loop counter
delay_loop:
        dec r17             ; increment inner loop counter
        brne delay_loop

        dec r16             ; decrement outer loop counter
        brne outer_loop
        ret

loop:                       ; main loop
        ldi r16, 0x0        ; all bits on PORTB low (leds on)
        out PORTB, r16

        call wait           ; sleep

        ldi r16, 0xff       ; all bits on PORTB high (leds off)
        out PORTB, r16

        call wait           ; sleep

        rjmp loop

Hallo Welt, ich blinke(elegante Loesung)

.include "m8def.inc"


; working register definitions
.def    w1  =   r16     ; working registers
.def    w2  =   r17


.ORG 0x0                            ; reset vector
        rjmp reset

.ORG OC1Aaddr                       ; Timer1 CompareA interrupt handler
        rjmp OC1AHandler

.ORG 0x13                           ; program start

reset:                              ; reset subprocedure

        ldi w1, low(RAMEND)         ; init stack to point to RAMEND
        out SPL, r16
        ldi w1, high(RAMEND)
        out SPH, r16

        ori w1, (1<<PB0) | (1<<PB1) | (1<<PB2)   ; configure PB1-PB3 as output
        out DDRB, w1

        ldi w1, 0b101               ; initial led state
        out PORTB, w1

        ldi w1, 0                   ; reset Timer1
        out TCNT1H, w1
        out TCNT1L, w1

        ldi w1, high(15625)         ; set timer compare match interrupt to occur after 1s
        out OCR1AH, w1
        ldi w1, low(15625)
        out OCR1AL, w1

        ldi w1, (1<<CS10) | (1<<CS11) ; divide system clock by 64
        out TCCR1B, w1
        clr w1                      ; nothing else
        out TCCR1A, w1

        ldi w1, (1<<OCIE1A)         ; enable compare interrupt in global interrupt mask
        out TIMSK, w1

        sei                         ; enable global interrupts


        rjmp main

OC1AHandler:
        push w1                     ; save w1
        in w1, SREG                 ; save the status register
        push w1

        ldi w2, 0xff                ; toggle all leds
        in w1, PORTB
        eor w1, w2
        out PORTB, w1

        ldi w1, 0                   ; reset timer1
        out TCNT1H, w1
        out TCNT1L, w1

        pop w1                      ; restore the status register
        out SREG, w1
        pop w1                      ; restore w1
        reti


main:
        rjmp main


Linkliste