- 3D-Druck Einstieg und Tipps         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 17

Thema: Atmega32 mit dem AVR-GCC in Assembler programmieren

  1. #1
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449

    Atmega32 mit dem AVR-GCC in Assembler programmieren

    Anzeige

    Praxistest und DIY Projekte
    Hallo zusammen,

    ich möchte jetzt, nach dem ich immer nur C programmiert habe, mich auch einmal mit Assembler auseinandersetzen. Und dafür den AVR-GCC, der ja schon installiert ist, verwenden.

    Code hab ich folgenden:
    main.S
    Code:
    #include <avr/io.h>                                                        
    
    
    .text                                ; was nun folgt, gehört in den FLASH-Speicher
    
    
    .global main                        ; main ist auch in anderen Modulen bekannt
    
    
    main:                                ; zu 'main' wird nach Reset hingesprungen
        LDI R24, 255                    ; der wert "255" = FF ins allgemeine Register R24
        OUT DDRD, R24                    ; das kommt ins Controll-register f. PortD
                                        ; dadurch ist das Port auf OUTPUT gestellt
    Hauptschleife:                        ; ein Sprunglabel
        LDI R24, 255                        ; der wert "255" = FF ins allgemeine Register R24
        OUT PORTD, R24                    ; schreiben wir nach PortD
        rjmp Hauptschleife                ; immer wiederholen
    Zum übersetzen benutze ich folgendes:
    Code:
    avr-gcc -o main.elf -mmcu=atmega32 main.S
    avr-objcopy -O ihex -j .text -j .data main.elf  main.hex
    Läuft ohne Fehler durch. Das ganze wird dann mit AVRDUDE auf den Atmega32 geklatscht.

    Der Controller sitzt auf einem AVR-Funk-Evaluationsboard von Pollin. Dort sind LED1 und LED2 an PD5 und PD6 angeschlossen.

    Die sollten jetzt eigentlich auch Leuchten. Tun sie aber nicht!

    Weis jemand Rat?

    Viele Grüße und vielen Dank schon mal
    -schumi-

    PS: OS = Ubuntu 11.10; AVR-GCC-Version = gcc-Version 4.5.3 (GCC)

  2. #2
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    34
    Beiträge
    3.501
    Blog-Einträge
    9
    Was meinst du mit "allgemeines Register"? Ich denke mal du meinst den Akkumulator. Und wenn du diesen Akkumulator mit 255 lädst und das dann ins PortD Register schreibst steht der Wert immernoch im Akumulator d.h. du musst ihn nicht mehr mit 255 laden.
    Wie sind die LEDs an den Controller angeschlossen? Kann es vielleicht sein das die nur leuchten wenn der Pin 0 ist, also Active Low.

  3. #3
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Danke für deine Antwort, Kampi :-D

    Was meinst du mit "allgemeines Register"? Ich denke mal du meinst den Akkumulator.
    Ja, schätz ich mal. Hab mich noch kaum mit Assembler auf dem AVR beschäftigt, hab das Beispiel aus irgend einem Wiki gezogen...

    Und wenn du diesen Akkumulator mit 255 lädst und das dann ins PortD Register schreibst steht der Wert immernoch im Akumulator d.h. du musst ihn nicht mehr mit 255 laden.
    Das ist mir klar, aber ich hatte es zuvor mit 0 statt 255 probiert, und dann wieder in 255 geändert. Deswegen steht das da^^

    [EDIT] Oder meinst du, dass er in der Hauptschleife ständig reingeschrieben wird? Ja, die zwei Zeilen könnte man auch vor die Hauptschleife hinstellen, aber es bleibt sich ja Wurscht...

    Wie sind die LEDs an den Controller angeschlossen?
    High active, habe aber trotzdem schon beide Varianten 0/255 probiert.


    Heist das denn jetzt, das der Code eigentlich gehen müsste, aber irgendetwas mit dem GCC o.ä. nicht stimmt?

    Hardwareschaden schließe ich aus, in C kann ich die LEDs einwandfrei ansteuern

    Vielen Dank nochmal
    -schumi-

  4. #4
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    34
    Beiträge
    3.501
    Blog-Einträge
    9
    Probier mal das hier aus.
    Statt:

    LDI R24, 255

    Das hier:

    LDI R24, 0

    In einem Turtorial haben die den Pin als Eingang geschaltet.

  5. #5
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Hulft nicht, das hatte ich auch schon probiert...

    Aber Not macht erfinderisch:
    Man macht sich eine minimale C-Datei, die genau das macht was man will:
    #include <avr/io.h>
    void main(void) {
    DDRD = 255;
    PORTD = 255;
    }
    Macht damit nen ASM-Dump:
    GAS LISTING /tmp/cc7Qz3w0.s page 1




    1 .file "main.c"
    2 __SREG__ = 0x3f
    3 __SP_H__ = 0x3e
    4 __SP_L__ = 0x3d
    5 __CCP__ = 0x34
    6 __tmp_reg__ = 0
    7 __zero_reg__ = 1
    8 .text
    9 .global main
    10 .type main, @function
    11 main:
    12 0000 DF93 push r29
    13 0002 CF93 push r28
    14 0004 CDB7 in r28,__SP_L__
    15 0006 DEB7 in r29,__SP_H__
    16 /* prologue: function */
    17 /* frame size = 0 */
    18 /* stack size = 2 */
    19 .L__stack_usage = 2
    20 0008 81E3 ldi r24,lo8(49)
    21 000a 90E0 ldi r25,hi8(49)
    22 000c 2FEF ldi r18,lo8(-1)
    23 000e FC01 movw r30,r24
    24 0010 2083 st Z,r18
    25 0012 82E3 ldi r24,lo8(50)
    26 0014 90E0 ldi r25,hi8(50)
    27 0016 2FEF ldi r18,lo8(-1)
    28 0018 FC01 movw r30,r24
    29 001a 2083 st Z,r18
    30 /* epilogue start */
    31 001c CF91 pop r28
    32 001e DF91 pop r29
    33 0020 0895 ret
    34 .size main, .-main
    GAS LISTING /tmp/cc7Qz3w0.s page 2




    DEFINED SYMBOLS
    *ABS*:00000000 main.c
    /tmp/cc7Qz3w0.s:2 *ABS*:0000003f __SREG__
    /tmp/cc7Qz3w0.s:3 *ABS*:0000003e __SP_H__
    /tmp/cc7Qz3w0.s:4 *ABS*:0000003d __SP_L__
    /tmp/cc7Qz3w0.s:5 *ABS*:00000034 __CCP__
    /tmp/cc7Qz3w0.s:6 *ABS*:00000000 __tmp_reg__
    /tmp/cc7Qz3w0.s:7 *ABS*:00000001 __zero_reg__
    /tmp/cc7Qz3w0.s:11 .text:00000000 main


    NO UNDEFINED SYMBOLS
    Kopiert sich das relevante in die eigenen main.S und schmeißt alles was komisch aussieht raus:
    #include <avr/io.h>
    .text
    .global main
    main:
    push r29
    push r28


    ldi r24,lo8(49)
    ldi r25,hi8(49)
    ldi r18,lo8(-1)
    movw r30,r24
    st Z,r18
    ldi r24,lo8(50)
    ldi r25,hi8(50)
    ldi r18,lo8(-1)
    movw r30,r24
    st Z,r18
    pop r28
    pop r29
    ret
    Hauptschleife:
    rjmp Hauptschleife

    Und Thada, schon leuchten die 2 LEDs. Jetzt muss ich nur noch Stück für Stück den Code auseinander nehmen und gucken wie der GCC das anstellt, dass die 2 leuchten...

  6. #6
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Wie sieht denn das .lss File aus. Da sollte das vollständige ASM File einschließlich dem Startcode von GCC und der Sprungtabelle drin stehen. Daran solle man sehen ob GCC hier irgendwas unerwartetes gemacht hat.

  7. #7
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Das Problem liegt darin wie die SFR namen definiert sind. Für C sind da die Adressen für den Zugriff als Speicher (per LDS / STS und ähnlich) angegeben. Für die Benutzung in ASM mit den Befehlen IN und OUT muss man davon noch 32 abziehen. Eine Erklärung findet sich im File sfr_defs.h.

  8. #8
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Ich bin jetzt nicht sicher ob ich das richtige gemacht habe. Ist das das was du sehen möchtest?
    Code:
    simon@simon-TravelMate-5735Z:~/Arbeitsfläche/test$ avr-objdump -d main.elf
    
    
    main.elf:     file format elf32-avr
    
    
    
    
    Disassembly of section .text:
    
    
    00000000 <__vectors>:
       0:    0c 94 2a 00     jmp    0x54    ; 0x54 <__ctors_end>
       4:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
       8:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
       c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      10:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      14:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      18:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      1c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      20:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      24:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      28:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      2c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      30:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      34:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      38:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      3c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      40:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      44:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      48:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      4c:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
      50:    0c 94 34 00     jmp    0x68    ; 0x68 <__bad_interrupt>
    
    
    00000054 <__ctors_end>:
      54:    11 24           eor    r1, r1
      56:    1f be           out    0x3f, r1    ; 63
      58:    cf e5           ldi    r28, 0x5F    ; 95
      5a:    d8 e0           ldi    r29, 0x08    ; 8
      5c:    de bf           out    0x3e, r29    ; 62
      5e:    cd bf           out    0x3d, r28    ; 61
      60:    0e 94 36 00     call    0x6c    ; 0x6c <main>
      64:    0c 94 47 00     jmp    0x8e    ; 0x8e <_exit>
    
    
    00000068 <__bad_interrupt>:
      68:    0c 94 00 00     jmp    0    ; 0x0 <__vectors>
    
    
    0000006c <main>:
      6c:    df 93           push    r29
      6e:    cf 93           push    r28
      70:    cd b7           in    r28, 0x3d    ; 61
      72:    de b7           in    r29, 0x3e    ; 62
      74:    81 e3           ldi    r24, 0x31    ; 49
      76:    90 e0           ldi    r25, 0x00    ; 0
      78:    2f ef           ldi    r18, 0xFF    ; 255
      7a:    fc 01           movw    r30, r24
      7c:    20 83           st    Z, r18
      7e:    82 e3           ldi    r24, 0x32    ; 50
      80:    90 e0           ldi    r25, 0x00    ; 0
      82:    2f ef           ldi    r18, 0xFF    ; 255
      84:    fc 01           movw    r30, r24
      86:    20 83           st    Z, r18
      88:    cf 91           pop    r28
      8a:    df 91           pop    r29
      8c:    08 95           ret
    
    
    0000008e <_exit>:
      8e:    f8 94           cli
    
    
    00000090 <__stop_program>:
      90:    ff cf           rjmp    .-2          ; 0x90 <__stop_program>
    simon@simon-TravelMate-5735Z:~/Arbeitsfläche/test$

  9. #9
    Erfahrener Benutzer Roboter-Spezialist Avatar von -schumi-
    Registriert seit
    30.12.2009
    Ort
    Wasserburg am Inn / Bayern
    Alter
    30
    Beiträge
    449
    Das Problem liegt darin wie die SFR namen definiert sind. Für C sind da die Adressen für den Zugriff als Speicher (per LDS / STS und ähnlich) angegeben. Für die Benutzung in ASM mit den Befehlen IN und OUT muss man davon noch 32 abziehen. Eine Erklärung findet sich im File sfr_defs.h.
    Hat jetzt zwar ein bischen gebraucht, aber ich glaub ich habs gecheckt:

    Im Datenblatt steht:
    Code:
    $12 ($32) PORTD PORTD7 PORTD6 PORTD5 PORTD4 PORTD3 PORTD2 PORTD1 PORTD0 65
    $11 ($31) DDRD DDD7 DDD6 DDD5 DDD4 DDD3 DDD2 DDD1 DDD0 65
    Die $32 und $31 (jeweils zweite Zahl von Links) sind die Adresse, die der GCC benutzt (umgerechnet von Hex nach Dez sind das nämlich 50 und 49 - die sich auch im Quellcode wiederfinden)

    Wenn ich jetzt 50-32 = 18 Rechne, und in 18 und auch 17 (49 - 32) jeweils 255 mit OUT reinschreibe, leuchten die LEDs!

    Und Praktischerweise sind die 12 und 11 im Datenblatt (jeweils erste Zahl) von hex nach dez umgerechnet auch 18 und 17, ich brauch also auch nicht jedesmal mühsam -32 rechnen :-D


    Vielen vielen Dank Besserwessi und Kampi! :-D


    Viele herzliche Grüße
    -schumi-

    [EDIT]
    Hier noch der aktuelle Quellcode:
    Code:
    #include <avr/io.h>                                                    
    .text
    .global main
    main:
        
        LDI r24, 255
        OUT DDRD-32, r24
        LDI r24, 255
        OUT PORTD-32, r24
        
        Hauptschleife:
            rjmp Hauptschleife
    Geändert von -schumi- (02.09.2011 um 18:30 Uhr)

  10. #10
    Moderator Robotik Einstein Avatar von Kampi
    Registriert seit
    21.11.2009
    Ort
    Monheim, Nordrhein-Westfalen, Germany
    Alter
    34
    Beiträge
    3.501
    Blog-Einträge
    9
    Deine Erklärung check ich jetzt nicht ganz

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Frage zum Programmieren im Assembler
    Von Toni224 im Forum PIC Controller
    Antworten: 11
    Letzter Beitrag: 12.02.2010, 19:13
  2. IRQ Programmieren in Assembler
    Von cmc im Forum Assembler-Programmierung
    Antworten: 6
    Letzter Beitrag: 08.03.2007, 12:12
  3. ASURO in Assembler programmieren!
    Von Ronny10 im Forum Asuro
    Antworten: 0
    Letzter Beitrag: 06.01.2007, 14:30
  4. Wie in Assembler programmieren?
    Von Jens im Forum Controller- und Roboterboards von Conrad.de
    Antworten: 5
    Letzter Beitrag: 22.04.2006, 17:34
  5. Voyage 200 in Assembler programmieren?
    Von Murus im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 11
    Letzter Beitrag: 04.10.2005, 20:10

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen