Forum: Compiler & IDEs USI (SPI Mode): Daten von Slave liegen am Eingang (DI) an, aber USIDR ist immer Null.


von Bimbi (Gast)


Lesenswert?

Hallo,

ich versuche mit Hilfe des USI über SPI ein Wort zu empfangen. Der Slave 
erhält die passende Clk und CS, drauf antwortet er auch. Dies kann ich 
auf de m Oszi gut erkennen. Aber aus irgendwelchem Grund ist das USIDR 
immer Null. Ich habe direkt am DI (PB5) gemsessen, die Daten kommen an 
aber nicht im Register. PB5 ist als Eingang (also 0) im Main deklariert 
worden.

Ich finde den Fehler nicht. Der Slave antwortet doch so schön... :-(

Hier die SPI-Funktion. Zum Test habe ich die Ergebnisse im EEPROM 
abgespeichert.
1
uint16_t SPI_Transceive(unsigned char byte)
2
{
3
  uint16_t daten=0;            
4
  USIDR=byte;                //zu sendene Daten (bei MAX6675 nicht möglich)
5
  USISR=(1<<USIOIF);            //Overflowflag löschen
6
  PORTB &=~(1<<PB2);            //CS auf low (SS)
7
  _delay_us(10);
8
  for(uint8_t i=0; i<=1; i++)        //zwei Zyklen = 16Bit empfangen
9
  {
10
    do
11
    {  
12
      USICR=(1<<USIWM0)|(1<<USICS1)|(1<<USICS0)|(1<<USICLK)|(1<<USITC);
13
      _delay_us(10);
14
    }
15
    while (!(USISR & (1<<USIOIF)));
16
    USISR=(1<<USIOIF);          //Overflowflag löschen
17
    if(i)                //Zweiter Zyklus:
18
      eeprom_write_byte(&lsb, USIDR);
19
      //daten|=USIDR;          //LSB empfangen und speichern
20
    else                //Erster Zyklus:
21
      eeprom_write_byte(&msb, USIDR);
22
      //daten|=USIDR*255;        //MSB empfangen und specihern
23
  }
24
  PORTB |=(1<<PB2);            //CS auf high (SS)
25
  return daten;
26
}

von Bimbi (Gast)


Lesenswert?

Ich habe vergessen zu sagen dass es sich um einen ATTiny2313 handelt.

von risu (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

obwohl ich den von Dir gewünschten SPI-Modus und ein paar andere 
relevante Details nicht kenne, wage ich mal ein paar Anmerkungen:

1. Mir ist nicht klar, weshalb Du USICR innerhalb Deiner 
"for"-Schleife initialisierst (USIOIF könntest Du auch mit 
"USISR|=(1<<USIOIF);" löschen).
2. Bei USICLK=1 müsstest Du den Takt für den 4-Bit-Counter per Software 
(durch Schreiben auf USITC) erzeugen (siehe Anlage). Deine restliche 
Initialisierung sorgt dafür, dass das Shift-Register durch das externe 
Clock-Signal getaktet wird (wie Du es vermutlich willst). Du setzt USITC 
aber nur in Deiner Initialisierung! Der Counter wird also nicht erhöht.
3. Das Schreiben ins EEPROM dauert vermutlich wesentlich länger als 
die Übertragung eines SPI-Bytes!

Debugging-Vorschläge:
a. SPI-Modus korrekt initialisieren und durch Setzen/Löschen von 
Debuging-I/O-Pins (nur zum Testen!) an verschiedenen Stellen im Programm 
feststellen, wo Dein Programm "hängen bleibt". Bei Deinem jetzigen 
Programmablauf gehe ich davon aus, dass durch Eintakten eines eingehen 
Bytes "USISR&(1<<USIOIF)" nie ungleich 0 wird, da der Counter aufgrund 
falscher Initialisierung nicht per Hardware weiterzählt, sondern 
USITC-Signale erwartet, die Du nicht erzeugst.
b. Nicht zwischendurch ins EEPROM schreiben!

Gruß

 risu

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.