Hallo,
Ich programmiere im Moment einen Wecker mit einem Atmega 48. Dazu
benutze ich ein normales LCD, das auch schon mal funktionierte, und zwar
mit den fertigen Routinen von hier:
http://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD
Doch in letzter Zeit gibt mir das AVR-Studio immer folgenden Fehler aus:
AVR Simulator: Invalid opcode 0xffff at address 0x00f400
Auch auf dem Mikrocontroller scheint das Programm in einer
Endlosschleife zu hängen, denn es passiert einfach gar nichts. Hier mein
Code:
1 | .include "m48def.inc"
|
2 | .def temp1 = r16; temp1
|
3 | .def temp2 = r17; temp2
|
4 | .def temp3 = r18; temp3
|
5 | .def zaehler = r19; zaehler
|
6 | .def anders = r20; anders
|
7 | .def modus = r21; modus
|
8 | .def dcf_count1 = r22; dcf_counter
|
9 | .def dcf_count2 = r23; dcf_counter
|
10 |
|
11 |
|
12 | .org 0x0000
|
13 | rjmp reset ; Reset Handler
|
14 | .org OVF0addr
|
15 | rjmp timer0_overflow ; Timer Overflow Handler
|
16 |
|
17 | reset:
|
18 | ldi temp1, 255 ; B = Ausgang
|
19 | out DDRB, temp1
|
20 | ldi temp1, 255 ; C = Ausgang
|
21 | out DDRC, temp1
|
22 | ldi temp1, 0 ; D = Eingang
|
23 | out DDRD, temp1
|
24 |
|
25 |
|
26 | ldi temp1, HIGH(RAMEND) ; Stackpointer initialisieren
|
27 | out SPH, temp1
|
28 | ldi temp1,LOW(RAMEND)
|
29 | out SPL, temp1
|
30 |
|
31 | ldi temp1, (0b01) ; CS00 setzen: Teiler 1
|
32 | out TCCR0B, temp1
|
33 | ldi temp1, (1<<TOIE0) ; TOIE0: Interrupt bei Timer Overflow
|
34 | sts TIMSK0, temp1
|
35 | sei ; Interrupts allgemein aktivieren
|
36 |
|
37 | ; Initialisierungen:
|
38 | rcall dcf77_init
|
39 | rcall dcf_init_1
|
40 | rcall lcd_init
|
41 | rcall lcd_clear
|
42 | rcall dcf_init_2
|
43 | ldi modus,0
|
44 | ldi temp1,0
|
45 | sts STU,temp1
|
46 | ldi temp1,0
|
47 | sts MIN,temp1
|
48 | ldi temp1,0
|
49 | sts SEK,temp1
|
50 | ; Jetzt beginnt das Hauptprogramm:
|
51 | ;.....
|
Weiter als bis "rcall lcd_init" kommt das Programm gar nicht. Es springt
zwar dorthin, doch dann funktioniert i.was nicht mehr richtig. Der Code:
1 | ;.......
|
2 | ; Längere Pause für manche Befehle
|
3 | delay5ms: ; 5ms Pause (bei 4 MHz)
|
4 | ldi temp1, $21
|
5 | WGLOOP0: ldi temp2, $C9
|
6 | WGLOOP1: dec temp2
|
7 | brne WGLOOP1
|
8 | dec temp1
|
9 | brne WGLOOP0
|
10 | ret ; wieder zurück
|
11 |
|
12 | ; Initialisierung: muss ganz am Anfang des Programms aufgerufen werden
|
13 | lcd_init:
|
14 | ldi temp3,50 ;!!!!!Hier bleibt das Programm stehen?,
|
15 | ; es funktioniert nur, wenn man es nur max 5 mal
|
16 | ; wiederholt
|
17 | powerupwait:
|
18 | rcall delay5ms
|
19 | dec temp3
|
20 | brne powerupwait
|
21 | ldi temp1, 0b00000011 ; muss 3mal hintereinander gesendet
|
22 | out PORTC, temp1 ; werden zur Initialisierung
|
23 | rcall lcd_enable ; 1
|
24 | rcall delay5ms
|
25 | rcall lcd_enable ; 2
|
26 | rcall delay5ms
|
27 | rcall lcd_enable ; und 3!
|
28 | rcall delay5ms
|
29 | ldi temp1, 0b00000010 ; 4bit-Modus einstellen
|
30 | out PORTC, temp1
|
31 | rcall lcd_enable
|
32 | rcall delay5ms
|
33 | ldi temp1, 0b00101000 ; 4Bit / 2 Zeilen / 5x8
|
34 | rcall lcd_command
|
35 | ldi temp1, 0b00001100 ; Display ein / Cursor aus / kein Blinken
|
36 | rcall lcd_command
|
37 | ldi temp1, 0b00000100 ; inkrement / kein Scrollen
|
38 | rcall lcd_command
|
39 | ret
|
40 | ;.......
|
Das Problem liegt denke ich bei der Stelle, die ich mit den Fragezeichen
markiert habe. Könnt ihr mir bitte sagen, was dort falsch sein könnte?
Ich habe auch nochmal das gesamte Projekt als rar-Archiv angehängt.
Danke
Hans