Forum: Mikrocontroller und Digitale Elektronik Programm soll statt Atmega8 auf Atmega48 laufen


von Markus A. (tubeland)


Lesenswert?

Hallo,

Anbei habe ich hier ein Programm einer Flip Flop Schaltung diese Läuft 
auf dem AT Mega8 einwandfrei

Nun habe ich Probleme dieses Programm auf einen ATmega48 am laufen zu 
bekommen.

Anbei das Programm und die Fehlermeldung
1
.include "m48def.inc"
2
3
.def iwr0      = r1
4
.def iwr1      = r2
5
6
.def key_old   = r3
7
.def key_state = r4
8
.def key_press = r5
9
10
.def temp1     = r17
11
.def sreg_save = r18
12
13
14
.equ key_pin   = PINB
15
.equ key_port  = PORTB
16
.equ key_ddr   = DDRB
17
18
.def leds      = r19
19
.equ led_port  = PORTD
20
.equ led_ddr   = DDRD
21
22
.org 0x0000
23
;rcall   EEPROM_read
24
    rjmp    init
25
26
.org OVF0addr
27
    rjmp    timer_overflow0
28
29
;
30
; *****************************************************************************
31
;
32
; Initialisierung
33
; Alle Komponenten auf die Startbedingungen einstellen
34
;
35
init:
36
;
37
;  Stackpointer
38
;
39
    ldi      temp1, HIGH(RAMEND)
40
    out      SPH, temp1
41
    ldi      temp1, LOW(RAMEND)     ; Stackpointer initialisieren
42
    out      SPL, temp1
43
;
44
; Ausgänge
45
;
46
    ldi      temp1, 0xFF
47
    out      led_ddr, temp1
48
;
49
; Eingänge
50
;
51
    ldi      temp1, 0xFF            ; Tasten sind auf Eingang
52
    out      key_port, temp1        ; Pullup Widerstände ein
53
;
54
; Timer für die Tastenabfrage
55
;
56
    ldi      temp1, 1<<CS02 | 1<<CS00   ; Timer mit Vorteiler 1024
57
    out      TCCR0, temp1
58
    ldi      temp1, 1<<TOIE0            ; Timer Overflow Interrupt einrichten
59
    out      TIMSK, temp1
60
61
    clr      key_old                ; die Register für die Tastenauswertung im
62
    clr      key_state              ; Timer Interrupt initialisieren
63
    clr      key_press
64
65
    sei                             ; und los gehts: Timer frei
66
67
;
68
; aus dem EEPROM den letzten Zustand wiederherstellen
69
70
    ldi      ZL,low(daten)
71
    ldi      ZH,high(daten)
72
    rcall    EEPROM_read            ; Byte ist in r16
73
  
74
    mov      leds, r16
75
  out      led_port, leds    
76
77
;
78
; Alles ist eingerichtet. Jetzt gehts mit der eigentlichen Arbeit los
79
;
80
main:
81
    cli                             ;
82
    mov      temp1, key_press       ; Einen ev. Tastendruck merken und ...
83
    clr      key_press              ; Tastendruck zurücksetzen
84
    sei
85
86
    cpi      temp1, 0               ; Tastendruck auswerten. Wenn eine von 8 Tasten
87
    breq     main                   ; gedrückt worden wäre, wäre ein entsprechendes
88
                                    ; Bit in key_press gesetzt gewesen
89
90
    eor      leds, temp1            ; Die zur Taste gehörende Led umschalten
91
    out      led_port, leds
92
93
                                    ; und den neuen Zustand im EEPROM ablegen
94
                                    ; das Z-Register ist noch vom Lesen an
95
                                    ; der richtigen Stelle
96
    mov      r16, leds
97
    rcall    EEPROM_write
98
99
    rjmp     main
100
101
;
102
; *****************************************************************************
103
;
104
; Timer Overflow
105
; wird regelmässig aufgerufen und hat die Aufgabe die Tasten auszuwerten
106
;
107
; Eine vollständig gedrückte Taste wird im Register key_press mit einem
108
; 1 Bit vermerkt. Der Benutzer ist selbst dafür zuständig, dieses Bit
109
; wieder zu löschen
110
;
111
timer_overflow0:               ; Timer Overflow Interrupt
112
113
    push    r0                 ; temporäre Register sichern
114
    in      r0, SREG
115
    push    r0
116
    push    iwr0
117
    push    iwr1
118
119
get8key:                       ;/old      state     iwr1      iwr0
120
    mov     iwr0, key_old      ;00110011  10101010            00110011
121
    in      key_old, key_pin   ;11110000
122
    eor     iwr0, key_old      ;                              11000011
123
    com     key_old            ;00001111
124
    mov     iwr1, key_state    ;                    10101010
125
    or      key_state, iwr0    ;          11101011
126
    and     iwr0, key_old      ;                              00000011
127
    eor     key_state, iwr0    ;          11101000
128
    and     iwr1, iwr0         ;                    00000010
129
    or      key_press, iwr1    ; gedrückte Taste merken
130
;
131
;
132
    pop     iwr1               ; Register wiederherstellen
133
    pop     iwr0
134
    pop     r0
135
    out     SREG, r0
136
    pop     r0
137
    reti
138
139
;
140
; *****************************************************************************
141
;
142
; Lesefunktion aus dem EEPROM
143
;
144
; Die Adresse von der gelesen werden soll, wird im Z-Register übergeben (r30/r31)
145
;
146
; Das gelesene Byte bekommt man im Register r16 zurückgeliefert
147
;
148
EEPROM_read:
149
    sbic    EECR,EEWE                   ; prüfe ob der vorherige Schreibzugriff
150
                                        ; beendet ist
151
    rjmp    EEPROM_read                 ; nein, nochmal prüfen
152
153
    out     EEARH, ZH                   ; Adresse laden
154
    out     EEARL, ZL
155
    sbi     EECR, EERE                  ; Lesevorgang aktivieren
156
    in      r16, EEDR                   ; Daten in CPU Register kopieren
157
  ;out      led_port, leds
158
    ret
159
160
;
161
; *****************************************************************************
162
;
163
; Schreibfunktion ins EEPROM
164
;
165
; Die Adresse an die geschrieben werden soll, wird im Z-Register übergeben (r30/r31)
166
; Das zu schreibende Byte wird im Register r16 übergeben
167
;
168
EEPROM_write:
169
    sbic    EECR, EEWE                  ; prüfe ob der letzte Schreibvorgang beendet ist
170
    rjmp    EEPROM_write                ; wenn nein, nochmal prüfen
171
 
172
    out     EEARH, ZH                   ; Adresse schreiben
173
    out     EEARL, ZL                   ; 
174
    out     EEDR, r16                   ; Daten  schreiben
175
    in      sreg_save,sreg              ; SREG sichern
176
    cli                                 ; Interrupts sperren, die nächsten
177
                                        ; zwei Befehle dürfen NICHT
178
                                        ; unterbrochen werden
179
    sbi     EECR,EEMWE                  ; Schreiben vorbereiten
180
    sbi     EECR,EEWE                   ; Und los !
181
    out     sreg, sreg_save             ; SREG wieder herstellen
182
    ret
183
184
185
; Daten im EEPROM definieren
186
;
187
.eseg
188
;
189
daten:
190
    .db     0b00000000


Das sind die Meldungen
1
C:\flipflop at mega48\flipflopneu3.asm(1): Including file 'C:\Programme\Atmel\AVR Tools\AvrAssembler2\Appnotes\m48def.inc'
2
C:\flipflop at mega48\flipflopneu3.asm(57): error: Undefined symbol: TCCR0
3
C:\flipflop at mega48\flipflopneu3.asm(59): error: Undefined symbol: TIMSK
4
C:\flipflop at mega48\flipflopneu3.asm(153): error: Undefined symbol: EEARH
5
C:\flipflop at mega48\flipflopneu3.asm(172): error: Undefined symbol: EEARH
Was muss dort anders sein damit es dann läuft?
Beste Grüße markus

: Bearbeitet durch User
von Fritz G. (fritzg)


Lesenswert?

Schau ins Datenblatt vom Mega48, wie dort die Register heissen.Es gibt 
da z.B. TIMSK1 und TIMSK2.

von S. Landolt (Gast)


Lesenswert?

Auch liegen die Register z.T. in einem anderen Adressbereich, also std 
statt out.
Und der ATmega48 hat nur 256 Bytes EEPROM, also kein EEARH.

von NobbyH (Gast)


Lesenswert?

Wie Fritz schon schrieb sind die Register vom ATMEGA8 und ATMEGA48 
teilweise unterschiedlich. D.h. Du musst diese entsprechend anpassen 
damit das Programm auf dem ATMEGA48 läuft.
In der Liste der Fehlermeldungen siehst Du genau, welche Register nicht 
identisch sind bzw. andere Namen haben:

D:\Software\Flipflop.asm(1): Including file 'C:\Program Files\Atmel\AVR 
Tools\AvrAssembler2\Appnotes\m48def.inc'
D:\Software\Flipflop.asm(57): error: Undefined symbol: TCCR0
D:\Software\Flipflop.asm(59): error: Undefined symbol: TIMSK
D:\Software\Flipflop.asm(154): error: Undefined symbol: EEARH
D:\Software\Flipflop.asm(173): error: Undefined symbol: EEARH

Es können aber auch die Inhalte der Register abweichend sein.
Details findest Du im Datenblatt

von Markus A. (tubeland)


Lesenswert?

ist es dann EERE ?

von S. Landolt (Gast)


Lesenswert?

(Pardon, Sie sollten wirklich das Datenblatt zur Hand nehmen)

EERE ist ein Bit im EECR.
Vermutlich gibt es nur EEARL, müsste ich aber auch erst ausprobieren.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Als groben Anhaltspunkt kannst du mal in den Migration Guide vom atmega8 
zum atmega88 (ja, 88 nicht 48) reinsehen.

von Dieter F. (Gast)


Lesenswert?


von Markus A. (tubeland)


Lesenswert?

Mich macht es neugierig was gemacht werden muss damit es funktioniert 
wenn ich es wüste würde ich nicht fragen

von S. Landolt (Gast)


Lesenswert?

Ob Ihnen das auf Dauer wirklich weiterhilft?

;    out      TCCR0, temp1
    out      TCCR0B, temp1

;    out      TIMSK, temp1
    sts      TIMSK0, temp1

;    out     EEARH, ZH                   ; Adresse laden

;    out     EEARH, ZH                   ; Adresse schreiben

von Markus A. (tubeland)


Lesenswert?

Nach der Änderung sind die Fehlermeldungen weg nur funktioniert es so 
nicht. Oder muss
;    out     EEARH, ZH                   ; Adresse laden

;    out     EEARH, ZH                   ; Adresse schreiben
auch ersetzt werden?

von S. Landolt (Gast)


Lesenswert?

> nur funktioniert es so nicht.
Zur Funktion kann ich nichts sagen, ich habe nur rein formal umgesetzt; 
wollte eigentlich auch nur meinen Schreibfehler von ganz oben 
wiedergutmachen.

Die beiden Zeilen mit EEARH werden ersatzlos gestrichen.

von S. Landolt (Gast)


Lesenswert?

Ich habe das jetzt mal eben zusammengesteckt: bei mir läuft es.
Einen schönen Sonntag wünsche ich.

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Markus Andrzejewski schrieb:
> Mich macht es neugierig was gemacht werden muss damit es funktioniert
> wenn ich es wüste würde ich nicht fragen

Der Punkt ist, dass du offensichtlich in fünf Jahren nichts dazugelernt 
hast. Du kommst hier mit dem selben Mist an, der vor fünf Jahren schon 
falsch war. Du bestehst immer noch darauf es genau so falsch zu machen, 
obwohl man dir schon vor fünf Jahren gesagt hat, dass es so nicht 
funktioniert und dir gezeigt hat wie es geht.

Dann ignorierst du heute, wie vor fünf Jahren, alle Hinweise die dir zu 
unbequem sind. Anders ausgedrückt, wie vor fünf Jahren behandelst du uns 
als ob wir für dich nur ein Stück Scheiße sind.

von Markus A. (tubeland)


Lesenswert?

Sorry, den hinweisen bin ich nach gegangen habe dann wohl an der 
falschen Stelle nach geschaut.

Muss sagen funktioniert jetzt doch. hatte den Taster zu kurz betätigt.

Habe dann
1
 ldi      temp1, 1<<CS02 | 1<<CS00   ; Timer mit Vorteiler 1024
geändert in
1
 ldi      temp1, 1<<CS01 | 1<<CS00   ; Timer mit Vorteiler 1024
so ist die Reaktion schneller.

Auf welche Seiten Hätte ich denn die Lösung gefunden?

: Bearbeitet durch User
von spess53 (Gast)


Lesenswert?

HI

> ldi      temp1, 1<<CS01 | 1<<CS00   ; Timer mit Vorteiler 1024

Ohne nachzusehen: ist garantiert falsch

>so ist die Reaktion schneller.

>Auf welche Seiten Hätte ich denn die Lösung gefunden?

Ich tippe auf die CKDIV8-Fuse. Die gibt es beim ATMega8 nicht.

MfG Spess

von Dieter F. (Gast)


Lesenswert?

spess53 schrieb:
>> ldi      temp1, 1<<CS01 | 1<<CS00   ; Timer mit Vorteiler 1024
>
> Ohne nachzusehen: ist garantiert falsch

Erstmal nur in Bezug auf den Kommentar ... die Fuse-Einstellung wird 
aber sicher auch eine Rolle spielen ... :-)

von Dieter F. (Gast)


Lesenswert?

Markus Andrzejewski schrieb:
> Auf welche Seiten Hätte ich denn die Lösung gefunden

Ich schätze mal, im Datenblatt - bei Timer ...

von spess53 (Gast)


Lesenswert?

Hi

>Erstmal nur in Bezug auf den Kommentar ...

Das war nicht auf den Kommentar gemünzt.

MfG Spess

von Dieter F. (Gast)


Lesenswert?

spess53 schrieb:
> Das war nicht auf den Kommentar gemünzt

Worauf denn? Eine "gültige" Timer-Einstellung ist es - oder?

von S. Landolt (Gast)


Lesenswert?

Der Sprung von /1024 auf /64 ist zu groß, soo langsam waren die Taster 
dann doch nicht.

von Dieter F. (Gast)


Lesenswert?

S. Landolt schrieb:
> Der Sprung von /1024 auf /64 ist zu groß, soo langsam waren die Taster
> dann doch nicht.

Mit CKDIV8 passt das ungefähr - aber was ist sonst noch falsch ?

von S. Landolt (Gast)


Lesenswert?

Einen eigentlichen Fehler kann ich nicht erkennen, auch fand ich die 
ursprüngliche Ansprechzeit nicht ungewöhnlich (bin eine Logamatic 2107 
gewohnt).
Aber ich hätte den Mittelweg gewählt, also /256.

von spess53 (Gast)


Lesenswert?

Hi

>Worauf denn? Eine "gültige" Timer-Einstellung ist es - oder?

Klar. Aber wenn im ursprünglichen Programm der Vorteiler von von 1024 
für eine angemessene 'Langsamkeit' notwendig war, und jetzt dafür ein 
Vorteiler von 128 notwendig ist, zeugt das von einer langsameren 
Taktfrequenz als angenommen.

MfG Spess

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.