Forum: Mikrocontroller und Digitale Elektronik konzeptionelle Fragen C167CR LM


von Stephan (Gast)


Lesenswert?

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

von Max Murks (Gast)


Lesenswert?

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.

von Stephan (Gast)


Lesenswert?

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

von Peter D. (peda)


Lesenswert?

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

von Max Murks (Gast)


Lesenswert?

Vermutlich "existiert" kein RAM in der Allocation von deinen Daten. Dies 
erklärt auch, warum es in der Simulation geht.

von Stephan (Gast)


Lesenswert?

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

von Stephan (Gast)


Lesenswert?

@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

von Max Murks (Gast)


Lesenswert?

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!

von Stephan (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.