Forum: Mikrocontroller und Digitale Elektronik Problem bei SPI Datenübertragung


von M. G. (ixil96)


Lesenswert?

Hallo,
Ich versuche ein paar Daten per SPI zu übertragen und kann leider kein 
Signal am MOSI messen. Ich verwende einen AT90PWM316 als Controler!

Kann mir bitte jemand weiter helfen?

Hier mein Code:
1
/********************************************************
2
* SPI-Master - Datenübertragung                      *
3
* Übertragung zweier 8-Bit Daten (11010010 und 10000001)*
4
* Prozessor:     AT90PWM316                          *
5
* Clock:      Osz. 8MHz intern                    *
6
********************************************************/
7
8
#include <avr/io.h>
9
#include <util/delay.h>
10
11
void SPI_Master_Init(void)
12
{
13
  SPCR &=    ~(1<<DORD);   // Send MSB first
14
  SPCR |=    (1<<MSTR);    // Controller = Master
15
  SPCR &=    ~(1<<CPOL);  // CLK positiv phase
16
  SPCR |=    (1<<CPHA);    // Sampling data @ rising edge
17
  SPCR |=    (1<<SPR1);    // CLK / 64 = 125kHz
18
19
  DDRB |=    (1<<PB1);    // Set MOSI output
20
  DDRB &=    ~(1<<PB0);    // Set MISO input
21
  DDRB |=    (1<<PB7);    // Set SCK output
22
  DDRD |=    (1<<PD3);    // Set SS output
23
24
  SPCR |=    (1<<SPE);    // SPI enable
25
}
26
27
void SPI_Master_Transmit(char cData)
28
{
29
  PORTD &=   ~(1<<PD3);        // SS = low (Slave = enabled)
30
  SPDR = cData;              // Start transmission
31
  while (!(SPSR & (1<<SPIF)));  // Wait for transmission complete
32
  PORTD |= (1<<PD3);          // SS = high (Slave = disabled)
33
}
34
35
36
int main(void)
37
{
38
  SPI_Master_Init();
39
40
  while(1)
41
  {
42
    SPI_Master_Transmit(0b11010010);
43
    _delay_ms(500);           // delaytime between next transmission
44
    SPI_Master_Transmit(0b10000001);
45
    _delay_ms(500);          // delaytime between next transmission
46
  }
47
}

von holger (Gast)


Lesenswert?

>kann leider kein Signal am MOSI messen.

Eigentlich sieht das gut aus. Wie hast du gemessen?

von Thomas E. (thomase)


Lesenswert?

m. g. schrieb:
> Ich verwende einen AT90PWM316

Hast du die 24-Pin-Version?

Dann guck dir im Datenblatt die Funktion des SPIPS-Bits im 
MCUCR-Register an. Dieses Bit muss in der 24-Pin-Version bei deiner 
Konfiguration gesetzt werden.

mfg.

: Bearbeitet durch User
von holger (Gast)


Lesenswert?

>Dann guck dir im Datenblatt die Funktion des SPIPS-Bits im
>MCUCR-Register an. Dieses Bit muss in der 24-Pin-Version bei deiner
>Konfiguration gesetzt werden.

Das sehe ich anders;)

von M. G. (ixil96)


Lesenswert?

Thomas Eckmann schrieb:
> m. g. schrieb:
>> Ich verwende einen AT90PWM316
>
> Hast du die 24-Pin-Version?

Ich habe die 32 Pin Version!

von M. G. (ixil96)


Lesenswert?

holger schrieb:
>>kann leider kein Signal am MOSI messen.
>
> Eigentlich sieht das gut aus. Wie hast du gemessen?

Mit dem Oszi!

von Thomas E. (thomase)


Lesenswert?

holger schrieb:
> Das sehe ich anders

Und?

"On 24 pins package, SPIPS has the following action:
– When the SPIPS bit is written to zero, the SPI signals are directed on 
alternate SPI
pins, MISO_A, MOSI_A, SCK_A and SS_A.
Bit 7 6 5 4 3 2 1 0
SPIPS – – PUD – – IVSEL IVCE MCUCR
Read/Write R/W R R R/W R R R/W R/W
Initial Value 0 0 0 0 0 0 0 0
178
7710A–AVR–03/07
AT90PWM216/316
– When the SPIPS bit is written to one,the SPI signals are directed on 
pins
MISO,MOSI, SCK and SS."

mfg.

von Thomas E. (thomase)


Lesenswert?

m. g. schrieb:
> Ich habe die 32 Pin Version!

Dann hat sich das mit dem SPIPS erledigt.

mfg.

von Thomas E. (thomase)


Lesenswert?

m. g. schrieb:
> void SPI_Master_Transmit(char cData)
> {
>   PORTD &=   ~(1<<PD3);        // SS = low (Slave = enabled)
>   SPDR = cData;              // Start transmission
>   while (!(SPSR & (1<<SPIF)));  // Wait for transmission complete
>   PORTD |= (1<<PD3);          // SS = high (Slave = disabled)
> }

Wieso schaltest du auf Slave bevor du sendest?

mfg.

: Bearbeitet durch User
von M. G. (ixil96)


Lesenswert?

Thomas Eckmann schrieb:
> m. g. schrieb:
>> void SPI_Master_Transmit(char cData)
>> {
>>   PORTD &=   ~(1<<PD3);        // SS = low (Slave = enabled)
>>   SPDR = cData;              // Start transmission
>>   while (!(SPSR & (1<<SPIF)));  // Wait for transmission complete
>>   PORTD |= (1<<PD3);          // SS = high (Slave = disabled)
>> }
>
> Wieso schaltest du auf Slave bevor du sendest?
>
> mfg.

Ist für einen angedachten SPI-Baustein. Hier muss ich zuerst SS auf low 
setzen. Wobei das in diesem Fall für die Übertragung egal ist!

von Axel R. (Gast)


Lesenswert?

schaltest du damit deinen eigenen Atmega als Slave oder das Gerät, 
welches du steuern möchtest?

von isidor (Gast)


Lesenswert?

m. g. schrieb:
> Wobei das in diesem Fall für die Übertragung egal ist!

Wenn ein Controller auf Slave gesetzt ist wird er keinen
Clock generieren da dieser vom Master ausgehen muss.
Im Slave Modus wartet er darauf dass Clock Flanken daherkommen
und er seine einzelnen DatenBits dazu generieren/ausgeben kann.

Das Schreiben

SPDR = cData;

lädt also nur das Datenregister, und sonst nichts.

von M. G. (ixil96)


Lesenswert?

Axel R. schrieb:
> schaltest du damit deinen eigenen Atmega als Slave oder das Gerät,
> welches du steuern möchtest?

Hier soll ein Sensor angesteuert werden!

von Thomas E. (thomase)


Lesenswert?

isidor schrieb:
> lädt also nur das Datenregister, und sonst nichts.

Und dann sendet er die Daten raus, weil er Master ist.

m. g. schrieb:
> Mit dem Oszi!

Was für ein Oszi?

Setz deine Delays auf 1ms, damit da ein bisschen was los ist auf dem 
Pin.

mfg.

von M. G. (ixil96)


Angehängte Dateien:

Lesenswert?

Ich habe mit dem Oszi (Tektronix 100MHz) eine Vergleichsmessung an einem 
anderen UC gemacht. Hier kann ich den Datenverkehr am MOSI gut messen. 
Also am Oszi liegt es nicht!

Anbei die Registereinstellungen unmittelbar nach der SPI 
Initialisierung.

Der UC arbeitet sonst ganz normal. Ich glaube hier nicht an einen 
hardwareseitigen Fehler der SPI-Schnittstelle.

von Axel R. (Gast)


Lesenswert?

Muss ich also selbst nachsehen, welcher PIN PORTD3 ist.
Nochmal: ist das der SS-Pin deines SPI Interfaces? wenn ja, dann ist das 
falsch. Das darfst Du nicht auf LOW ziehen, weil sonst dein Atmel als 
Slave geschaltet wird. Nimm einen anderen PIN und sieh zu, dass der 
SS-PIN deines SPI interfaces immer auf H-Pegel steht. SONST GEHT DAS 
NICHT!. Dein Atmel erwartet sonst von aussen auf der CLK-leitung einene 
Takt und taktet synchron zudiesem takt seine Daten raus.
Am MOSI kommt nichts raus, sagst Du.
KOmmt am SCK was raus?
Wenn am SCK nichts raus kommt, lege dort mal 100Khz oder so an.
Dann müsstest Du deine Daten aus dem Datenregister sehen.

Axel

von Karl H. (kbuchegg)


Lesenswert?

Axel R. schrieb:
> Muss ich also selbst nachsehen, welcher PIN PORTD3 ist.
> Nochmal: ist das der SS-Pin deines SPI Interfaces? wenn ja, dann ist das
> falsch. Das darfst Du nicht auf LOW ziehen, weil sonst dein Atmel als
> Slave geschaltet wird.

Seit wann?

Nochmal: Die SPI Einheit ist als Master konfiguriert!
Der Zustand des SS Pins, ob 0 oder 1, spielt dazu keine Rolle, solange 
er nur als Ausgang konfguriert ist. Und das ist er.

Und ja. PD3 ist der zur SPI gehörende SS.

: Bearbeitet durch User
von Axelr. (Gast)


Lesenswert?

Ok, wenn das SO ist, habe ich nichts gesagt.
Mir war so, als wenn der SlaveSelcet-PIN den Atmel als Slave schaltet, 
wenn der auf LoW geht.
OK - höre weiter zu:)

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.