Ich will eine Steuerung bauen für das Einschalten bzw Ausschalten der
Heizung in der Wohnung, ueber MOD-GSM(also SMS Versand und
Auswertung).Dazu habe ich Olimex Platine mit Pi32MX220(40MHZ ->Fosc),
programmiere in C mit Pinguino IDE version x.4. Ich habe aus der
Dokumentation von Microchip rausgelesen, dass die Timer4 und Timer5
kann man zusammen schalten und daraus ein 32 Bit Timer bauen, ich will
mit dem Timer45 ein Interrupt auslosen, das hat schon mal nicht
funktioniert. Keine Ahnung warum hier ist mein C Code:
// define here the code to execute when an interrupt occure
21
void__attribute__((nomips16))Tmr5Interrupt(void)
22
{
23
24
digitalWrite(K,HIGH);
25
26
init_timer45();
27
}
28
29
voidinit_timer45(void)
30
{
31
32
T4CON=0x0;// Stop timer 4
33
T5CON=0x0;// Stop timer 5
34
T4CONSET=0x0008;// Enable 32 Bit mode pescaler 1:1,
35
// Internal clock source
36
37
TMR4=0x0;// Clear contents of the timer 4 and timer 5
38
39
PR4=0xDC3CBA00;// Load PR4 and PR5 with 32 Bit value
40
41
IPC5SET=0x00000004;// Set priority level 1
42
IPC5SET=0x00000001;// Set sub priority level 1
43
IFS0CLR=0x00100000;// clear the timer 5 interrupt status flag
44
IEC0SET=0x00100000;// enable timer 5 interrupt
45
T4CONSET=0x8000;//Start the timer
46
47
}
48
49
voidsetup(){
50
//run once:
51
pinMode(K,OUTPUT);
52
53
init_timer45();
54
}
55
56
voidloop(){
57
//run repeatedly:
58
//digitalWrite(K,HIGH);
59
}
Definitiv habe ich irgendwo ein oder mehrere Fehlern, nach meinen
Berechnungen soll Interrupt nach ca. 60 sec Portausgang K auf High
setzen, ist aber nicht der Fall. Danke für die Hilfe.
@Thomas
Nein hat nicht geholfen ich glaube es ligt an der Interrupt Vector
definition! Kennt sich jemand aus mit dem kalkulieren der Vectornummer
für Pic32, danke
Zu einem Compiler gibt es meistens auch ein Verzeichnis mit Beispielen,
die sollten eigentlich laufen.
Und wenn man die verstanden hat, kann man davon ausgehend seinen eigenen
Code schreiben.
Nur planlos rumraten bringt allgemein garnichts.
Ich würde auch nicht gleich mit nem 32Bit-Boliden anfangen, sondern nem
kleinen 8Bitter.
Die 40MHz sind für ne Heizungssteuerung etwa 1000-fach zu schnell.
@Peter
Danke für den vorschlag, ich habe leider schon die platine vom olimex
da, mit pic32mx, gerade die neue interrupt beispiele lassen sich nicht
mit pinguino ide übersetzen.
Um das ganze langsammer zu machen wollte ich die timer4 und timer5
zusammen schalten, damit ich auf 2^32 - 1, also ein 8byte wert in
timer45 setzen kann.
Leider wird die interrupt routine nicht ausgelost, led leuchtet nicht.
Also weiss ich nicht woran es liegen kann, aber danke für die
rückmeldung.
Ivan schrieb:> gerade die neue interrupt beispiele lassen sich nicht> mit pinguino ide übersetzen.
Du brauchst natürlich solche Beispiele, die zu Deiner Toolchain passen.
Ansonsten schmeiß die Toolchain weg und nimm eine passende.
@Peter
ich finde kein beispiel wo ich zwei timer 2 und 3 bzw. 4 und 5 zu einem
schalte und dann mit timer23 bzw. timer45 interrupt auslose. In meiner
anwendung möchte ich die zwei priorisierten interrupts laufen lassen den
1 interrupt fürs abholen der sms und den zweiten zum steuern der
portsausgänge und zeitberechnung. Das abholen der sms funktioniert
bereits, aber wenn ich dazu timer45 nehme, dann geht es nicht mehr.
Interrupt wird nicht durch timer45 ausgelost. Keine ahnung warum? Werde
dankbar für jeden hinweis.
Die Initialisierung für Timer45 ist in Ordnung.
Ob die Initialisierung von der IPC, IFS und IEC Register OK ist habe ich
nicht überprüft, wie auch die Interruptroutinen selbst - ziemlicher
Aufwand um einen Timerinterrupt zu Händeln ( ich verwende MPLAB/MPLABX
und dem C32/CX32 - da gibt es aussagekräftige Funktionen bzw. Macros
dafür)
z.B.
void __ISR(_TIMER_1_VECTOR, IPL5SOFT) Timer1Handler(void)
{
mT1ClearIntFlag();
LATBINV = 0x00008000; //Ausgangssignal für Testzwecke erzeugen
}
macht genau das was du machst - nur eben Timer1, Priority=5 und ein
anderer Pin für die LED.
btw: Warum Initialisierts du in der Interruptroutine jedesmal Timer45
aufs neue?? Das Löschen des entsprechenden Interruptflags reicht völlig.
Ivan schrieb:> ich finde kein beispiel wo ich zwei timer 2 und 3 bzw. 4 und 5 zu einem> schalte und dann mit timer23 bzw. timer45 interrupt auslose.
Dann nimm doch erstmal ein Beispiel für einen Timer und bring das zum
Laufen.
Du kannst dann im Interrupt einfach eine Variable hochzählen.
Man muß nicht alle Features nehmen, nur weil sie möglich sind.
Ich bin mir aber sicher, im Datenblatt werden die Unterschiede
beschrieben sein, so viele können das ja nicht sein.
@Chris
Hallo und danke zuerst für den hiweis, ich werde heute abend
MPLAB/MPLABX
und den compiler C32/CX32 ausprobieren, vielleicht bringe ich es zum
laufen mit diesem tool. Ich fand das pinguino ide ziemlich komfortabel,
aber alles hat sein preis.
Warum ich timer45 neu initialisiere? Hm, ich war schon ziemlich
verzweifelt, und dachte, wenn es nicht beim ersten durchlauf klappt dann
... , also war nicht sicher ob der timer4 und timer5 laufen, habe kein
simulator oder so was.
Ich probiere heute den neuen weg und melde mich noch mal. Danke!!!
.....PR4 = 0xFFFFFF00;
Keine Ahnung wie der Controller konfiguriert ist, aber wenn der mit FRC
8MHz Takt läuft PBCLK 1:1 ist, dann dauert es 4294967040 * 0,125µs bis
der Interrupt ausgelöst wird..das sind 536 Sekunden bzw. 9 Minuten
Und das hier:
void __ISR(_TIMER_45_VECTOR, IPL5SOFT) Timer45Handler(void) //Priority=5
....
IPC5SET = 0x00000006; // Set priority level = 6
passt auch nicht so recht zusammen - entweder 5 oder 6 !
@Chris
Danke für die antwort, war schon zu spät wo ich das ganze zusammen
geschrieben habe, konzentration war ganz unten. Ja, den fehler sehe ich
auch, kann erst heute abend neu ausprobieren.
Habe noch eine frage Chris, da mein englisch nicht so gut ist, wie muss
man richtig den IPLX für irgendein timer wählen, bin mit der tabelle von
microchip nicht klar gekommen. Wenn du mir das kurz erklären kannst wäre
schön.
Danke.
IPLx{mode} legt fest auf welche Weise die Register bei Einsprung in die
Interruptroutine gesichert werden.
IPLxSOFT: Sichert/Wiederherstellung die Register mit PUSH/POP Befehle
auf den Stack - langsamste Methode
IPLxSRS: Sicher die Register in ein "Shadow Register Set" mit einem
einzigen Befehl - schnellste Methode, da es aber nur 1 solches
Registerset gibt (ev. gibt es mehrere, aber da müsste ich erst
nachsehen!?) kann darüber nicht x-beliebig verfügt werden.
IPLxAUTO: erzeugt zusätzlichen Code welcher vor der Registersicherung
testet, ob SOFT oder SRS verwendet werden kann/muss.
IPLx{mode} kann man auch weglassen, dann wird AUTO angenommen.
(nur so im Groben, wies exakt funkteoniert habe ich auch nicht im
Kopf..ist im XC32-Compiler manual genauer beschrieben)
Das "x" in IPLx{mode}...musst du selbst entscheiden wie wichtig,
dringlich, etc. dein Timerinterrupt gegüber anderen Interruptquellen
ist.
Muss dann aber mit den Einstellungen in den IPCx Registern
übereinstimmen!
// Wait until the SMS indicator string is received
60
x=1000000;
61
while(x--){}
62
63
64
65
charf=0;
66
charc;
67
68
x=1000000;
69
70
do{
71
72
73
PORTCbits.RC7=1;
74
//PORTCbits.RC7 = 0;
75
if(f<2){
76
c=UARTGetDataByte(UART2);//ReadUART2();
77
// Skip the <CR><LF> characters at the beginning of the string
78
if(!(c==0x0d||c==0x0a)){buffer[f]=c;f++;}
79
80
c=UARTGetDataByte(UART2);//ReadUART2() ;
81
if(!(c==0x0d||c==0x0a)){buffer[f]=c;f++;}
82
83
}else{
84
c=UARTGetDataByte(UART2);//ReadUART2() ;
85
buffer[f]=c;f++;
86
}
87
88
}while(c!='K');
89
buffer[f]='\0';
90
PORTCbits.RC7=0;
91
92
93
94
95
WriteString("AT+CMGDA=\"DEL ALL\"\r\n");
96
}
97
return0;
98
}
99
100
101
// helper functions
102
voidWriteString(constchar*string)
103
{
104
while(*string!='\0')
105
{
106
while(!UARTTransmitterIsReady(UART2))
107
;
108
109
UARTSendDataByte(UART2,*string);
110
//putsUART2(*string);
111
string++;
112
113
while(!UARTTransmissionHasCompleted(UART2))
114
;
115
}
116
}
Nach meiner überlegung, wenn ich ein SMS mit inhalt 'K' sende muss die
led off sein, ist aber nicht der fall, wenn jemand helfen könnte würde
ich sehr dankbar
Tut sich gar nichts auf den UART Pins?
Das ist doch ein PIC32MX220xxxxx - oder??
Da sind die Pins für UART, SPI, I2C nur über PPS (Peripheral Pin select)
zugänglich.
Die Beschreibung dafür findet sich im PIC32MX1xx/2xx Manual (DS61168) ab
Seite 143.
Ich habe hier einen PIC32MX220F032B auf Lochraster mit MAX3232 aufgebaut
und die Zuordnung von RX/TX findet so statt:
// Zugriff auf PPS must erst freigeschaltet werden!!
SYSKEY = 0; // locked durch sinnlosen Wert
SYSKEY = 0xAA996655; // Key1 für unlock
SYSKEY = 0x556699AA; // Key2 für unlock
CFGCONbits.IOLOCK = 0;
// Peripheral pin select:
PPSInput(3,U1RX,RPB2); // RX auf RB2
PPSOutput(1,RPB3,U1TX); // TX auf RB3
// PPS-Zugriff wieder sperren
CFGCONbits.IOLOCK = 1;
SYSKEY = 0; // locked
Für dein Board musst du dir die entsprechenden PPSInput/PPSOutput
entsprechend abändern.
Trotzdem geht es nicht, die led an port RC7 ist konstant an, es liegt
bestimmt an der auswertung von character, oder die while schleife ist
nicht richtig oraniesiert. Ich habe übrigens :PIC32MX220F032D an dem
olimex board. Habe noch zusätzlich an dem Tx ausgang led angelegt(nicht
während der datenübertragung), die flimmert leicht, also tut sich da
was, hm ??
Hmmmm...der _UART2_VECTOR bedient 3 Interruptquellen, u.a. auch den
TX-Interrupt (was nr.3 ist weiss ich jetzt nicht auswendig, habe ich bei
mir aber auchnicht berücksichtigt...). Versuch einfach mal das TX-Int
Flag zurückzusetzen, also nach dem
if(INTGetFlag(INT_SOURCE_UART_RX(UART2)))
{
......
......
}
fügst du noch:
// TX Interrupt ohne Funktion
if ( INTGetFlag(INT_SOURCE_UART_TX(UART1)) )
{
INTClearFlag(INT_SOURCE_UART_TX(UART1));
}
ein.
@Chris
Also HW ist in ordnung, ich habe probiert noch ein gleichen board
(olimex pi32-pinguino-mx220) mit pinguino ide zu programmieren, das
programm nutzt nicht uart2 wie ich sonder uart1 und es funktioniert, µC
signaliesiert, dass die sms empfangen werden, ich werde probieren mein
mplab programm auf uart1 umzustellen, wieso geht es nicht über uart2?
Keine Ahnung auf die Schnelle.
Die beiden von mir geposteten Zeilen
......
// TX Interrupt ohne Funktion
if ( INTGetFlag(INT_SOURCE_UART_TX(UART1)) )
{
INTClearFlag(INT_SOURCE_UART_TX(UART1));
}
.....
hast du hofffentlich auf UART2 angepasst??