Im Manual zum XC8 Compiler steht, wie man Interrupts verwendet. Ist
glaube ich nicht so, wie du das gelöst hast (hab jetzt nicht
nachgeschaut). In den Fehlermeldungen steht ja schon, dass er einige
pragmas nicht kennt.
Noch ein Tipp: Wenn du globale Variablen in Interruptfunktionen
verwendest, deklariere sie als volatile.
Hallo,
danke für deine Antwort hab nachgeschaut und hat viel geholfen.
Aber wenn ich die variable als volatile deklariere bekomme ich folgenden
Fehlermeldungen:
Warning [359] C:\code.c; 63.14 illegal conversion between pointer types
pointer to volatile unsigned char -> pointer to unsigned char
ich brauche glaube ich zwei interrupts:
eins der mir meldet, dass der Master das read command gesendet hat weil
der Master verschiedene Daten senden kann und zwar jeder Zeit,
eins der das Laufen des gesamten Programms unterbricht und die daten
über SPI senden. ich habe dann die interrupts so geschrieben:
volatile unsigned char info[1] = { 0x00 };
volatile unsigned char data_send[4] = { 0xAB, 0x48, 0x69, 0x00};
void interrupt isrmssp2(void)
{
if(PIR3bits.SSP2IF && PIE3bits.SSP2IE)
{
getsSPI2(info, 1);
if(((unsigned char)info[0] & 0x60) == 0x20)
{
TMR0IF = 1;
TMR0IE = 1;
return;
}
}
}
void interrupt isr(void)
{
if(TMR0IF && TMR0IE)
{
TMR0IF = 0;
putsSPI2((unsigned char *)data_send);
return;
}
}
void main()
{
RCONbits.IPEN = 0;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
T0CONbits.T08BIT = 0;
T0CONbits.T0CS = 0;
T0CONbits.PSA = 0;
T0CONbits.TMR0ON = 1;
INTCON2bits.INTEDG0 = 1;
INTCONbits.GIE = 1;
}
aber wenn ich die empfangenen Daten des Masters anschaue, dann sind sie
falsch. Was mache ich bitte da falsch?
Ist das dein gesamtes Programm? Ich weiss nicht was passiert, wenn das
main verlassen wird. Also besser noch eine Endlosschleife einfügen.
Geht er in die richtige Interruptroutine rein, wenn der Master Daten
sendet? Du sagst, die Daten sind falsch. Was erwartest du und was kommt
raus? Wie stellst du die empfangenden Daten dar?
Es erscheint mir auch komisch, dass du das Timer0 Interrupt manuell
auslöst. Evt. geht dort etwas schief.
salade Poisson schrieb:> TMR0IF = 1;> TMR0IE = 1;
Müsste wohl heissen:
INTCONbits.TMR0IF = 1;
INTCONbits.TMR0IE = 1;
hallo,
wie kann ich merken dass daten über SPI liegen? brauche ich dafür einen
Interrupt zu programmieren der ausgelöst wird wenn daten über SPI
liegen?
salade Poisson schrieb:> brauche ich dafür einen> Interrupt zu programmieren der ausgelöst wird wenn daten über SPI> liegen?
Da gibt es irgendwo ein Bit in einem Register. Das wird gesetzt wenn
Daten über die SPI angekommen sind. Ist der entsprechende Interrupt
freigegeben wird er dann auch ausgelöst. Du kannst ihn aber auch sperren
und per Programm abfragen.
Generell ist es beim PIC alle Interrupts zu einer Adresse springen (die
zweite mal weggelassen). Beim Interrupt wird dann die Funktion die dort
beginnt ausgeführt. Alle freigegebenen Interrupts abzuarbeiten und die
Flags zurückzusetzen ist dann dein Job.
Hallo,
ich hab so ein problem:
ich wollte mein temperaturmesssystem kalibirieren. ich habe es gemacht
aber das problem ist wenn ich keine Daten über SPI empfange oder sende
dann funktioniert die Kalibrierung, aber wenn ich daten über SPI
empfange dann funktioniert die Kalibrierung nicht mehr. Ich brauche dann
eine neue Kalibrierung. Die SPI beeinflusst dann mein Ergebnis. Weiß
jemand der Grund dafüR
Deine Fragen oder Probleme sind wohl nur zu lösen, wenn du auch die
komplette Beschaltung deines uC veröffentlichst, insbesondere die SPI
Signale und alle dort angeschlossenen Komponenten.
Vermutlich kommt sich was irgendwie "in die Quere".
Evt. solltest du die Funktionalitäten SPI erstmal ohne Interrupt-Nutzung
herstellen. Ob für SPI der Interruptfunktionalität überhaupt sinnvoll
ist kann man erst sehen wenn man das komplette System sieht, und auch
die Datenraten bzw. Clockraten bekannt sind.
Für sporadische oder langsame (< 10 Hz) Abfrage eines Temperatursensors
würde ich das nicht über Interrupt machen.
Gruss
Hallo
war mein Fehler. Hatte falsche Daten gesendet deshalb hatte er falsche
Rechnungen durchgeführt. Meine frage ist wie kann ich mit dem Interrupt
daten Auslesen und sie in einem Puffer schreiben? Ich lese Daten aus
aber ich habe den Eindruck dass er Sie nicht speicher. Ich hab es wie
folgt gemacht:
unsigned char info[1] = { 0x00 };
unsigned char data_rcv[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; //{ 0x67,
0x68, 0x77, 0x7F, 0x00 };
unsigned char data_send[11] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00 };
void interrupt isr5(void)
{
if(PIR3bits.SSP2IF && PIE3bits.SSP2IE)
{
getsSPI2(info, 1);
switch(info[0] & 0x78)
{
case 0x60:
data_rcv[0] = info[0];
break;
case 0x68:
data_rcv[1] = info[0];
break;
case 0x70:
data_rcv[2] = info[0];
break;
case 0x78:
data_rcv[3] = info[0];
break;
default:
break;
}
if((( info[0] & 0x60 ) == 0x40 ))
{
switch(((info[0] >> 3 ) & 0x03))
{
case 0x00:
data[1] = data_send[0];
data[0] = data_send[1];
break;
case 0x01:
data[1] = data_send[2];
data[0] = data_send[3];
break;
case 0x02:
data[1] = data_send[4];
data[0] = data_send[5];
break;
case 0x03:
data[1] = data_send[6];
data[0] = data_send[7];
break;
default:
data[1] = data_send[8];
data[0] = data_send[9];
break;
}
putsSPI2(data);
info[0] = 0x00;
}
return;
}
}
zum sehen ob der slave die Daten empfängt hab ich folgendes main
geschrieben:
void main (void)
{
float temp = 14450.0;
unsigned char nun = 0x00;
unsigned char configdata[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
Set_SPI(2);
initPIC();
SSP2BUF =0;
RCONbits.IPEN = 0;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
PIR3bits.SSP2IF = 0;
IPR3bits.SSP2IP = 1;
PIE3bits.SSP2IE = 1;
for(unsigned int i=0; i<4; ++i)
{
num = ( data_rcv[i] >> 3 ) & 0x03;
switch(num)
{
case 0x00:
temp = temp / 2;
data_send[0] = ( signed int ) ( temp / 256 );
data_send[1] = ( signed int )temp%256;
break;
case 0x01:
temp = temp / 3;
data_send[2] = ( signed int ) ( temp / 256 );
data_send[3] = ( signed int ) temp%256;
break;
case 0x02:
temp = temp / 4;
data_send[4] = ( signed int ) ( temp / 256) ;
data_send[5] = ( signed int ) temp%256;
break;
case 0x03:
temp = temp / 5;
data_send[7] = ( signed int )Temperature%256;
break;
default:
temp = temp / 6;
data_send[8] = ( signed int ) ( temp / 256 );
data_send[9] = ( signed int )temp%256;
break;
}
}
}
}while(1)
continue;
}
Wenn ich data mit Null initialisiere dann führt er keine Rechnung aus
und er sendet nur dummi daten an Master. Aber wenn ich den mit gultigen
Informationen initialisiere dann macht er die Rechnungen und er sendet
die Daten an Master wenn gefordert.
ich brauche die Daten vom Master auszulesen weill ich Sie Später für die
Berechnung verwenden soll. Weißt du woran es liegt