Mega32/Mega8 SPI funktioniert nicht

OP (Firma: 4CKnowLedge) Persönliche Seite #815824
Lesenswert?

Hallo, schönen Nachmittag ^^

Nach etlichen Kaffeetassen und Versuchen, hab ich mich durchgerungen, 
nach diesem (wahrscheinlich) banalen Fehler zu fragen...

Ich hab folgenden Code mit Mega8 und Mega32 probiert und messe mit Oszi 
und LA genau gar nichts! Hab ich etwas übersehen?

Beide µC's auf 8MHz interner Takt gefused.
1
#include <avr/io.h>
2

3
void SPI_MasterInit(void);
4
void SPI_MasterTransmit(char);
5

6

7
void main(void)
8
{
9
  SPI_MasterInit();
10
  while(1)
11
  {
12
    SPI_MasterTransmit(0xEE);
13

14
  }
15
}
16

17

18
void SPI_MasterInit(void)
19
{
20
/* Set MOSI, SCK and /SS output, all others input */
21
DDRB = (1<<PB5)|(1<<PB7)|(1<<PB4);
22
/* Enable SPI, Master, set clock rate fck/16 */
23
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
24
}
25

26

27
void SPI_MasterTransmit(char cData)
28
{
29
/* Start transmission */
30
SPDR = cData;
31
/* Wait for transmission complete */
32
while(!(SPSR & (1<<SPIF)));
33
}
OP (Firma: 4CKnowLedge) Persönliche Seite #815927
Lesenswert?

klausy wrote:
> was is mit den define's der Bits? sonst ist alles korrekt...
> Hardware????

Ja, das sollte ja nur ein Testprogramm sein, die Defines dürften an dem 
ganzen nichts ändern...

Die Hardware läuft korrekt... Ich hab zum Test mal LED's auf den Pins 
getestet...


Ich hab das ganze mal durch den Debugger (nur Simuliert) laufen 
lassen...

Dabei ist mir aufgefallen... wenn ich
1
void SPI_MasterInit(void)
2
{
3
/* Set MOSI, SCK and /SS output, all others input */
4
DDRB = (1<<PB5)|(1<<PB7)|(1<<PB4);
5
/* Enable SPI, Master, set clock rate fck/16 */
6
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
7
}

so mache, setzt mir das schreiben auf SPCR PB5(MOSI) den PIN also wird 
zum Eingang...

jetzt hab ich das ganze so:
1
void SPI_MasterInit(void)
2
{
3

4
/* Enable SPI, Master, set clock rate fck/16 */
5
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
6

7
/* Set MOSI, SCK and /SS output, all others input */
8
DDRB = (1<<PB5)|(1<<PB7)|(1<<PB4);
9
}

lt. Debugger sind jetzt zumindest mal die Datenrichtungen richtig...

EDIT: Ich habe das ganze getestet mit beiden Versionen der 
Transmit-Funktion und keines der beiden Programme zeigt Reaktion.
Gast #815945
Lesenswert?

Hallo Jürgen,

Tust Du so, dann sollte es gehen, ansonsten hast Du ein HW Problem :

void SPI_Init(void)
{
  uint8_t dummy;

  PORTB |= (uint8)0x20;   /* set MOSI hi */
  DDRB &= (uint8)~0x40;  /* clr bits */
  DDRB |= (uint8)0xb0;   /* 1011 SCK=O,MISO=I,MOSI=O,SS=O */
  /* setup SPI : clock = f/32 */
  /* select clock phase positive-going in middle of data */
  /* master mode, enable SPI */
  SPCR = (1<<MSTR)|(1<<SPE)|(1<<SPR1)|(1<<SPI2X);

  dummy = (SPSR); // clear status, nie verkehrt...
}

uint8_t SPI_TransferByte(uint8_t tx)
{
  uint8_t rx;

  SPDR = tx;

  // polling mode, wait for SPIF
  while((SPSR & (uint8_t)0x80) != (uint8_t)0x80);

  rx = SPDR;

return rx;
}
OP (Firma: 4CKnowLedge) Persönliche Seite #815975
Lesenswert?

Danke Tom! Ich hab mal deinen Code reingeklopft...

Anscheinend ist es wirklich ein HW Problem...

Allerdings funktioniert die ISP Schnittstelle, drum frag ich mich wieso 
nicht die SPI? Am Steckbrett kanns kaum liegen, da ich alle Messungen 
direkt an den Pins des µC durchführe...

Ein kleines Danke nochmal zwischendurch ^^
Gast #816314
Lesenswert?

Hallo Jürgen,

mein Code auf einem 32 mit 16MHz Quarz sieht so aus:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdlib.h>
4

5
void transmit(unsigned char, char);
6

7
void Load_Low()
8
{  
9
  PORTB &= ~(1 << PB4);
10
}
11

12
void Load_High()
13
{
14
  PORTB |= (1 << PB4);
15
}
16

17

18
void SPI_MasterInit(void) {
19

20
    DDRB = (1<<PB4)|(1<<PB5)|(1<<PB7);      // set PB4(SS), PB5 (MOSI) and PB7 (SCK) output, all others input
21

22
    SPCR = (1<<SPE)|(1<<MSTR);           // enable SPI, Master, set clock rate fck/4  
23
  
24
    PORTB |= (1 << PB7)|(1 << PB4);
25
}
26

27
void transmit(unsigned char addr, char data) {
28
  
29
  SPDR = addr;                      // Start transmission
30
  while(!(SPSR & (1<<SPIF)));           // Wait for transmission complete
31
  
32
  asm volatile("nop");
33
 
34
  SPDR = data;                      // Start transmission
35
  while(!(SPSR & (1<<SPIF)));            // Wait for transmission complete
36
}
37

38
void test_Init(void)
39
{
40
  Load_Low();
41
  for (int i = 0; i < 8; i++)
42
  {
43
  transmit(0x0C,0x01);            // normal mode  transmit(0x0C,0x01);
44
  }
45
  Load_High();
46

47
int main()
48
{
49
  
50
  SPI_MasterInit();
51
  _delay_us(10);
52
  test_Init();
53
  
54
  tu was....
55

56
  while (1) { _delay_ms(10); }
57
}

Das funktioniert bei mir einwandfrei.

Gruß
Udo

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren