Forum: Mikrocontroller und Digitale Elektronik Unerklärlicher Interrupt im Programm


von Benny B. (pen)


Lesenswert?

Hallo zusammen,
Ich arbeite gerade an einem größeren Projekt mit einem ATMEGA8515, 
programmiere in C und benutze das AVR Studio 4. Im Moment versuche ich 
über SPI einen DA-Wandler anzusteuern, doch dabei tauchte ein Problem 
auf.
Und zwar bleibt mein Programm immer an der gleichen Stelle "hängen", 
selbst wenn ich es simuliere(aber ohne JTAG). Lasse ich die Optimierung 
weg, klappts einwandfrei, ich frage mich nur, wo das Problem liegen 
soll. Erst einmal ein Ausschnitt:


void spi_init(void)
{
  DDR_SPI = OUTPUT;
  DDR_SPI &= ~(1<<DD_MISO);
  SPCR = (1<<SPIE)|(1<<SPE)|(1<<MSTR)|(1<<SPR1)|(1<<SPR0);
  SS_OFF;
  sei();
}


ISR(SIG_SPI)
{

}

uint16_t value(float da)
{
  uint16_t result = 0;
  da /= 0.002441;
  result = (uint16_t)da;
  return result;
}

void spi_send_2byte(uint16_t send)
{
  uint8_t sen = 0;
  sen = send >> 8;
  send &= 0xFF;
  SPDR = sen;
  while(!(SPSR & (1<<SPIF)));
  SPDR = send;
  while(!(SPSR & (1<<SPIF)));
}

void spi_send_dac(uint8_t cmd, float temp)
{
  uint16_t data = 0;
  data = value(temp);
  uint16_t send_dac = 0;
  cmd &= 0x0F;
  send_dac = cmd << 12;
  data &= 0x3FF;
  data <<= 2;
  send_dac += data;
  send_dac &= 0xFFFC;
  spi_send_2byte(send_dac);
}

Aus meinem Hauptprogramm rufe ich die Funktion spi_send_dac wie folgt 
auf:
spi_send_dac(0b0001, 0.02);
Die anderen beiden Funktionen werden dann ja innerhalb der Funktion 
spi_send_dac aufgerufen (eigentlich)...
Denn nach der Zeile
send_dac += data;
springt das Programm in die ISR, was ich mir nicht erklären kann, und 
die darauffolgende Zeile wird dann nicht mehr ausgeführt, bzw. bleibt 
das Programm dann in dieser Zeile stehen, was ich mir nicht erklären 
kann.
Ich hoffe, dass irgendwer eine Idee dazu hat!

von STK500-Besitzer (Gast)


Lesenswert?

>SPCR = (1<<SPIE)|

Wenn du in der ISR sowieso nichts machst, dann solltest du das (1<<SPIE) 
weglassen.

von Benny B. (pen)


Lesenswert?

Das Problem ist halt dann, dass ich ja beim Senden den Vergleich
    while(!(SPSR & (1<<SPIF)));
mache. Dazu brauche ich aber doch den SPIE, oder nicht?

von Karl H. (kbuchegg)


Lesenswert?

Benny B. schrieb:
> Das Problem ist halt dann, dass ich ja beim Senden den Vergleich
>     while(!(SPSR & (1<<SPIF)));
> mache. Dazu brauche ich aber doch den SPIE, oder nicht?

Du solltest dir angewöhnen, das Datenblatt deins Prozessors beim 
Programmieren irgendwo am Bildschirm zu haben und bei jedem Bit, das du 
setzt, die Beschreibung zu lesen

[quote]
• Bit 7 – SPIE: SPI Interrupt Enable
This bit causes the SPI interrupt to be executed if SPIF bit in the SPSR 
Register is set and the if
the global interrupt enable bit in SREG is set.
[/quote]

SPIE brauchst du nur dann, wenn du, ausgehend vom SPIF Bit, eine ISR 
ausführen lassen möchtest. SPIF ist also Voraussetzung dafür, dass SPIE 
irgendetwas bewirken kann. Aber ein nicht gesetztes SPIE Bit hat keinen 
Einfluss auf die Funktion von SPIF

von Benny B. (pen)


Lesenswert?

Na das hört sich sehr gut an!
Habe den SPIE nun weg gelassen und das Programm läuft einwandfrei 
soweit!
Vielen Dank für die schnelle und präzise Hilfe!

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.