Results 1 to 9 of 9
  1. #1

    Title
    Principal
    Join Date
    Dec 2008
    Posts
    39
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts

    Probleme mit SRAM

    hallo,
    glaub ich pack die welt nicht mehr. vielleicht kann mir wer bitte folgende tatsache erklären. spiel gerade ein bisschen herum mit dem microcontroller und wollte eigentlich nur folgendes ausprobieren: Einen wert in den sram schreiben (vorinitialisieren) diese wert auslesen, und auf die digital anzeige ausgeben. so ich hab geschrieben:

    (jetzt hab ich teilweise sogar schon die bsp aus dem lecture script genommen und das funktioniert auch nicht !!!)

    .NOLIST
    .INCLUDE "m16def.inc"
    .LIST

    ; zum vorinitialisieren des sram
    .section .data
    .org 0x0010 ; d.h an der adressse 0x0070 sollte eigentlich 0x01 drinnen stehen richtig?
    .byte 0x01

    .section .text

    .org 0x0000
    rjmp main

    main:
    ldi R16, 0x00
    out PORTC, R16
    ldi R16, 0xff
    out DDRC, R16

    lds R16, 0x0070
    out PORTC, R16

    end:
    rjmp end


    es lässt sich alles wunderbar komplieren und rüber spielen, nur angezeigt wird was falsches. erwartet wäre ja das nur ein led leuchtet, aber nein, da leuchten gleih 4 warum?

  2. #2

    Title
    Veteran
    Join Date
    Mar 2009
    Posts
    2
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts
    Hallo!
    Willkommen im Club, denn ich habe genau das gleiche Problem und auch noch keine Lösung. Ich will trotzdem schon schreiben, was ich bezüglich Speicherarchitektur und Addressierung herausgefunden habe:

    ATMega16 Manual:
    * Es gibt drei verschiedene Speicher: Flash, EEPROM, Data Memory (SRAM)
    * ihex-Dateien sind Dateien für den Flash-Speicher. Sie werden vom AT16Prog in diesen geladen.

    * Unsere Programme werden in den Flash-Speicher geladen.

    Es gibt zwei unterschiedliche Klassen von Befehlen um auf Speicher zuzugreifen:

    1) Um auf den Flash-Speicher zugreifen zu können, muss LPM/SPM verwendet werden. Diese Instructions addressieren den Flash bytegenau und liefern ein Byte zurück. Achtung!: lpm arbeitet nur mit dem Z-Register.

    2) Um auf den SRAM-Speicher zugreifen zu können, muss LD/ST und Abkömmlinge benutzt werden.

    *** Jetzt kommt die Verwirrung ***

    In der Anleitung für Exercise 3.2 steht unter Pitfalls:
    "If you use the SRAM for your array, note that the array cannot be initialized automatically, you have to initialize the array within your program."

    Im AVR Assembler kann man jedoch unter '.section .data' sehr wohl ein Array und sonstige Variablen schon mit default-Werten initialisieren.

    Im GNU-Assembler Manual heißt es weiters (Abschnitt Sections -> Ld Sections), dass .text und .data Sections vom Linker komplett gleich behandelt werden. Alles was man für eine Section sagen kann, ist auch richtig für die andere.

    Das bedeutet für mich, dass auch alles, was unter '.section .data' aufgeführt ist in den Flash-Speicher geladen wird und deshalb der Zugriff auch mit LPM/SPM zu erfolgen hat.

    '.section .data' ist meiner Meinung deshalb was anderes, als was im ATMega16 Manual als 'Data Memory/SRAM' bezeichnet wird.

    Wenn irgendetwas davon falsch ist, was ich geschrieben habe, bitte sagen, weil ich war bis jetzt auch noch nicht dazu fähig, mein Byte-Array korrekt zu addressieren und hab schon alle möglichen Varianten durchprobiert.

    *** die aktuelle Variante ***

    .section .text

    ...

    infloop:
    ldi ZH, hi8(numbers)
    ldi ZL, lo8(numbers)
    lpm temp, Z

    out SEG_PORT, temp

    rjmp infloop

    .section .data

    numbers:
    .byte 0b00111111
    .byte 0b00000011
    ...
    .byte 0b01110001

  3. #3

    Title
    Principal
    Join Date
    Dec 2008
    Posts
    39
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts
    hallo,
    freut mich das nicht nur ich unfähig bin. sag mal, hast du zufällig auch das folgende problem?
    bei mir funktioniert es bereits das ich hinauf und hinunter zählen kann (das mit dem sram hab ich dawei profresorisch gelöst). soweit so gut. beim hinunterzählen funktioniert alles, bei 0, wird der wrap around gemacht passt. nur beim hinaufzählen bleibt er auf einmal bei F stehen, und macht den wrap around nicht, sondern bleibt einfach stehen-aus. hab jetzt schon probiert das ich mir das punkt-led aufleuchten lasse, wenn er das register mit dem neuen wert beschreibt (also mit 0 für den wrap around) aber das leuchtet nie auf, also anscheinend geht er da gar nicht hinein. und ich hab keine ahnung warum nicht. das vorgehen ist ja analog für das hinunterzählen und da funktioniert es scheinbar.
    fällt wem dazu was ein?

  4. #4

    Title
    Principal
    Join Date
    Dec 2008
    Posts
    39
    Thanks Thanks Given 
    0
    Thanks Thanks Received 
    0
    Thanked in
    0 Posts
    problem gelöst

  5. #5

    Title
    Elite
    Join Date
    Oct 2007
    Location
    Monkey Island
    Posts
    341
    Thanks Thanks Given 
    48
    Thanks Thanks Received 
    41
    Thanked in
    31 Posts
    Die Behauptung im Instruction Manual, man könne mit ".section .data" den SRAM vorinitalisieren ist in der Tat sehr verwirrend, aber wenn man sichs mal überlegt ist es eigentlich völlig sinnlos einen flüchtigen Speicher (also den SRAM in dem Fall) zu initialisieren - nach dem Ausschalten wärs eh wieder weg, deshalb können auch nur Daten auf den Flash-Speicher oder den EEPROM übertragen werden (bzw es wäre vielleicht technisch möglich vom PC aus den SRAM zu beschreiben, aber wie gesagt es ist völlig sinnlos).

    Diese unmögliche SRAM-Vorinitialisierung würde erfordern dass der Prozessor etwa extra bei jedem Reset einen gewissen Speicherbereich von nicht-flüchtigem Speicher (Flash, EEPROM) zum SRAM lädt. Recht viel mehr als dass der PC einfach auf $0000 gesetzt und der Ausführungszyklus gestartet wird passiert aber in Wirklichkeit nicht

    Bezüglich des Adressierungsproblem: ich glaub man muss hier aufpassen, weil vom Assembler ein Label die Adresse mit byte-Größe zurückgegeben wird, die Befehle vom ATmega16 erwarten sich aber Adressen mit word-Größen, also um richtig zu adressieren muss man die gewünschte Adresse mit zwei Multiplizieren:
    ldi ZH, hi8(numbers*2)
    ldi ZL, lo8(numbers*2)

    Das wär das erste das ich probieren würde, aber keine Garantie dass das dann auch wirklich funktioniert (hab mit dem Beispiel noch nicht angefangen)!
    Last edited by fieselschweif; 14-03-2009 at 18:00. Reason: typo
    http://happyvimming.blogspot.com/
    -----
    Etwas zusätzlichen Speicher gefällig?
    "Signetics 25120 - Fully Encoded, 9046xN Random Access Write-Only-Memory" (Datenblatt lesen!)

  6. #6

    Title
    Baccalaureus
    Join Date
    Oct 2007
    Location
    Klein Harras
    Posts
    993
    Thanks Thanks Given 
    4
    Thanks Thanks Received 
    109
    Thanked in
    81 Posts
    Ds mit dem *2 kann ich nicht bestätigen, da dies bei mir nicht nötig ist. Auch gibt es die Befehle hi8/lo8 laut manual ja nicht, das ist was von avr-gcc, außerdem meckert er wenn man so wie im manual high/low verwenden möchte. Soweit ich durch googlen herausgefunden habe ist, dass *2 mit hi8/lo8 nicht mehr nötig, da dieser das erledigt und weiters sogar nicht kompiliert wenn mans macht. Hat mich einize Zeit gekostet bis ich da draufgekommen bin.

    Ja .section .data ist unnötig. Da muss man erst recht am anfang mittels sts in den sram laden.

    mfg Schakal
    Last edited by Schakal; 14-03-2009 at 18:28.

  7. #7

    Title
    Elite
    Join Date
    Oct 2007
    Location
    Monkey Island
    Posts
    341
    Thanks Thanks Given 
    48
    Thanks Thanks Received 
    41
    Thanked in
    31 Posts
    Quote Originally Posted by Schakal View Post
    Ds mit dem *2 kann ich nicht bestätigen, da dies bei mir nicht nötig ist. Auch gibt es die Befehle hi8/lo8 laut manual ja nicht, das ist was von avr-gcc, außerdem meckert er wenn man so wie im manual high/low verwenden möchte. Soweit ich durch googlen herausgefunden habe ist, dass *2 mit hi8/lo8 nicht mehr nötig, da dieser das erledigt und weiters sogar nicht kompiliert wenn mans macht. Hat mich einize Zeit gekostet bis ich da draufgekommen bin.
    Okay hab gerade nachgesehen, ich habe "damals" als ich mit den Atmel AVRs experimentiert habe und das mit der 2-er-Multiplikation notwendig war schlicht und einfach einen anderen Assembler (avra) verwendet, der kompatibel zu dem vom AVR Studio ist, d.h. alle Beispiele im Datenblatt beziehen sich auf diese Syntax. Dort gibts dann auch LOW(), HIGH() und .db - letzteres wurde glaube ich neulich im TUWIS Forum von jemandem vermisst.
    (siehe ein Beispiel zu indirekter Adressierung z.B. auch hier http://www.mikrocontroller.net/artic...zeige#Programm)

    Finde es seltsam dass wir in dieser LVA die GNU Assembler Syntax verwenden - nicht dass ich so ein großer Windows Liebhaber wäre aber in dem Fall wärs einfach sinnvoller sich an die offzielle von Atmel in den Manuals verwendete Syntax zu halten, zumal wahrscheinlich auch >90% des Codes den man so im Netz zu AVR µCs findet in dieser verfasst ist.
    Aber was solls, man kann nicht alles haben, muss ich mich halt ein bisschen umgewöhnen... sobald wir dann C verwenden sollte das ohnehin hinfällig sein.
    http://happyvimming.blogspot.com/
    -----
    Etwas zusätzlichen Speicher gefällig?
    "Signetics 25120 - Fully Encoded, 9046xN Random Access Write-Only-Memory" (Datenblatt lesen!)

  8. #8
    Snafu's Avatar
    Title
    Baccalaureus
    Join Date
    Sep 2007
    Posts
    688
    Thanks Thanks Given 
    4
    Thanks Thanks Received 
    101
    Thanked in
    38 Posts
    Hab die Codes für die Zahlen im Flash gespeichert und verwende
    Code:
    ldi ZH, hi8(Codes) ; Z register mal initialisieren
    ldi ZL, lo8(Codes)
    ...
    lpm R16, Z+ ; in der Schleife
    um den aktuellen Code einzulesen und das Z Register gleich zu inkrementieren.
    Das funktionniert auch alles ganz gut, allerdings nur beim Hinaufzählen. Der lpm Befehl kann ja leider nur inkrementieren, muss ich wenn ich hinunterzählen will wirklich immer mit der ZH und ZL zuweisung arbeiten?
    Wär ja dann ned gleich schnell weil lpm ja immer 3 Cycles braucht egal ob man lpm; lpm Rd, Z; oder lpm Rd, Z+ verwendet wenn ich das richtig verstanden hab.

  9. #9

    Title
    Elite
    Join Date
    Oct 2007
    Location
    Monkey Island
    Posts
    341
    Thanks Thanks Given 
    48
    Thanks Thanks Received 
    41
    Thanked in
    31 Posts
    @Snafu: Ich würd einfach den Zählwert in ein eigenes Register (mit beinhaltendem Wertebereich [0,16[)stopfen, und diesen halt jeweils immer vor der Ausgabe zu Z addieren - der Nachteil ist halt dass man Z jedes mal wieder in der Schleife neu setzen muss, aber ich sehe keine andere Möglichkeit und ich glaube die paar Taktzyklen kann man schon verschmerzen. Sieht dann ungefähr so aus:
    Code:
    ldi Zero, 0x00
    
    loop:
        ldi ZL, lo8(Codes)
        ldi ZH, hi8(Codes)
        add ZL, Counter
        adc ZH, Zero
        lpm ; Code steht im R0
    Das eigene Zero-Register sieht nicht gerade schön aus aber ich glaube anders geht es nicht, da es keine Addition mit Immediate mode gibt im AVR Instruction Set.
    Wäre es bei deiner Methode überhaupt möglich gewesen, zu bestimmen, wann Code "F" überschritten wurde und man wieder auf 0 setzen muss?
    http://happyvimming.blogspot.com/
    -----
    Etwas zusätzlichen Speicher gefällig?
    "Signetics 25120 - Fully Encoded, 9046xN Random Access Write-Only-Memory" (Datenblatt lesen!)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •