Forum: Mikrocontroller und Digitale Elektronik ASM Codeproblem


von Bruno M. (brumay)


Lesenswert?

Hallo,

Ich bin dabei ein Programm für einen LCD Controller zu schreiben und 
stoße dabei auf ein Problem, das ich mir nicht erklären kann.
1
LCD_Clear:
2
 ldi  XL, 0x00  
3
 ldi  XH, YMin  ;Display-RAM erst ab 0x500 zu erreichen
4
 ldi  temp, 0
5
6
LCD_Clear_loop:
7
 st  X+, temp  
8
 cpi  XH, 0xFF  ;bis 0xFFFF gelöscht?
9
 brne  LCD_Clear_loop
10
  
11
 sbi  PORTD, AB16  ;Adreßbit an
12
 clr  XL
13
 clr  XH
14
15
LCD_Clear_loop2:  
16
 st  X+, temp  
17
 cpi  XH, 0x40  ;80 kb = 81920 bytes (XH=0x40) gelöscht?
18
 brne  LCD_Clear_loop2
19
20
cbi  PORTD, AB16  ;Adreßbit aus

Wie man sieht, geht es um die Löschschleife. Da der Speicher 80 kb groß 
ist, brauche ich eine 17. Adressleitung (AB16), die ich vor der zweiten 
Schleife zuschalte.
Das Problem ist nun, daß die erste Schleife zwar normal durchläuft, in 
der zweiten aber bei XL = 1A wieder von 0 gezählt wird und ich somit in 
der Schleife hängen bleibe.

Kann mir das jemand erklären???
Herzlichen Dank im Voraus,
Bruno

von Karl H. (kbuchegg)


Lesenswert?

welcher µC ist das und wie ist die Hardware verschaltet?


>  cpi  XH, 0xFF  ;bis 0xFFFF gelöscht?

genau genommen bis 0xFEFF
denn nach der Erhöhung von 0xFEFF ist das XH das erste mal 0xFF und die 
Bedingung trifft das erste mal zu.

>  clr  XL
>  clr  XH
>
> LCD_Clear_loop2:
>  st  X+, temp

und du bist sicher, dass du beginnend bei 0 in den Speicher schreiben 
darfst? Bei den AVR _Attiny und AtMegas, liegen beginnend ab dieser 
Speicheradresse zb die Systemregister im Speicher. Unter anderem zb auch 
das Register XL.

von Mystik (Gast)


Lesenswert?

....funkt irgendein Interrupt dazwischen und und ändert dir XL auf 
0x00?

von Sascha W. (sascha-w)


Lesenswert?

Karl Heinz Buchegger schrieb:
> und du bist sicher, dass du beginnend bei 0 in den Speicher schreiben
> darfst? Bei den AVR _Attiny und AtMegas, liegen beginnend ab dieser
> Speicheradresse zb die Systemregister im Speicher. Unter anderem zb auch
> das Register XL.
und genau dazu passt
>> bei XL = 1A
denn dort liegt XL im Adressraum wird wird damit wieder auf Null 
gesetzt!

Sascha

von Bruno M. (brumay)


Lesenswert?

Herzlichen Dank für die Hinweise!

Da habe ich wieder mal um die Ecke gedacht!!!
Natürlich kann ich den Speicher nicht von 0 an beschreiben, deswegen 
habe ich ja vor der ersten Schleife das XL auf YMin gesetzt. Bei der 
zweiten Schleife habe ich dann nur noch an den LCD Controller gedacht 
und nicht mehr an den ATMega.

Damit stellt sich aber das Problem, daß ich nicht nur den Anfang des 
Speichers nicht erreichen kann, sondern auch noch ein unerreichbares 
Loch im Speicherraum habe.

Oder gibt es dafür eine Lösung?

von Peter D. (peda)


Lesenswert?

Bruno M. schrieb:
> Oder gibt es dafür eine Lösung?

Man teilt das externe RAM in Häppchen von 32kB und läßt A15 des MC 
permanent auf high.
D.h. Du brauchst 2 IOs als A15, A16 des RAM.

von Karl H. (kbuchegg)


Lesenswert?

Bruno M. schrieb:

> Damit stellt sich aber das Problem, daß ich nicht nur den Anfang des
> Speichers nicht erreichen kann, sondern auch noch ein unerreichbares
> Loch im Speicherraum habe.

Genau so sehe ich das.

> Oder gibt es dafür eine Lösung?

Vom Mega nicht A0 bis A15 abgreifen, sondern zb A15 ebenfalls auf einen 
dir zugänglichen Portpin legen. Wenn das nicht reicht, dann eben A14 
auch noch.

D.h. dein Bildspeicher liegt dann für dein Programm immer an denselben 
4k/8k/wasauch immer. Und mit den zusätzlichen "Adress"-leitungen wählst 
du aus, welche dieser Speicherkacheln im Moment in diesem 
Speicherfenster sichtbar sein soll. Deine Speicherkachel scheint dann 
für den µC an mehreren Adressen auf. Wenn das ein Problem ist, dann 
musst du zusätzlich noch aus zb dem originalen A15 so etwas wie einen 
Chip Select bauen, der den Zugriff auf den externen Speicher nur dann 
freigibt, wenn du tatsächlich auf eine Adresse >= 0x8000 zugreifst. 
Allerdings hängt das auch davon ab, wie das externe Memory Interface 
deines µC funktioniert und genau deswegen hab ich nach dem µC-Typ 
gefragt

Abgesehen davon sehe ich nicht viele Möglichkeiten, was du sonst noch 
tun könntest.

von Bruno M. (brumay)


Lesenswert?

Danke für die schnellen Antworten.

Das muß ich erst einmal verdauen, da es ja, wenn ich es richtig 
verstanden habe, die komplette HW umschmeißt.

Bruno

von Bruno M. (brumay)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Allerdings hängt das auch davon ab, wie das externe Memory Interface
> deines µC funktioniert und genau deswegen hab ich nach dem µC-Typ
> gefragt

Sorry, habe ich erst jetzt gelesen.

Ich arbeite mit einem Mega162.

von Peter D. (peda)


Lesenswert?

Bruno M. schrieb:
> Das muß ich erst einmal verdauen, da es ja, wenn ich es richtig
> verstanden habe, die komplette HW umschmeißt.

Nicht unbedingt.
IMHO kann man den A15-Pin vom Bus abkoppeln und dann als normalen IO 
benutzen.

von Karl H. (kbuchegg)


Lesenswert?

Bruno M. schrieb:
> Danke für die schnellen Antworten.
>
> Das muß ich erst einmal verdauen, da es ja, wenn ich es richtig
> verstanden habe, die komplette HW umschmeißt.

Ja, das soll vorkommen, wenn man sich das im Vorfeld nicht richtig 
durchdenkt.
Ist aber nicht so schlimm. Mit einem Teppichmesser und Draht ist es 
behebbar.

> Ich arbeite mit einem Mega162.
1
The XMEM interface will autodetect
2
whether an access is internal or external.

Gut. Ein 'Problem' weniger.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz Buchegger schrieb:

> Gut. Ein 'Problem' weniger.

Ich nehms zurück, nachdem ich im Datenblatt das Kapitel über XMEM etwas 
genauer studiert habe.
http://www.atmel.com/Images/Atmel-2513-8-bit-AVR-Microntroller-ATmega162_Datasheet.pdf
zb Seite 33

Noch verstehe ich nicht, warum die das so gemacht haben.
Wenn du das als Bildspeicher benutzen willst, dann hast du da noch 
einiges an Arbeit vor dir, weil es ja nicht egal ist, welche Zelle jetzt 
über welche konkrete Adresse angesprochen wird. Bei dir muss die 
Reihenfolge im Speicher ja stimmen.

von Bruno M. (brumay)


Lesenswert?

Das habe ich jetzt nicht verstanden.

Die Darstellung auf Seite 33 ist ja nur anwendbar wenn ich einen 
externen 32k Speicher habe und den voll nutzen will. Wenn ich den 
gesamten Adressraum bis 0xFFFF ausnutze funktioniert das ja sowieso 
nicht.

von Karl H. (kbuchegg)


Lesenswert?

Ja, du hast recht. Hab eine weile gebraucht, bis ich raus hatte, wie 
Atmel die Sache meint. Mich hat da das Hin und Her über 0x8000 bus 
0x84FF verwirrt.

Ich denke Peter hat recht. A15 nimmst du nicht vom XMEM Interface 
sondern du kontrollierst das selber, so wie du auch A16 selber 
kontrollierst.
mit diesen beiden zusätzlichen I/O Pins unterteilst du deine maximal 
möglichen externen 128k praktisch gesehen in 4 Bänke zu je 32kB, die du 
jeweils durch Einstellen der Banknummer in deinen privaten A15/A16 Bits 
auswählst und die du ab 0x8000 ansprechen kannst.
Du musst dazu noch nicht mal eine Hardware-Änderung machen, sondern 
brauchst nur dem XMEM Interface das A15 am Port C abkoppeln und selber 
die Kontrolle über PC7 übernehmen.

Peter hat das schneller verstanden als ich. :-)

von Bruno M. (brumay)


Lesenswert?

Dann will ich mal mein Glück versuchen.

Bruno

von Bruno M. (brumay)


Lesenswert?

Ich muß mich noch einmal melden.

Ich habe die Vorschläge zur Speicherverwaltung umgesetzt und ich meine 
es funktioniert auch. Zumindest teilweise. Trotzdem habe ich ein 
Problem. Zuerst der von mir benutzte Code:
1
;**********
2
;Speicherorganisation:
3
;externes RAM beginnt bei 0x8000 = (1)000000000000000
4
;mit AC7 = 0 wird daher Speicher 0 adressiert, Speicherraum geht damit bis 0x7FFF =(0)111111111111111
5
;dann muß AC7 auf high um Speicherraum bis 0xFFFF zu erreichen,
6
;wird dann AB16 auf high gesetzt, sind auch die oberen Bereiche bis 80 KByte (81920 Byte) zu adressieren. 
7
LCD_Clear:
8
  cbi    PORTC, 7
9
  ldi    XL, 0x00  
10
  ldi    XH, 0x80          ;externes RAM ab 0x8000, mit AC7 low beginnt Speicher damit bei 0
11
  clr    temp
12
  ldi    temp1, 0x00          ;Ende ATMega Speicher (0xFFFF) wenn XH = 0xFF + 1
13
  rcall  LCD_Clear_loop
14
15
  sbi    PORTC, 7
16
  ldi    XL, 0x00  
17
  ldi    XH, 0x80        
18
  rcall  LCD_Clear_loop
19
20
  cbi    PORTC, 7
21
  sbi    PORTD, AB16          ;Adreßbit an
22
  ldi    XL, 0x00  
23
  ldi    XH, 0x80        
24
  ldi    temp1, 0xC0          ;Oberste Adresse =   0x14000  = (1)(0)100000000000000, XH damit 0x40 + 0x80= C0  
25
  rcall  LCD_Clear_loop
26
27
  cbi    PORTD, AB16          ;Adreßbit aus
28
  rjmp  Linie
29
  ;rjmp  ASCII
30
31
LCD_Clear_loop:
32
  st    X+, temp  
33
  cp    XH, temp1
34
  brne  LCD_Clear_loop
35
  ret
36
  
37
Linie:
38
  cbi    PORTC, 7
39
  cbi    PORTD, AB16
40
  ldi    XL, 202
41
  ldi    XH, 0x80          ;Start externes RAM
42
43
Linieloop:
44
  ldi    temp, 0xFF
45
  st     X, temp
46
  adiw  XL,1
47
48
  cpi    XL,238
49
  brne  Linieloop
50
51
  rjmp  Linie

Zur Umgebung: Ich steuere mit dem AT162 einen LCD Controller S1D13705 
von Epson an. Ausgabe auf einem Farb-LCD 320x240

Mein Problem:
Entsprechend Code wird in Zeile 5 eine Linie ausgegeben. Das geschieht 
auch, aber im unteren Drittel des LCDs erscheint die Linie noch einmal!

Ich kann einfach keine Erklärung dafür finden. Auch ein HW-Problem 
schließe ich nicht aus, aber auch dafür finde ich keine logische 
Erklärung.

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.