Forum: Mikrocontroller und Digitale Elektronik ATmega128 und SPI Problem


von CG (Gast)


Lesenswert?

Hallo

Vielleicht kann mir ja jemand helfen bei meinem Problem.
Ich habe einen ATmega128 und würde gerne die SPI-Schnittstelle testen.
Leider bleibt mein Programm an folgender Stelle immer hängen (kommt 
nicht mehr aus der while-Schleife raus)

while(!(SPSR & (1<<SPIF)));     //Wait until transmission complete

Habe schon einiges versucht doch leider alles ohne Erfolg.

Was mache ich denn falsch?
Habe keine gegenstelle angeschlossen, aber ich denke mal nicht das das 
was ausmacht oder? ich müsste ja zumindest einen Takt auf der SCK-Pin 
sehen.

Ich bedanke mich im Vorfeld für alle hilfreichen Antworten :-)

Zu den Eckdaten:
M103C Fuses ist nicht gesetzt
BOOTSZ ist auf 512 gesetzt
SUT_CKSEL ist auf Ext. Cystal/Resonator High Freq.: Start-up time: 16K 
CK +64ms
ein 16MHz Quarz ist angeschlossen

Ich habe einen Tastkopf an SCK von der SPI-Schnittstelle angeschlossen 
doch leider sehe ich dort auch gar keinen Tackt.



Zum TestCode:

main
1
#include "global.h"          // Globale Lib 
2
3
int main(void)
4
{
5
  char data;         //Received data stored here
6
    
7
  cli();            // Disable all interrupts
8
  spi_init_master();      // SPI Inizalisierung
9
//  spi_init_slave ();  
10
  initPort();          // Inizalisierung der Ports         
11
  sei();            // enable all interrupts
12
13
while(1)
14
    {    
15
  SWITCH_LED1;  
16
  _delay_ms(500);
17
  data = 0x00;                    //Reset ACK in "data"
18
    data = spi_tranceiver('Hallo', PIN_SPI_CS1);     
19
  SET_LED3;
20
  }
21
}
in der global.h
1
// SPI
2
#define PORT_SPI    PORTB
3
#define DDR_SPI      DDRB
4
#define PIN_SPI_MISO  3    // PB3
5
#define PIN_SPI_MOSI  2    // PB2
6
#define PIN_SPI_SCK    1    // PB1
7
#define PORT_SPI_CS    PORTC
8
#define DDR_SPI_CS    DDRC
9
#define PIN_SPI_CS1    7    // PC7
10
#define PIN_SPI_CS2    6    // PC6
11
#define PIN_SPI_CS3    5    // PC5
12
13
in der spi_master_slave.c
14
/*
15
 * spi_master_slave.c
16
 *
17
 * Created: 12.02.2015 14:08:46
18
 *  Author: u308488
19
 */ 
20
21
#include "spi_master_slave.h"
22
23
/*
24
// SPI Transmission/reception complete ISR
25
ISR(SPI_STC_vect)
26
{
27
    // Code to execute
28
    // whenever transmission/reception
29
    // is complete.
30
}
31
*/
32
33
void spi_init_slave (void)
34
{
35
   DDR_SPI |= (1<<PIN_SPI_MISO);    // MISO als Ausgang definieren
36
   SPCR |= (1<<SPE);                    //Enable SPI
37
38
}
39
40
//Initialize SPI Master Device
41
void spi_init_master (void)            
42
{
43
  DDR_SPI = (1<<PIN_SPI_MOSI) | (1<<PIN_SPI_SCK); // MOSI und SCK als Ausgang definieren
44
  DDR_SPI &= ~(1<<PIN_SPI_MISO);          // MISO als Eingang definieren
45
  PORT_SPI = (1<<PIN_SPI_MOSI) | (1<<PIN_SPI_SCK);
46
  
47
//  SPCR = (1<<SPR1)|(1<<SPR0);            // Prescaler: Fosc/128, Enable Interrupts
48
//  SPCR = (1<<SPI2X);                // Prescaler: Fosc/2,
49
  SPCR = (1<<MSTR);                // Set as Master
50
  SPCR = (1<<SPE);                // Enable SPI
51
  //  SPCR = (1<<SPIE);              // SPI Interrupt Enable
52
    
53
  SPSR |= (0 << SPIF); // SPIF zum Start löschen 
54
  _delay_ms(10);
55
}
56
57
//Function to send and receive data
58
char spi_tranceiver (char data, unsigned char cs)
59
{
60
  PORT_SPI_CS &= ~(1<<cs);    //SS am Slave Low --> Beginn der Übertragung
61
  SWITCH_LED2;
62
    SPDR = data;                       //Load data into the buffer
63
    while(!(SPSR & (1<<SPIF)));     //Wait until transmission complete
64
  PORT_SPI_CS |= (1<<cs);      //SS High --> Ende der Übertragung
65
  return SPDR;                     //Return received data  
66
}

--

Wie schon von Mitforisten angemerkt: Quelltext in [ c ] [ /c ] - Tags 
einschließen.

-rufus

: Bearbeitet durch User
von Mitlesa (Gast)


Lesenswert?

CG schrieb:
> Ich bedanke mich im Vorfeld für alle hilfreichen Antworten :-)

Die Leser würden sich bedanken wenn du übersichtlichen, sauber
tabulierten Code zeigen würdest. Insbesondere die C-Code
Formatierung beim Posten wäre hilfreich.

von CG (Gast)


Lesenswert?

Okay
dafür entschuldige ich mich und werde dies fürs nächste mal beachten

von Jope (Gast)


Lesenswert?

Sollte der SPI_CS-Pin in spi_init_master() nicht als Ausgang definiert 
werden?

von dummy (Gast)


Lesenswert?

Der SS Pin MUSS beim SPI Master ein Ausgang sein.
Acu wenn er nicht benutzt wird.

von Mitlesa (Gast)


Lesenswert?

dummy schrieb:
> Der SS Pin MUSS beim SPI Master ein Ausgang sein.
> Acu wenn er nicht benutzt wird.

Nö.

von N.G. (Gast)


Lesenswert?

nein, er muss nicht auf Ausgang stehen, aber er darf niemals low werden, 
sonst geht der µC vom Master- in den Slave-mode über.

von dummy (Gast)


Lesenswert?

>nein, er muss nicht auf Ausgang stehen, aber er darf niemals low werden,
>sonst geht der µC vom Master- in den Slave-mode über.

Und ist deshalb als Eingang nicht mehr sinvoll verwendbar.
Tolles "nein". Als Ausgang kann man den Pin wenigstens noch gebrauchen.

von N.G. (Gast)


Lesenswert?

dummy schrieb:
> Und ist deshalb als Eingang nicht mehr sinvoll verwendbar.
> Tolles "nein". Als Ausgang kann man den Pin wenigstens noch gebrauchen.

Tolles "MUSS". Ich wollte nur andeuten, dass man den Pin schon auf Input 
haben kann, in manchen Schaltungen mag das auch gewollt sein, aber du 
hast mit deiner Aussage was den Sinn angeht natürlich recht :)

von Cyblord -. (cyblord)


Lesenswert?

dummy schrieb:
> Als Ausgang kann man den Pin wenigstens noch gebrauchen.

Darum macht es Sinn ihn direkt als CS Pin zu nehmen. Dafür geht er gut, 
man hat keinen Pin verschwendet und man kommt später nicht in Versuchung 
den Pin als Eingang zu verwenden.

von Mitlesa (Gast)


Lesenswert?

Hilft nicht bei seinem SPI Problem da die SPI Maschine im
Master Mode unabhängig von der Betätigung des SS Pin arbeitet.

von Debugger (Gast)


Lesenswert?

1
  SPCR = (1<<MSTR);                // Set as Master
2
  SPCR = (1<<SPE);                // Enable SPI

bei enable SPI wird der vorher gesetzte Master mode wieder zurückgesetzt 
-> Slave

von CG (Gast)


Lesenswert?

Mitlesa schrieb:
> Mitlesa

Ihr habt zwar alle recht aber leider hilft es wie Mitlesa schon schrieb 
es mir nicht bei meinem Problem :-(

von Mitlesa (Gast)


Lesenswert?

CG schrieb:
> hilft es wie Mitlesa schon schrieb es mir nicht bei meinem Problem :-(

Aber was er schreibt sollte schon beachtet werden! :

Debugger schrieb:
> bei enable SPI wird der vorher gesetzte Master mode wieder zurückgesetzt
> -> Slave

von CG (Gast)


Lesenswert?

Das habe ich erst gesehen als ich es schon abgeschickt hatte.
Werde es direkt mal ausprobieren und euch berichten :-)

von Martin (Gast)


Lesenswert?

Das ist ja schrecklich ohne richtige Code Übersicht
1
#include "global.h"          // Globale Lib
2
3
int main(void)
4
{
5
  char data;         //Received data stored here
6
7
  cli();            // Disable all interrupts
8
  spi_init_master();      // SPI Inizalisierung
9
//  spi_init_slave ();
10
  initPort();          // Inizalisierung der Ports
11
  sei();            // enable all interrupts
12
13
while(1)
14
    {
15
  SWITCH_LED1;
16
  _delay_ms(500);
17
  data = 0x00;                    //Reset ACK in "data"
18
    data = spi_tranceiver('Hallo', PIN_SPI_CS1);
19
  SET_LED3;
20
  }
21
}
22
23
in der global.h
24
25
// SPI
26
#define PORT_SPI    PORTB
27
#define DDR_SPI      DDRB
28
#define PIN_SPI_MISO  3    // PB3
29
#define PIN_SPI_MOSI  2    // PB2
30
#define PIN_SPI_SCK    1    // PB1
31
#define PORT_SPI_CS    PORTC
32
#define DDR_SPI_CS    DDRC
33
#define PIN_SPI_CS1    7    // PC7
34
#define PIN_SPI_CS2    6    // PC6
35
#define PIN_SPI_CS3    5    // PC5
36
37
in der spi_master_slave.c
38
/*
39
 * spi_master_slave.c
40
 *
41
 * Created: 12.02.2015 14:08:46
42
 *  Author: u308488
43
 */
44
45
#include "spi_master_slave.h"
46
47
/*
48
// SPI Transmission/reception complete ISR
49
ISR(SPI_STC_vect)
50
{
51
    // Code to execute
52
    // whenever transmission/reception
53
    // is complete.
54
}
55
*/
56
57
void spi_init_slave (void)
58
{
59
   DDR_SPI |= (1<<PIN_SPI_MISO);    // MISO als Ausgang definieren
60
   SPCR |= (1<<SPE);                    //Enable SPI
61
62
}
63
64
//Initialize SPI Master Device
65
void spi_init_master (void)
66
{
67
  DDR_SPI = (1<<PIN_SPI_MOSI) | (1<<PIN_SPI_SCK); // MOSI und SCK als 
68
Ausgang definieren
69
  DDR_SPI &= ~(1<<PIN_SPI_MISO);          // MISO als Eingang definieren
70
  PORT_SPI = (1<<PIN_SPI_MOSI) | (1<<PIN_SPI_SCK);
71
72
//  SPCR = (1<<SPR1)|(1<<SPR0);            // Prescaler: Fosc/128, 
73
Enable Interrupts
74
//  SPCR = (1<<SPI2X);                // Prescaler: Fosc/2,
75
  SPCR = (1<<MSTR);                // Set as Master
76
  SPCR = (1<<SPE);                // Enable SPI
77
  //  SPCR = (1<<SPIE);              // SPI Interrupt Enable
78
79
  SPSR |= (0 << SPIF); // SPIF zum Start löschen
80
  _delay_ms(10);
81
}
82
83
//Function to send and receive data
84
char spi_tranceiver (char data, unsigned char cs)
85
{
86
  PORT_SPI_CS &= ~(1<<cs);    //SS am Slave Low --> Beginn der Übertragung
87
  SWITCH_LED2;
88
    SPDR = data;                       //Load data into the buffer
89
    while(!(SPSR & (1<<SPIF)));     //Wait until transmission complete
90
  PORT_SPI_CS |= (1<<cs);      //SS High --> Ende der Übertragung
91
  return SPDR;                     //Return received data
92
}

von CG (Gast)


Lesenswert?

Debugger schrieb:
> SPCR = (1<<MSTR);                // Set as Master
>   SPCR = (1<<SPE);                // Enable SPI
>
> bei enable SPI wird der vorher gesetzte Master mode wieder zurückgesetzt
> -> Slave

Super es funktioniert :-)

Habe diesen Bereich einfach umgeschieben und siehe da Daten werden 
versendet.
SPCR = (1<<MSTR) | (1<<SPE); // Set as Master, Enable SPI

Dankeschön für eure Hilfe. :-)

von Peter D. (peda)


Lesenswert?

Martin schrieb:
> spi_init_master();      // SPI Inizalisierung
>   initPort();          // Inizalisierung der Ports

Falsche Reihenfolge!

Der /CS Pin muß zuerst Ausgang werden!

von CG (Gast)


Lesenswert?

Oh das habe ich übersehen danke.

Darf ich noch fragen ob die slave Routien richtig ist?

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.