AVR ATMEGA32 - SPI in GCC - CODEPROBLEM, erbitte Hilfe

#4044008
Lesenswert?

Hallo und schönen Sonntag allerseits,

ich versuche eine SPI Kommunikation zwischen einem Atmel ATMEGA32L (als 
Master) und einem bzw später mehreren Slaves zu implementieren.


Leider tat sich lt. Oszilloskop nicht das was ich mir erhofft habe. Habe 
ich etwas vergessen, übersehen oder falschgemacht?


Anbei mein C - Code mit der Bitte um Hilfe, Anregung und 
Lösungsvorschläge.


1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdbool.h>
4
#include <avr/interrupt.h>
5

6
// Prototypen
7

8
void SPI_MasterInit(void);
9
void SPI_MasterTransmit( int cData);
10
unsigned char SPI_MasterReceive(void);
11

12

13

14

15
int main(void)
16
{
17
    // Interrupts erlauben
18
    sei();
19
    //TestPin wechselt Zustand bei erfolgreichem Funktionsdurchlauf
20
    DDRD |= (1<<DDD7);
21
    
22
    unsigned char test= 0x54;
23
    unsigned char back;
24
    unsigned char end = false;
25
   
26
    while(end!=true)
27
    {
28
        SPI_MasterTransmit(test);
29
        back = SPI_MasterReceive();
30
     
31
    }
32
    
33
    
34
    return 0;               /* never reached */
35
}
36

37

38

39
void SPI_MasterInit(void)
40

41
{
42

43
    /* Set MOSI and SCK output, all others input */
44
    DDRB |= (1<<DDB5)|(1<<DDB7);
45
    // SET MISO als Eingang
46
    //DDRB &= ~(1<<DDB6);
47
    // MOSI, MISO und Takt auf LOW
48
    //PORTB &= ~((1<<PB5)|(1<<PB6)|(1<<PB7));
49
    // slave select als Ausgang
50
    DDRD |= (1<<DDD4);
51
    // SS auf High
52
    PORTD |= (1<<PD4);
53
    
54
    /* SPI Kontrollregister */
55
    
56
    // SPI Interrupt enable , SPI aktivieren, Mastermode
57
    SPCR |= ((1<<SPE)|(1<<MSTR));
58
    
59
   //Taktbasis low, steigende flanke MO, fallende flanke MI, SPI Takt = /4 -> 1 MHz / 4 = 250 KHZ = 250.000 Hz
60
    //SPCR &= ~((1<<SPIE)|(1<<CPOL)|(1<<CPHA)|(1<<SPR0)|(1<<SPR1));
61
   
62
    /*SPI  Status Register*/
63
    
64
    //Kontrollflag setzen
65
    
66
    PORTD |= (1 <<PD7);
67
    
68
}
69

70
void SPI_MasterTransmit( int cData)
71

72
{
73
    //testflag löschen
74
    PORTD &= ~(1<<PD7);
75

76
    //Slaveselect auf Masse
77
    PORTD &= ~(1<<PD4);
78
    
79
    
80
    /* Start transmission */
81
    SPDR = cData;
82
    /* Wait for transmission complete */
83
    while(!(SPSR & (1<<SPIF)));
84
    
85
    PORTD |= (1<<PD4);
86
    
87
    //testflag setzen
88
    PORTD |= (1 <<PD7);
89
    
90
    
91
    
92
    
93
}
94

95
  unsigned char SPI_MasterReceive(void)
96
{
97
    //testflag löschen
98
    PORTD &= ~(1<<PD7);
99
    
100
    _delay_ms(10);
101
    //testflag setzen
102
    PORTD |= (1 <<PD7);
103
    //
104
    return SPDR;
105
    
106
    
107
}

1
Fuse high byte:
2
# 0xB9 = 1 0 1 1   1 0 0 1
3
Fuse low byte:
4
# 0x81 = 1 0 0 0   0 0 0 1
Gast #4044022
Lesenswert?

Der Slave Select ist doch PB4 und nicht PD4 oder?
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdbool.h>
4
#include <avr/interrupt.h>
5

6
// Prototypen
7

8
void SPI_MasterInit(void);
9
uint8_t SPI_MasterTransmit(uint8_t cData);
10

11

12
int main(void)
13
{    
14
    uint8_t test= 0x54;
15
    uint8_t back;
16
    unsigned char end = false;
17
   
18
    while(end!=true)
19
    {
20
        back = SPI_MasterTransmit(test);   
21
    }
22
    
23
    
24
    return 0;               /* never reached */
25
}
26

27

28

29
void SPI_MasterInit(void)
30
{
31
    // SS auf High
32
    PORTD |= (1<<PB4);
33

34
    /* Set MOSI and SCK output, all others input */
35
    DDRB |= (1<<DDB4)|(1<<DDB5)|(1<<DDB7);
36
    
37
    // SPI Interrupt enable , SPI aktivieren, Mastermode
38
    SPCR |= ((1<<SPE)|(1<<MSTR)); 
39
}
40

41
uint8_t SPI_MasterTransmit(uint8_t cData)
42
{
43
    //Slaveselect auf Masse
44
    PORTB &= ~(1<<PB4);
45
    
46
    
47
    /* Start transmission */
48
    SPDR = cData;
49
    /* Wait for transmission complete */
50
    while(!(SPSR & (1<<SPIF)));
51
    
52
    PORTB |= (1<<PB4);
53
    
54
    return SPDR;
55
}
Gast #4044025
Lesenswert?

OOh da hatte sich noch ein Fehler eingeschlichen
1
void SPI_MasterInit(void)
2
{
3
    // SS auf High
4
    PORTB |= (1<<PB4);
5

6
    /* Set MOSI and SCK output, all others input */
7
    DDRB |= (1<<DDB4)|(1<<DDB5)|(1<<DDB7);
8
    
9
    // SPI Interrupt enable , SPI aktivieren, Mastermode
10
    SPCR |= ((1<<SPE)|(1<<MSTR)); 
11
}

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