www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATtiny12 für Modellbau-Lauflichtsteuerung


Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo zusammen,

ich habe eine frage zu meinem code (siehe unten). ich bin anfänger in 
maschinensprache. zuletzt habe ich einen commodore 64 in 6510 
programmiert, seitdem schlummern meine bemühungen dort.

ich habe für meine modell-kirmesfahrgeschäfte die lauflichter und 
motorsteuerungen alle mit verschiedenen atmels aufgebaut. für ein 
fahrgeschäft, dass sehr wenig platz auf dem mittelbau hat, habe ich mir 
jetzt ein paar attiny12 kommen lassen (sowohl dip zum testen als auch 
smd für die endversion).

hier ein paar rahmendaten:

plattform: pc mit bascom, stk500
zielprozessor: attiny12 (ohne sram, die tücken hab ich schon gelöst)

das programm läuft, lädt aber nicht die daten aus dem .db-bereich zur 
ausgabe. im simulator lädt er mit den z-pointer ordentlich, aber lpm 
liefert müll. da ich anfänger bin, steh ich da jetzt mit meinem kurzen 
hemd und frage mich, wieso das nicht geht. ich bitte um hinweise, wie 
ich den code auf einem attiny12 ans rennen kriege (bitte keine 
alternativen prozessorvorschläge oder plattformwechsel).

hier der code:
'--------------------------------------------------------------------
' Lauflicht 5-Kanal für den ATtiny12
'
' 01.12.09
'
'--------------------------------------------------------------------

' register 10 bis 27 können frei genutzt werden, die anderen verwendet bascom
' und sollten in ruhe gelassen werden

$regfile = "ATtiny12.DAT"
$crystal = 1200000
$tiny
$noramclear
$swstack = 0
$framesize = 0

$asm
.def Zaehler1 = R17
.def Zaehler2 = R18
.def Muster = R16
.def Wiederholung = R19

rjmp main                                                   ' zum hauptprogramm

Main:
 ldi muster ,&b00011111                                     ' 3 Nullen und 5 Einsen in Universalregister
 !Out Ddrb , Muster                                         ' An Datenrichtungsregister

Mymain:

   ldi zl, low(licht * 2)
   ldi zh, high(licht * 2)
   ldi wiederholung, 32

Vorwaerts:
   lpm                                                      ' durch z-puffer adressiertes byte in R0 laden
   adiw zl,1                                                ' eins weiter im speicher
   mov muster, r0                                           ' r0 ins muster schieben
   !Out Portb , muster                                      ' und auf portb ausgeben
   lpm                                                      ' nächstes datenbyte
   adiw zl,1                                                ' pointer eins weiter
   mov zaehler1,r0                                          ' r0 in zaehler1 schieben
   rcall Warten                                             ' unterprogramm warteschleife aufrufen


   lpm                                                      ' durch z-puffer adressiertes byte in R0 laden
   adiw zl,1
   mov muster, r0
   !Out Portb , muster                                      ' und auf portb ausgeben
   lpm                                                      ' nächstes datenbyte
   adiw zl,1                                                ' pointer eins weiter
   mov zaehler1,r0
   rcall Warten                                             ' unterprogramm warteschleife aufrufen

   dec wiederholung                                         ' wiederholungszähler um 1 verringern
brne vorwaerts                                              ' solange ungleich null, wieder nach anfang des lichtmusters


rjmp mymain                                                 ' endlosprogramm, wieder an anfang springen

Warten:
'--- etwas warten
Outer2:
   ldi zaehler2, 255
   Inner2:
      dec zaehler2
      nop
      nop
      nop
      cpi zaehler2,0
   brne inner2
   dec zaehler1
   cpi zaehler1,0
brne outer2
ret
Licht:
.db 00 , 128 , 01 , 128 , 02 , 128 , 04 , 128 , 08 , 128 , 16 , 128 , 32 , 128 , 64 , 128 , 128 , 128
.db 00 , 128 , 01 , 128 , 02 , 128 , 04 , 128 , 08 , 128 , 16 , 128 , 32 , 128 , 64 , 128 , 128 , 128

$end Asm
End


Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>im simulator lädt er mit den z-pointer ordentlich, aber lpm liefert müll.

Was heißt "liefert müll"? Irgendwelche Werte müssen ja nach lpm in r0 
erscheinen. Ändere das erste Datenbyte mal von 0 in 53 und check das 
allererste lpm. Erscheint 53 in r0 oder nicht?

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in r30/r31 (zl/zh) steht im simulator 67/00 und in r0 steht f8. diese f8 
(statt der beabsichtigten 00) schiebt er mir dann in r16 und das dann 
auf den port. und eine f8 finde ich nirgendwo. das ist das, was der 
simulator liefert, der prozessor wirft mir als letzte 5 bit laut 
invertiertem led-status auf dem stk-500 (attiny12 mit 6 bit ausgabe, 
aber einer weniger wegen reset für isp) xxx11000 aus.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vergessen: ich hab das erste .db mal auf 53 geändert. der simulator 
bleibt bei f8.

Autor: Icke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oberflächlich fallen mir zwei Dinge ins Auge. ADIW ist für Registerpaare 
vorgesehen und nicht für Einzelregister:

falsch: adiw zl, 1
richtig: adiw zh:zl, 1

und die Warteschleife ist imho für Lauflicht zu kurz (hab ich aber nur 
geschätzt, nicht gerechnet)

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich bin ja für jeden tipp dankbar - und habs ausprobiert. bascom mag die 
notation zh:zl nicht und sagt "low pointer register expected" und bricht 
den compiler mit error 200/201 ab. ich hatte die online-hilfe auch so 
verstanden, dass man bascom da nur das low-register angibt.

die warteschleife ist schon ok so. ich habe ja ein funktionierendes 
lauflicht, was aber immer wieder die daten direkt auf den port schreibt 
statt über data-bereiche. da ist die gleiche warteschleife drin und es 
funktioniert prima: 
http://macs-modellwelt.de/video/octopussy/20091204... (der 
ampelfarbene arm rechts arbeitet mit dem attiny12, die masten links mit 
attiny2313).

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hoppla, wie mir ein Blick ins Datenblatt verriet, verfügt der ATtiny12 
gar nicht über die Instruktion adiw!

@Markus: Definier Dir zwei Register _0 und _1, z. B.

.def _0 = r20
.def _1 = r21

und setz sie beim Programmstart entsprechend mit ldi auf 0 bzw. 1.

Ersetze anschließend alle "adiw zl,1" durch

add ZL, _1
adc ZH, _0

Läuft das Programm dann korrekt?

Autor: Icke (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...noch einfacher wäre natürlich:

lpm Z+

weiß jetzt aber nicht genau, ob der tiny den Befehl unterstützt.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so, an alle zusammen: das war mal richtig cool, denn der code läuft nach 
einigen modifikationen und etwas ausprobieren. und das in unter 3 
stunden!

der tipp mit "adiw geht nicht auf dem attiny12" war sehr gut. kann er 
wirklich nicht, der workaround mit den konstanten-registern klappt. lpm 
z+ ist glaube ich noch fortschrittlicher uns somit auf dem alten ding 
nicht implementiert. jetzt verstehe ich auch den hinweis "not 
recommended for new design" im datenblatt.

spaßig an der sache: der simulator tut so, als könne der attiny12 aber 
adiw. auf dem simulator klappte das prima. stützt sich der simulator auf 
die def-files oder denkt der sich lustig was aus?

ein weiteres problem, was ich vermute und jetzt einfach mal abgestellt 
habe: der attiny12 hat ja kein sram, also auch ein stack-problem. im 
vorbeigehen habe ich irgendwo gelesen, dass er dafür die letzten 3 
doppel-register nimmt. wenn das stimmt, muss ich mich nicht wundern, 
wenn nach einem rcall mein z-register wuschig ist und nur noch mist 
enthält. da die warteschleife jetzt eh nur noch einmal genutzt wird, 
habe ich sie in den hauptcode verschoben und schenke mir den 
unterprogramm-aufruf. so spare ich mir das retten vom z-register.

was ich mich jetzt noch frage: er hat im obigen code das 
licht-daten-label "licht:" nicht korrekt übersetzt, es stand zwei bytes 
zu früh (nach einblick mit einem hex-editor ins hex-file). jetzt addiere 
ich 2 drauf und es geht.

entrümpelt habe ich den code jetzt auch noch etwas und nun sieht er so 
aus und klappt (wer will, darf ihn verwenden):
$asm
.def Zaehler1 = R17
.def Zaehler2 = R18
.def Muster = R16
.def Wiederholung = R19
.def _0 = r20
.def _1 = r21

rjmp main                                                   ' zum hauptprogramm

Main:
 ldi muster ,&b00011111                                     ' 3 Nullen und 5 Einsen in Universalregister
 !Out Ddrb , Muster                                         ' An Datenrichtungsregister

Mymain:

   ldi _0,0
   ldi _1,1
   ldi zl, low(licht * 2)
   ldi zh, high(licht * 2)
   add ZL, _1
   adc ZH, _0
   add ZL, _1
   adc ZH, _0
   ldi wiederholung, 5

Vorwaerts:
   lpm                                                      ' durch z-puffer adressiertes byte in R0 laden
   add ZL, _1
   adc ZH, _0
   mov muster, r0                                           ' r0 ins muster schieben
   !Out Portb , muster                                      ' und auf portb ausgeben
   lpm                                                      ' nächstes datenbyte
   add ZL, _1
   adc ZH, _0
   mov zaehler1,r0                                          ' r0 in zaehler1 schieben
   Outer2:
      ldi zaehler2, 255
      Inner2:
         nop
         nop
         nop
         dec zaehler2
         cpi zaehler2,0
      brne inner2
      dec zaehler1
      cpi zaehler1,0
   brne outer2

   dec wiederholung                                         ' wiederholungszähler um 1 verringern
brne vorwaerts                                              ' solange ungleich null, wieder nach anfang des lichtmusters

rjmp mymain                                                 ' endlosprogramm, wieder an anfang springen

Licht:
.db 01 , 100 , 02 , 100 , 04 , 100 , 08 , 100 , 16 , 100
$end Asm

Autor: Wayne Monga (vibra)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
moin

ich subtrahiere -1


subi ZL,-1 ; Increment Z by 1
sbci ZH,-1

ist das selbe wie

adiw zlo,1

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
warum benutzt du nicht nen tiny 25/45/85

die sind genauso groß. kosten nicht wirklich mehr und bieten 
Erweiterungsmögliochkeiten.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weil ich 20 tiny12 bestellt hab :) und das einzige, was alle 
atmel-prozessoren mit meiner lauflicht-applikation haben, ist große 
langeweile. der arme fräst sich ja nur durch NOPs. da muss nix erweitert 
werden und es reicht das, was da ist.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Glückwunsch.

>der simulator tut so, als könne der attiny12 aber adiw.

Das dürfte eigentlich nicht sein.

>stützt sich der simulator auf die def-files oder denkt der sich lustig was aus?

Öffne doch mal die zugehörige def-Datei in einem Editor und check, ob da 
irgendwas mit lpm drin verzeichnet ist, etwa ein Eintrag der Art 
INSTRUCTION_LPM = NO.

>ein weiteres problem, was ich vermute und jetzt einfach mal abgestellt
>habe: der attiny12 hat ja kein sram, also auch ein stack-problem.

Der ATtiny12 hat kein SRAM, aber sehr wohl einen Stack, nämlich einen 
3-Level-Hardware-Stack. Er besteht aus drei 9 Bit breiten 
Extra-Registern, die vom Programm aus nicht addressierbar sind. Dieser 
Stack wird für Interrupts und normale Subroutinen verwendet. Du kannst 
also problemlos rcall und ret verwenden, solange die 
Verschachtelungstiefe nicht größer als drei wird. Die drei 
Stack-Register haben mit den Registern r0...r31 nichts zu tun.

>wenn das stimmt, muss ich mich nicht wundern, wenn nach einem rcall mein
>z-register wuschig ist und nur noch mist enthält.

Nein, das hast Du falsch verstanden.

>er hat im obigen code das licht-daten-label "licht:" nicht korrekt
>übersetzt, es stand zwei bytes zu früh

Sehr merkwürdig. Vielleicht werden die Datenbytes nach .DB von BASCOM 
auf gerade Wortadressen ausgerichtet, aber das ist nur eine vage Idee.

>jetzt addiere ich 2 drauf und es geht.

Machs doch so und spar Dir die vier add/adc-Zeilen:

   ldi zl, low(licht * 2 + 2)
   ldi zh, high(licht * 2 + 2)

>entrümpelt habe ich den code jetzt auch noch etwas

Wenn Du noch was rauswerfen willst: cpi zaehler2,0 und cpi zaehler1,0 
sind überflüssig, denn dec setzt ja schon das Z-Bit.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>irgendwas mit lpm drin verzeichnet ist, etwa ein Eintrag der Art
>INSTRUCTION_LPM = NO.

Korrektur:

irgendwas mit adiw drin verzeichnet ist, etwa ein Eintrag der Art
INSTRUCTION_ADIW = NO.

Autor: Markus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
so, die cpis sind auch noch raus - das war damals in 
6502-maschinensprache auch so, dass das zero-flag automatisch gesetzt 
wird. ich war mir hier nicht sicher, deshalb hab ich das cpi mit 
reingesetzt, obwohl ich wie damals schon runterzählende schleifen 
gemacht habe, um bei 0 den branch zu setzen.

die veränderungen beim setzen des z-registers auf
   ldi zl, low(licht * 2 + 2)
   ldi zh, high(licht * 2 + 2)

hat wieder alles zernagelt, dann indizierte er wieder falsch und die 
liuchtmuster passen nicht mehr. alternativ habe ich nur 1 draufaddiert, 
ging genauso in die hose (mit dem identisch falschen lichtmuster). ich 
schieb das jetzt mal dreisterweise auf den bascom 1.11.9.1, den ich hier 
benutze. ich habe es auch noch mit dem ! vor low und high probiert, 
damit er die befehle nicht mit basic-tokens verwechselt (siehe out), 
aber das produziert auch nicht das gewünschte. ich nehme das jetzt als 
gegeben hin und freu mich, dass es geht, wobei ich das im normalfall 
gern exakt wüsste. die lauflichtsteuerungen sind nicht mein hauptziel 
beim modellbau.

danke für die hinweise zum hardware-stack. in das dat-file von bascom 
habe ich auch reingesehen, die sperren oder erlauben da nichts mit 
befehlen, wenn ich das jetzt auf die schnelle verstanden habe. dort 
steht nur was über ram-ausstattung, i2c erlaubt oder gesperrt etc.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.