Hallo, habe jetzt ein kleines Problem mit Bascom, für eine Sprachausgabe
verwende ich die Befehle Loadlabel für den Sprachbefehl (z.B. Ziffern
0-9, diverse Worte). Das Ganze geht wunderbar für Atmega644, allerdings
haben nur wenige Worte Platz. Jetzt möchte ich das Ganze erweitern und
habe einen Atmega1284P verwendet (128kB), doch loadlabel geht - wie ich
nach längerem Suchen entdeckt habe - nur bis 64k Adressraum. Was nun?
Kann ich die Speicheradresse irgendwie - vielleicht mit Assembler
ermitteln?
Hier zur Info der Programmcode:
1
Timer0_isr: '4000 Hertz
2
'Achtung Byt etc. Übergabevariablen nicht verwenden,
3
'da parallel ablaufende Prozesse
4
'daher auch alles raus aus Timer
5
Timer0 = Ctimer0preload 'zeitkritisch, daher am Anfang!
6
If Wrdsoundpos > 0 Then
7
Ti = Cpeek(wrdsoundpos) 'Bereits jetzt nächstes Sample in Variable holen
8
If Ti = 255 Then 'Endezeichen eines Wortes
9
Wrdsoundpos = 0
10
If Byttelpointer > 0 Then
11
Decr Byttelpointer
12
End If
13
Else
14
If Bittelpause = 0 Then
15
Ocr1al = Ti
16
End If
17
Incr Wrdsoundpos
18
End If
19
End If
20
If Byttelpointer > 0 Then
21
If Wrdsoundpos = 0 Then
22
Ti = Len(strtel) 'in strtel stehen die Wörter, zB. 012345,
23
Ti = Ti - Byttelpointer
24
Ti = Strtelbytes(ti + 1) 'strtelbytes=Overlay-Bytes zu strtel
25
Bittelpause = 0
26
Tccr1a = &B10000001 'Pin D5, OC1A, nicht invertiert, 8-Bit-...
27
Tccr1b = &B00001001 '...Fast-PWM, Timer1 ohne Vorteilung 8x
28
Select Case Ti
29
Case 48
30
Wrdsoundpos = Loadlabel(0) 'wrdsoundpos=Pointer ins Flash-ROM
31
'Hier stehen im Data-Bereich Bytes für 4kHz Sprachausgabe, Ziffer 0
Für den größeren Speicherraum benützt der ATMEGA1284
außer den X, Y, Z-Registern, die 16Bit breit sind,
noch ein zusätzliches Register. (Für die weiteren Adressleitungen)
Bascom kenne icht nicht, daher kann ich nicht sagen ob Du den
entstandenen ASM-Code ansehen kannst.
Dann könntest Du nämlich sehr schnell feststellen, ob Bascom
den Speicher überhaupt adressiert oder adressieren kann.
Den Namen dieses zusätzlichen Registers findest Du im Datenblatt bzw.
auch in der ASM-Hilfe vom AVR-Studio.
CPEEKH + CPEEK?
Dabei wird der Speicher allerdings in Seiten (Pages) zerlegt. Ob, wie
und wo Bascom Konstanten im Programmspeicher ablegt, müsstest du mit dem
Manual klären.
Oder ne gescheite Programmiersprache, in der es benutzbare Zeiger gibt.
Damit ließe sich dein Programm sicherlich eleganter formulieren, ohne
Gehirnzerknoten wegen Paging.
Sven P. schrieb:> CPEEKH + CPEEK?>> Dabei wird der Speicher allerdings in Seiten (Pages) zerlegt. Ob, wie> und wo Bascom Konstanten im Programmspeicher ablegt, müsstest du mit dem> Manual klären.>> Oder ne gescheite Programmiersprache, in der es benutzbare Zeiger gibt.> Damit ließe sich dein Programm sicherlich eleganter formulieren, ohne> Gehirnzerknoten wegen Paging.
Tja, die Zeiger gehen mir irgendwie schon ab - aber ansonst ist halt die
Syntax so einfach...
Aber dein Hinweis mit CPEEKH ist schon einiges Wert, ich könnte mir
vorstellen, dass ich den Speicherbereich dann hardcodiere, da ich als
Programmierer ja weiß, wo die DATA-Bereiche (in etwa) liegen. Also die
hinteren Data-Bereiche liegen dann auf Page 2 und ich muss mit Peekh
zugreifen. Ist halt nicht wirklich elegant, naja vielleicht wird Mark
noch den loadlabel-Befehl um einen loadlabelh erweitern.
Manfred S. schrieb:> Tja, die Zeiger gehen mir irgendwie schon ab - aber ansonst ist halt die> Syntax so einfach...
Naja, gerade das verstehe ich ja nicht. Du betreibst da im Wesentlichen
ja nur Bitfummelei -- auf die Möglichkeiten (insbesondere CONFIG) von
Bascom greifst du garnicht zurück.
Und so besteht dein Programmtext im Wesentlichen nur aus einer Seite
Fließtext von überflüssigen Zeichen, weil Basic halt so geschwätzig ist
:-)
So - Problem gelöst. Ich positioniere einfach mit Restore den
Data-Zeiger und lese dann die Bytes von der Position bis zur Endemarke
($FF) ein. Interessant ist nur, dass auch lookup nur mit 64k kann (habs
getestet), Restore aber problemlos mit den 128k zurechtkommt. Hier noch
der korrigierte Code..
1
Timer0_isr: '4000 Hertz
2
'Achtung Byt etc. Übergabevariablen nicht verwenden,
3
'da parallel ablaufende Prozesse
4
'daher auch alles raus aus Timer
5
Timer0 = Ctimer0preload 'zeitkritisch, daher am Anfang!
6
If Bitplayspeech > 0 Then
7
Read Ti 'Lese ab Restore-Zeiger Bytes für Sprachausgabe
8
If Ti = 255 Then
9
Bitplayspeech = 0
10
If Byttelpointer > 0 Then 'Ausgabe der Wörter nacheinander bis Ende
11
Decr Byttelpointer
12
End If
13
If Byttelpointer = 0 Then 'Ansage am Telefon bis lngtelselbstrpt wh.
14
If Lngtelselbstrpt > 0 Then
15
Byttelpointer = Len(strtel)
16
Decr Lngtelselbstrpt
17
Else
18
Tccr1a = 0 'Ton aus
19
Tccr1b = 0
20
End If
21
End If
22
Else
23
If Bittelpause = 0 Then 'Trick: Sprachausgabe leer für Pause
24
Ocr1al = Ti
25
End If
26
End If
27
End If
28
If Byttelpointer > 0 Then
29
If Bitplayspeech = 0 Then '1 Wort fertig ausgegeben?
30
Ti = Len(strtel)
31
Ti = Ti - Byttelpointer
32
Ti = Strtelbytes(ti + 1)
33
Bittelpause = 0
34
Bitplayspeech = 1 'Sprachausgabe des Wortes bei nächstem Timeraufruf
35
Tccr1a = &B10000001 'Pin D5, OC1A, nicht invertiert, 8-Bit-...
36
Tccr1b = &B00001001 '...Fast-PWM, Timer1 ohne Vorteilung 8x