Hallo Zusammen,
Ich versuche gerade herrauszufinden wie Adresse des Sequence complete
Interrupt des ADC vom MC9S12C lautet. Also die Adresse im Speicher wo er
nach auslösen hinspringt. Hab das Datenblatt schon x-mal durchforstet
und es gelingt mir nicht.
Zudem stosse ich immer wieder auf Adressangaben wie "Module Base +
0x001" - Was ist die "Module Base"?
Danke für eure Hilfe!
Ok, Nachtrag.
Ich habe jetzt doch etwas gefunden, macht mich aber nicht wirklich
Schlauer. Es müsste laut Datenblatt diese Adresse sein, oder: 0xFFD2,
0xFFD3 ATD.
Ok, das sind 2 Speicherstellen aber wie passt da noch ein Jumpbefehl
davor? Oder ist da beim HCs12 nicht mehr nötig und ich bin noch etwas
Odlscool?
Des weiteren verstehe ich den Code eines Kollegen nicht welcher für
einen Timer-interrupt folgenden Code geschrieben hat:
1
voidinitTimer(void){
2
// timer enable, freeze while BDM
3
*((unsignedchar*)0x0fe2)=0x06;
4
*((void(**)(void))0x0fe3)=timer_interrupt;
5
TSCR1=0x80;// Timer enable
6
TSCR2=0x07;// Prescaler = 128 (1 timer tick every 16µs)
7
TCTL2=0x00;// TC2 disconnected from Pin
8
TIOS|=0x04;// TC2 is Output Compare
9
TIE|=0x04;// TC2 Interrupt enable
10
}
Ich dachte bissher immer die "0x0fe3" wäre die Adresse für den
Timmerinterrupt. Passt dan aber nicht mit der Tabelle im Datenblatt
zusammen.
Markus schrieb:
> *((unsigned char *) 0x0fe2) = 0x06;> *((void(**)(void)) 0x0fe3) = timer_interrupt;> Ich dachte bissher immer die "0x0fe3" wäre die Adresse für den> Timmerinterrupt. Passt dan aber nicht mit der Tabelle im Datenblatt> zusammen.
Wieso? Passt doch wunderbar:
> *((void(**)(void)) 0x0fe3) = timer_interrupt;
timer_interrupt wird wohl die aufzurufende Funktion sein. Deren Adresse
wird beginnend ab 0x0fe3 abgelegt. Der cast links sieht etwas seltsam
aus (eigentlich müsste es ein Stern alleine auch tun), ist aber dem
Datentyp nach ein Pointer auf eine Funktion.
> *((unsigned char *) 0x0fe2) = 0x06;
das wird dann wohl der 'Jump' sein. Schau doch mal ins Datenblatt deines
Prozessors welcher OpCode sich hinter 0x06 verbirgt.
Passt wunderbar? - Dann bin ich zu doof.
Im datenblatt steht was von Adresse 0xFFDE, 0xFFDF für Standard
timer overflow TMSK2 (TOI), das ist aber weit entfernt von 0x0FE3.
>das wird dann wohl der 'Jump' sein.
Richtig, ist ein Jump aber ich bin immer noch verwirrtt wegen der
Adresse. Der Code mit Funktioniert aber ich komm nicht dahinter wo mein
Kollege diese Adressangaben herhat.
Markus schrieb:
> Passt wunderbar? - Dann bin ich zu doof.> Im datenblatt steht was von Adresse 0xFFDE, 0xFFDF für Standard> timer overflow TMSK2 (TOI), das ist aber weit entfernt von 0x0FE3.>>>das wird dann wohl der 'Jump' sein.> Richtig, ist ein Jump aber ich bin immer noch verwirrtt wegen der> Adresse. Der Code mit Funktioniert aber ich komm nicht dahinter wo mein> Kollege diese Adressangaben herhat.
Jetzt bin ich verwirrt.
Dein Aussage:
"Ich dachte bissher immer die "0x0fe3" wäre die Adresse für den
Timmerinterrupt."
Und im Code schreibt er die Adresse einer Funktion namens
"timer_interrupt" nach 0x0fe3.
Beides mal die gleiche Adresse - was verwirrt dich daher?
Was soll da nicht passen? (OK, die Frage bleibt, warum der eigentliche
jump nach 0x0fe2 kommt, aber das kann ich dir nicht beantworten)
> Im datenblatt steht was von Adresse 0xFFDE, 0xFFDF für Standard> timer overflow TMSK2 (TOI), das ist aber weit entfernt von 0x0FE3.
Da geb ich dir recht. Aber ohne das Datenblatt ist das schwer zu
entscheiden.
Hallo Markus,
leg dir eine Vektortabelle an und trage alle benutzten Interrupts dort
ein. Für nicht benutzte Interrupts legts du dir einen DummyIsr an.
Damit brauchst du solche Häßlichkeiten wie
*((unsigned char *) 0x0fe2) = 0x06;
*((void(**)(void)) 0x0fe3) = timer_interrupt;
nicht, das erledigt dann dein Linker. Bei deinem manuellem Konstrukt
mußt du bei jeder Änderung diese Adressen kontrollieren und anpassen.
Dann muss die Vektortabelle nur noch an die richtige Adresse des FLASH
gelinkt werden. Bei den Frescale S12 ist das normalerweise ganz am Ende.
Im Anhang mal ein Beispiel des S12C32.
Zu deiner Frage mit dem Module Base: Du kannst bei dem S12 das RAM, das
EEPROM und die Register verschieben, damit ändert sich dann (natürlich)
die Module Base Adresse und du mußt die Registeradressen anpassen.
>Beides mal die gleiche Adresse - was verwirrt dich daher?
Mich verwirrt dass im Datenblatt etwas anderes steht und ich die Adresse
"0x0fe3" dort niergens finden kann. Der Code funktioniert aber dennoch.
>Da geb ich dir recht. Aber ohne das Datenblatt ist das schwer zu
entscheiden.
Wäre jemand so nett und schaut mal ins Datenblatt des MC9S12C und sagt
mit die Adresse für den "Sequence complete
Interrupt" des ADC? - Danke
>leg dir eine Vektortabelle an und trage alle benutzten Interrupts dort
ein.
Ist im Prinzip eine gute Idee aber dazu muss ich erstmal Verstehen wo
den die Adressen der Interrupts liegen um so eine Tabelle anzulegen.
Aber da bin ich im Augenblick noch nicht angekommen.
Was ich auch noch nicht verstehe: Im Datenblatt stehen 2 Adressen - Wie
pack ich da eine neue Adresse und einen Jump Befehl rein - Ich dachte
ich bräuchte da zumindest 3 freie Speicherstellen?
Danke Euch!
OK, dir fehlt ein klein wenig das Verständis, wie das mit den Interrupts
so abläuft.
DIe Adresse des Sequence Complete Interrupts ist 0xFFD2, d.h. an dieser
Adresse (16 Bit! 0xFFD2 und 0xFFD3) steht wo der erste Befehl der ATD
Sequence complete Service Routine im Adressraum steht. Oder anders
formuliert, der Inhalt diese Adresse zeigt auf eine andere Adresse,
nämlich die der Serviceroutine.
Du brauchst hier also nicht mit Gewalt ein Jump hinzuschreiben, das geht
dann immer schief.
Soweit verstanden?
Deshalb eine Vektortabelle anlegen, so ungefähr wie ich sie gepostet
habe, Serviceroutine eintragen und den Rest vom Linken erledigen lassen.
>OK, dir fehlt ein klein wenig das Verständis, wie das mit den Interrupts>so abläuft.
Ja, ich hab noch wenig Erfahrung mit dem HCS12 und auch mit dem
GNU-Compiler.
Ich weis nur das es beim 80c535 3 Speicherstellen waren, eine für einen
"jmp" und 2 für die Adresse. Aber so wie ich dich verstehe ist der HCS12
da schon etwas weiter und springt automatisch an die Adresse die er an
0xFFD2 und 0xFFD3 findet. Bin halt schon etwas in die Jahre gekommen ;-)
Wie gesagt, auch mit dem Gnu-Compiler bin ich noch nicht wirklich
vertraut darum noch eine Frage zur Vectortabelle.
Funktioniert das so? Hab es in der GNU-Documentation so gefunden. Wird
(".vectors") mit der ersten Adresse der Vectortabelle automatisch vom
Compiler erstezt oder muss ich da noch etwas tun?
1
externvoid_start(void);/* entry point in crt0.s */
Hallo,
sieht gut aus. Sollte so funktionieren.
Der Ausdruck "( section (".vectors") )" markiert dieen Code als Sektion.
Diese Sektion wiederum gibt an, wo der Code hin gelinkt werden soll.
Deshalb muss im Linkerfile auch ein Label .vectors auftauchen und mit
der richtigen Adresse verknüpft sein.
So ist es zumindest bei Metrowerks, Cosmic oder anderen Compilern. Den
GNU kenne ich nicht, vermute aber mal, dass der auch so arbeitet.