Hallo zusammen ich bin ein Quereinsteiger, was die Programmierung von Mikrokontrollern angeht. Ich habe auch schon das Manual zu dem Controller durchgelesen (und auch einiges an Büchern), nur leider werd ich nicht so richtig schlau, was das ganze Speichermanagement angeht. Ich denke das ist auch so ziemlich das schwierigste Thema... Nun zu meinem Problem: Ich soll über den Port8 vier D/A Wandler ansprechen. Die Daten für diese Wandler kommen über einen Can Bus. Das ganze ist auf einem entsprechenden board untergebracht, dessen Namen ich nicht genau kenne, alle Anschlüsse usw sind halt auf diesem Board. Um die D/A Wandler korrekt anzusprechen muss man über jeweils vier Pins des Port8 ein bestimmtes Timing Schema realisieren: - Pin0 ist der Clock - Pin1 sind die Daten (serrielle Ausgabe) - Pin2 ist ein so genannter Load Device Ausgang - Pin4 bis Pin7 sind die Chip Select Ausgänge, die den entsprechenden D/A Wandler ansprechen Das ganze Funktioniert auch schon recht gut, ich habe es mittels einer Interrupt Routine und dem Timer0 realisiert. Das Problem ist nun, dass die Daten, die serriell ausgegeben werden sollen, in einer speziellen Endlosfunktion gelesen werden, die die CAN Kommunikation realisiert. Das ganze CAN Lesen und Schreiben ist schon realisiert, ich soll meine Funktionalität dann einfach nur in dieses Zielsystem integrieren. Wenn ich nun die Ausgabe der gelesenen Daten über die Interruptroutine starte stehen selbige nat. nicht mehr zur Verfügung, da sie ja nur in der Funktion bekannt sind. Ich versuche nun vor meiner Ausgabe die Daten in entsprechende globale Variablen zu kopieren, damit sie auch in der Interruptroutine zur Verfügung stehen. Und genau hier setzt mein Problem an... Ich schaffe es nicht die globalen Daten auszuwerten. Das ganze wird noch etwas verrückter, weil ich schon eine globale Variablen habe, mit denen es funktioniert. Das Problem ist, dass das genau die Variablen sind, die nur in der Funktion zur Verfügung stehen. Im Zielsystem wird es diese nicht geben. Dies ist die Definition meiner globalen Variablen: CAN_DATA_T idata data; //Daten Strucktur, in der die Candaten gespeichert werden, mit diesen Variablen geht es BYTE idata daten[4];// Variable in die die Daten geschoben werden sollen int idata schieb; //Schiebevariable um das aktuelle Bit für die Serrielle Ausgabe zu selectieren Im Simulator funktioniert das ganze übrigens wunderbar, egal welche Variable ich nehme. Ich bin mir eigentlich ziemlich sicher, dass das ganze mit der Speichermap zusammenhängt, und da komme ich einfach nicht weiter. Hat hier jemand einen Tip, wo ich gute Informationen wie und warum ich die Speichereinstellungen vornehmen muss. Externer, Interner Speicher??? In welchen Speicherbereich schreibe ich was, und wie steuere ich das??? Woher weiss ich wieviel Speicher ich für Daten und Code brauche, wohin kommt das dann??? Meine momentane Speichereinstellung: (aus dem Zielsystem entnommen) NCODE (0x000000-0x00DFFF), NCONST (0x00C000-0x00DFFF), NDATA (0x400000-0x403FFF), NDATA0 (0x400000-0x403FFF), FDATA(0x404000-0x40FFFF), FDATA0(0x404000-0x40FFFF), XDATA(0x404000-0x40FFFF), XDATA0(0x404000-0x40FFFF) Ich habe mich schon erfolgreich durch das ganze Thema Interrupts, Timer, Comperatoren, Ein/Ausgabe usw gekämpft, aber mit dem Speicher komme ich einfach nicht klar. Ich brauche dringend Hilfe!!! Ich bedanke mich im Voraus für die hoffentlich zahlreichen Antworten. mfg Stephan
Es ist kein Problem des Speichermanagement, sondern Dein Compiler optimiert den Code und entfernt "nicht verwendete Variablen". Deklariere Deine "entsprechende globale Variablen" volatile, dann gehts.
Hallo danke erstmal für den Hinweis. Allerdings scheint es nicht ganz so einfach zu sein... Hier nocheinmal genauer was ich erreichen will: //Variablendefinition volatile unsigned char idata daten[4]; sbit datenpin = P8^1; //Interruptfunktion void serrielle_ausgabe() interrupt 0x20 //interrupt von timer0 { for (i=0; i<=8; i++) { datenpin = daten[0] & i; //Bitweises ausgeben } } //kopieren der daten void daten_formatieren(CAN_DATA_T data) { daten[0]=data.data[3] } //can überwachungsfunktion void can_test() { CAN_DATA_T data; data.data[3] = 0xAA; //beispielhaft für das Lesen der Daten vom Canbus daten_formatieren(data); T0R = 1; while(1) {} } //main void main() { /* Timer und Portinitialisierungen */ can_test; } Ich will also die Daten, die in der Funktion "can_test" anfallen in eine Globale Variable kopieren um sie in der Interruptfunktion "serrielle_ausgabe" ausgeben zu können. Allerdings klappt das Kopieren der Daten ums verrecken nicht. Weder volatile, noch sonst irgendwas bringt hierbei das gewünschte Ergebnis. Weiss jemand wo mein Fehler liegt? So langsam bin ich echt am verzweifeln... Der hier angegebene Code ist übrigens nur beispielhaft, Logik und Syntax sind nicht 100%ig richtig. Prinzipiell sollte aber rüberkommen was der Code bewirken soll. Ich bin für jede Hilfe dankbar. mfg Stephan
Das Daten übergeben sieht korrekt aus, nur serrielle_ausgabe() ist totaler Mumpitz. Du mußt noch den Taktpin pulsen und das Byte schieben. Ich würde dafür ne lokale Variable (= Register) nehmen, das geht schneller, weniger Code und zerstört nicht daten[0]. Peter
Vermutlich "existiert" kein RAM in der Allocation von deinen Daten. Dies erklärt auch, warum es in der Simulation geht.
Hallo Natürlich ist die Funktion "serrielle_ausgabe" in der hier dargestellten Form völliger Unsinn... Sie war ja nur beispielhaft angegeben. Hier vielleicht nocheinmal etwas genauer: sbit clock = P8^0; //pin, an dem der clock ausgegeben wird volatile int idata schieb = 0; //schiebevariable um das aktuelle datenbit zu selektieren void serrielle_ausgabe() interrupt 0x20 { unsigned char y = 0x80; y >> schieb; /*an dieser stelle wird die Selektionsvariable um genau soweit geschoben, welches Bit gerade ausgegeben werden soll*/ if (/*hier wird die schiebevariable abgefragt*/) { datenpin = daten[0] & y; } clock = !clock; schieb++; } Die "schieb" Variable dient halt dazu die Interrupts mitzuzählen um jeweis feststellen zu können, an welcher Stelle sich die Ausgabe befindet. Du schreibst daten[0] würde zerstört??? Wie das denn und wo? Wie gesagt, prinzipiell funktioniert die serrielle Ausgabe ja, nur irgendwie nicht mit der weiter oben angegebenen Form des datenkopierens. Woran liegt das? mfg Stephan
@Max Murks; es existiert kein RAM in der Allocation... genau sowas dachte ich mir ja, nur hab ich genau davon keine Ahnung. Kannst du mal genauer erklären was das (für mich ziemlich kryptische) bedeutet. Man kann ja festlegen wo die Daten hinkommen sollen, nur wohin? Ich weiss ich nerve, aber danke trotzdem nochmal für eure Mühe... mfg Stephan
1. Hardware analysieren 1.1 FLASH Größe, RAM Größe 1.2 Welche CS-Signale zu welchen Speicherbausteinen (CS0=FLASH; CS1=RAM) ? 1.3 Boot Info Hardware Codiert (P0H, P0L) über Pullup Widerstände 2. Software Konfiguration 2.1 SYSCON gemäß Hardware konfigurieren (siehe Datenblatt) 2.2 BUSCONX gemäß Hardware konfigurieren (siehe Datenblatt) 2.3 ADDRSELX gemäß Hardware konfigurieren (siehe Datenblatt) 3. Compiler/Linker/Locater Einstellungen 3.1 ROM-Bereich festlegen (LocMemRom=0h-01FFh,10000h-2FFFFh) 3.2 RAM-Bereich festlegen (LocMemRam=0F000h-0F1FFh, 30000h-3FFFFh) Kurz gesagt: Hardware, Firmware und Linker/Locater müssen aufeinander abgestimmt werden!
So, nach ziemlich langen Manuelrecherchen habe ich jetzt folgende Informationen bekommen: Der Chip ansich besitzt insgesammt 4k internen Speicher, 2k internal RAM und 2k XRAM. zusätzlich sind extern ein 1MB grosser Flashspeicher angeschlossen und ein 256kb grosser SRAM. Der Flashspeicher läuft wohl über die CS0 Leitung und der SRAM über die CS1 Leitung... Der Flash ist mit 512 * 16bit definiert, und der SRAM mit 256 * 16bit. Über die Boot Info habe ich nichts herausbekommen, dazu steht nichts im Manual des Minimoduls, was allerdings drin steht, ist, das es keine Verdrahtung des Port0 nach aussen gibt... Damit komme ich zu folgender Konfiguration: SYSCON: 0000`0000`0001`0100 => 0x14h, XPEN = enabled und watchdog aus BUSCON0: 0000`0110`1000´1110 => 0x068Eh, 16bit multiplex, tristate zeit, verzögerte Aktivierung, Verlängerung des des ALE Signals und 1 Waitstate BUSCON1: ist gleich BUSCON0 ADDRSEL1: 0000`0010`0000`0110 => 0x0206h für 256kb Speicher und eine Startadresse von 0x20h... Ich denke, das die Konfikuration damit halbwegs in Ordnung ist, jetzt bleibt nur noch die Linkereinstellung... Ich habe mit das jetzt so gedacht: NCODE (0x000000-0x00DFFF), NCONST (0x00C000-0x00DFFF), NDATA (0x200000-0x203FFF), NDATA0 (0x200000-0x203FFF), FDATA(0x204000-0x20FFFF), FDATA0(0x204000-0x20FFFF), XDATA(0x204000-0x20FFFF), XDATA0(0x204000-0x20FFFF) Ist das jetzt soweit richtig? Ich korrigiere, es scheint soweit richtig zu sein, denn es funktioniert... HURAAA, ich bedanke mich auf jeden Fall für eure Hilfe, ich habe hier genau die richtigen Anstösse bekommen, die mich letztendlich auf die richtige Spur gebracht haben... Nichts desto trotz bleiben noch ein paar Fragen, es wäre nett, wenn Ihr auch diese beantworten würdet: Was hat das mit ALE Signalen auf sich? Was ist das und warum sollte man es um eine TCL verlängern bzw. warum nicht? In der Speichermap ist in dem Adressbereich für den externen Speicher allerlei Zeugs angegeben... Was ist das genau, und woher weiss ich, wie gross der jeweilige Bereich sein muss? Ich bedanke mich jetzt schon für eure Antworten. mfg Stephan
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.