Forum: Mikrocontroller und Digitale Elektronik SPI receive liefert falsche Daten


von Thomas B. (escamoteur)


Angehängte Dateien:

Lesenswert?

Hi,

ich bin gerade dabei mit meinem VS1011 warm zu werden. Soweit versteht 
er erst mal wenn ich ihm was sage. Nur wenn ich ihn was frage kommt 
nicht alles bei meinem mega32 an.

Bei dem Test schreibe ich erst einen Wert in das Volume-Register und 
lese ihn dann wieder aus.
Eigentlich sollte ich 0xA2F5 bekommen, lese aber nur 0xA207. Laut 
Logicanalyser sendet mit der VS aber den korrekten Wert, nur der AVR 
verliert wohl ein paar Bits.


Das ist mein Quellcode

#include <avr/io.h>
#ifndef F_CPU
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert
   (z.B. durch Übergabe als Parameter zum Compiler innerhalb
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die
   "nachträgliche" Definition hinweist */
#warning "F_CPU war noch nicht definiert, wird nun mit 7372800 
definiert"
#define F_CPU 7372800UL     /* Quarz mit 7.3728 Mhz */
#endif
#include <util/delay.h>

#include <avr/interrupt.h>

#include <avr/io.h>          // (1)


void initPorts(void)
{
  DDRB = 0xff; // all out


  PORTB  |= (1 << PB0) | (1 << PB1); // VS1011 CS high

  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0); //SPI on
}



void WriteMP3Command(uint8_t reg, uint16_t value)
{
    PORTB &= ~(1 << PB0);

    SPDR = 0x2; //write command
    while(!(SPSR & (1<<SPIF)));

    SPDR = reg;
    while(!(SPSR & (1<<SPIF)));

    SPDR = (uint8_t) (value >> 8);
    while(!(SPSR & (1<<SPIF)));

    SPDR = (uint8_t) value;
    while(!(SPSR & (1<<SPIF)));



    PORTB  |= (1 << PB0);
}


uint16_t ReadMP3Register(uint8_t reg)
{
  uint16_t result = 0;

  PORTB &= ~(1 << PB0);

  SPDR = 0x3; //read command
  while(!(SPSR & (1<<SPIF)));

  SPDR = reg;
  while(!(SPSR & (1<<SPIF)));

  SPDR = 0xaa; //push result byte one out;
  while(!(SPSR & (1<<SPIF)));
  result = SPDR;

  result = result << 8;

  SPDR = 0xaa; //push result byte one out;
  while(!(SPSR & (1<<SPIF)));

  result |= SPDR;


  PORTB  |= (1 << PB0);

}



void MP3_SetVolume(uint16_t volume)
{
  WriteMP3Command(0xB,volume);

}


uint16_t result=0;

main()
{
  initPorts();

  PORTB |= (1 << PB2); // VS reset off

  MP3_SetVolume(0xA2F5);

  result = ReadMP3Register(0xB);


}

von Thomas B. (escamoteur)


Lesenswert?

Hat wirklich keiner von euch ne Idee??

Gruß
Tom

von gastlich (Gast)


Lesenswert?

bin nicht sicher, aber tönt nach einem CPOL oder CPHA problem.

schau dir mal die polarisation und die phase der takt und datenleitung 
des spi an. im datenblatt des VS1011 findest du sicher die nötigen 
einstellungen ...

gruss Claudio

von NOP (Gast)


Lesenswert?

[code]
uint16_t ReadMP3Register(uint8_t reg)
{
  uint16_t result = 0;

  PORTB &= ~(1 << PB0);

  SPDR = 0x3; //read command
  while(!(SPSR & (1<<SPIF)));

  SPDR = reg;
  while(!(SPSR & (1<<SPIF)));

  result = SPDR;// ####### <--- einfügen #############

  SPDR = 0xaa; //push result byte one out;
  while(!(SPSR & (1<<SPIF)));
  result = SPDR;

  result = result << 8;

  SPDR = 0xaa; //push result byte one out;
  while(!(SPSR & (1<<SPIF)));

  result |= SPDR;


  PORTB  |= (1 << PB0);

}
[code]

von Thomas B. (escamoteur)


Lesenswert?

@NOP: Wieso?

von NOP (Gast)


Lesenswert?

>@NOP: Wieso?

Weil das SPIF-Flags sonst nicht gelöscht wird, was aber für das 
nachfolgende wichig ist.

von Thomas B. (escamoteur)


Lesenswert?

@NOP: Habs eingefügt, aber Ergebnis ist das selbe.
Gruß
Tom

von Thomas B. (escamoteur)


Lesenswert?

Oh Mann, habs grad gefunden:

In ReadMP3Register() hat am Schluss

return result;

gefehlt.

Was ich nur nicht verstehe woher ich in main() dann 0xA207 als Ergebnis 
bekomme.

Dummerweise war das erste Byte gleich dem das ich erwartet hatte, daher 
hatte ich den SPI im Verdacht.

Gruß
Tom

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.