Hallo,
ich verwende den LPC2148 auf dem Evaluationsboard MCB2140 von Keil. Zum
Debuggen verwende ich das Programm Hitop 5.
Mein Problem ist, dass mein Programm nach Aufruf der Startfunktion nicht
mehr aus der ISR heraus springt, sondern immer wieder nach abarbeiten
der ISR wieder in die selbige springt.
Hier der Code im wesentlichen:
1
intmain(void)
2
{
3
4
i2cMaster_init();
5
while(1)
6
{
7
start(0x90);
8
}
9
return0;
10
11
}
12
13
voidi2cMaster_init(void)
14
{
15
MEMMAP=0x2;
16
17
PINSEL0=0;
18
PINSEL1=0;
19
PCONP|=(1<<I2C_POWER);
20
21
PINSEL0|=(1<<SCL0_PINSEL)|(1<<SDA0_PINSEL);//SDA und SCL Pins auf I2C-MOdus
Hmmm...
gehören die "breaks" nicht jeweils ausserhalb der geschweiften Klammern?
Ich kennne jetzt den LPC nicht, aber hast Du, wenn benötigt das
Interrupt-Flag vom I2C zurückgesetzt? Bei manchen Controller ist das
händisch zu machen.
Steffen
M. D. schrieb:
> Mein Problem ist, dass mein Programm nach Aufruf der Startfunktion nicht> mehr aus der ISR heraus springt, sondern immer wieder nach abarbeiten> der ISR wieder in die selbige springt.
Üblicherweise bedeutet das, dass die interruptauslösende Bedingung dann
nicht beseitigt wurde.
Meistens ist es so, dass eine ISR diese Bedingung automatisch
zurücksetzt. Aber gerade bei Kommunikations-ISR ist es oft so, dass man
das Datenregister des Bausteins auslesen muss, damit das entsprechende
Interrupt-Flag gelöscht wird.
Wie das bei deinem Prozessor ist, weiß ich nicht. Aber einen Versuch
wäre es wert.
Sprich: Wenn dir der Aufruf der ISR schon anzeigt, dass ein Byte
eingetrudelt ist, dann solltest du es auch abholen. Selbst dann, wenn
ein anderes Flag dir eine Fehlerbedingung anzeigt.
Hat nur indirekt mit Deinem Problem zu tun, aber dennoch:
Mit festen Zuweisungen solltest Du vorsichtig sein, wenn Du eigentlich
nur Bitoperationen machen willst. Es funktioniert zwar schon, wenn man
weiss was man tut. Aber meist gibts weniger Fehler, wenn Du Bits
folgendermassen setzt oder löschst...
Beispiele:
SIC Bit setzen
I20CONCLR |= (1 << SIC);
SIC Bit löschen
I20CONCLR &= ~(1 << SIC);
Johnny schrieb:
> Mit festen Zuweisungen solltest Du vorsichtig sein, wenn Du eigentlich> nur Bitoperationen machen willst.
Ne, das stimmt schon, der ARM7 hat spezielle Löschregister.
Eine 1 löscht, eine 0 hat keinen Effekt.
Das ist als Krücke gedacht, da er nicht wie der ARM-Cortex-M3
Bitoperationen kann.
Peter
Ok ,habe das mit dem break geändert, ändert aber leider nichts
am Programmablauf.
Zu |= kann ich nur sagen, dass ich vor diesem Problem faat 10 Tage an
einem anderen Problem hing und nichts lief, da ich |= verwendet habe bei
einem Register dass man nur schreiben kann und ich deswegen Probleme
ohne Ende hatte. Deswegen bin ich damit vorsichtig.
Aber ich will jetzt nicht in dieses Thema abschweifen.
Habe das Falg schon am Anfang der Rotunie gelöscht, nur habe ich dann
das Problem, dass das Statusregister, dass ich ja auslesen will,
verändert wird..
Ob die breaks in der Klammer sind oder draussen ist hier komplett
wurscht. Und die {} für die switch cases sind hier sowieso überflüssig,
werden nur benötigt, wenn man dort lokale Variablen definieren will.
Nur bringt es u.U. nichts, das SI Bit zu löschen, wenn der eigentliche
Grund für den Interrupt noch da ist. Es gibt ja mehr Zustände, als du in
der ISR berücksichtigst. Wenn du meinst, die seien sinnlos, dann
solltest du dennoch darauf reagieren, Daten abholen und wegwerfen,
Abbruch (Stop) erzwingen, ...
Noch etwas ist mir aufgefallen:
Erst wenn ich das SI-Flag lösche, werden die Änderungen sichtbar, sprich
bei Abhandlung des Falls "0x08" wird erst nach löschen Von Si, die
gesaendete Adresse am Oszi sichtbar.
> Die Werte die vorkamen, werden von meiner ISR abgehandelt.
Und wenn mal was anderes vorkommt als im Test soll das Programm qua
Vorschrift einfach hängen bleiben oder abstürzen?
Normalerweise müssten da auch ohne Fehler noch andere Stati kommen.
Beispielsweise wenn die Adresse raus ist und Daten fällig werden. Gibt
dazu ein paar schöne Tabellen im Manual (Tab148+).
Nein ,mir ist schon klar, dass das Programm so nicht optimal ist.
Aber ich meine in meinem konkreten Problemfall sehe ich ja, aus welchem
Interruptgrund die ISR ausglöst wurde und jetzt habe ich eben das
Problem dass ich nicht mehr aus der ISR heraus komme.
Ich habe auch schonmal was zu dem thema gesehen als ich das Problem noch
nicht hatte, habe es aber bisher noch nicht wieder gefunden...
dann werde ich mal weiter suchen.
Wäre dankbar für schnelle Hilfe,
Gruß
M. D. schrieb:
> Erst wenn ich das SI-Flag lösche, werden die Änderungen sichtbar, sprich> bei Abhandlung des Falls "0x08" wird erst nach löschen Von Si, die> gesaendete Adresse am Oszi sichtbar.
08/10 heisst ja nur, dass eine Start Condition komplett ist. Solange SI
nicht gelöscht wird ändert sich am Bus per Definition nichts. Siehe
Doku, steht da so drin. Und die Adresse hat er ohnehin erst als Reaktion
auf 08/10, wie sollte die also vorher auf dem Bus sichtbar werden
können?
Ich entschuldige mihc, ich habe auf die falsche Speicherstelle geschaut.
Also Si-Flag wird gelöscht, und Slaveadresse und Daten werden korrekt
ausgegeben, aber die ISR wird eben nie beendet.....
Ich hab jetzt mal die komplette ISR drin.
Ganz des Hauptproblem ist eigentlich, dass alles bis zum abarbeiten von
"0x28" Routine funktionert(Slaveadresse übertragen mit ACK), allerdings
ist der Satuscode nach dem abrbeiten der "0x28"-Routine ="0x10" und dass
die Daten nicht übertragen werden.
Wenn der Statuscode dann 0x10 ist, springt die ISR wieder in die "0x10"
Behandlung.
char buf_config[]={0xAC,0x00,11};
char buf_start[]={0xEE,11};
char buf_read[]={0xAA,11};
char receice_buf[1];
int count = 0, i = 0;
int slaveaddr = 0;int data = 0;
M. D. schrieb:
> case 0x08:> I20DAT = slaveaddr; //addr> temp1 = I20DAT; <============
Wozu ist das denn gut?
Wie sehen i2c_stop() und i2c_write() aus?