seltsames Problem mit SPI und 595

Gast #1897024
Hallo,

möchte per 74..595 mehrere 7 Segmentanzeigen ansteuern.
Momentan habe ich erstmal einen 595 angeschlossen.

Momentan bin ich bei 3 Varianten:

1. Über manuelles rüberschieben bekomme ich Daten rein.
2. Hardware SPI klappt dagegen nicht.
3. Software SPI irgendwie auch nicht. Das ist seltsam, zumal 1.) geht.
Hier kommt nur nicht reproduzierbares Chaos rüber, bei jedem µC reset 
etwas anderes.

Das Setup:

Der 595 ist über MISO, SCK und PD7 als RCK (der Pin, der die Register 
auf die Ausgangspins übernimmt) angeschlossen.
µC ist ein Mega32 mit 16Mhz Quarz.
Reset des 595 ist fest auf VCC, Output enable auf GND.

Variante 1 (Jedes Bit manuell rüberschieben):
1
#include <avr/io.h>
2
#include <stdlib.h>
3

4
#define  RCK_DDR DDRD
5
#define RCK_PORT PORTD
6
#define  RCK_PIN  7
7
#define SPI_MOSI   5
8
#define SPI_SCK    7
9
#define SPI_SS    4
10
#define DDR_SPI    PORTB
11

12

13

14
int main(void) {
15

16
  DDRD |= (1<<PD2); //macht eine LED an
17
  PORTD |= (1 << PD2);
18

19
  
20
  DDRB |= (1<<7) |  (1<<5); //sck und mosi
21
  DDRD |= (1<<7); 
22
  PORTB |= (1<<5);
23
  PORTB |= (1<<7);
24

25
  PORTB &= ~(1<<7);
26
  PORTB &= ~(1<<5);
27

28
  PORTB |= (1<<7);  //weitere Clockimpulse
29
  PORTB &= ~(1<<7);
30

31
  PORTB |= (1<<7);
32
  PORTB &= ~(1<<7);
33

34

35
  PORTB |= (1<<7);
36
  PORTB &= ~(1<<7);
37

38

39

40

41
  PORTD |= (1<<7);  //LEDs anmachen
42
  PORTD &= ~(1<<7);
43

44
  while (1)  {
45

46

47
  }
48

49
}

Variante 2: Hardware SPI
1
#include <avr/io.h>
2
#include <stdlib.h>
3

4
#define  RCK_DDR DDRD
5
#define RCK_PORT PORTD
6
#define  RCK_PIN  7
7
#define SPI_MOSI   5
8
#define SPI_SCK    7
9
#define SPI_SS    4
10
#define DDR_SPI    PORTB
11

12
void SPI_MasterInit(void);
13
void display_write(uint8_t dc) {
14

15
  SPDR = dc; 
16

17
  while (!(SPSR & (1 << SPIF)));
18
  
19
  RCK_PORT &= ~(1 << RCK_PIN); //LEDs anmachen
20
  RCK_PORT |= (1 << RCK_PIN);
21

22
}
23

24
int main(void) {
25

26
  SPI_MasterInit();
27
  display_write(0b10101010);
28

29
  DDRD |= (1<<PD2);
30
  PORTD |= (1 << PD2);
31

32
  while (1);
33

34

35
}
36

37
void SPI_MasterInit(void) {
38
  /* Set MOSI and SCK output, all others input */
39
  DDR_SPI = (1 << SPI_MOSI) | (1 << SPI_SCK) | (1 << SPI_SS);
40
  /* Enable SPI, Master, set clock rate fck/2 */
41
  SPCR = (1 << SPE) | (1 << MSTR) | (1 << SPR0) | (1 << SPR1);
42
  //SPSR |= (1 << SPI2X);
43
  
44
  RCK_DDR |= (1<<RCK_PIN);
45
  RCK_PORT |= (1<<RCK_PIN);
46
}

Variante 3: (Software SPI mit SPI Pins)
1
#include <avr/io.h>
2
#include <stdlib.h>
3

4
#define  RCK_DDR DDRD
5
#define RCK_PORT PORTD
6
#define  RCK_PIN  7
7
#define SPI_MOSI   5
8
#define SPI_SCK    7
9
#define SPI_SS    4
10
#define DDR_SPI    PORTB
11

12
void SPI_MasterInit(void);
13
void display_write(uint8_t dc) {
14

15
  unsigned char bits;
16
  for (bits = 8; bits > 0; bits--) {
17
    PORTB &= ~(1<<SPI_MOSI);
18
    if (dc & 0x80) {
19
      PORTB |= (1<<SPI_MOSI);
20
    }
21

22
    dc <<= 1;
23
    
24
    PORTB |= (1<<SPI_SCK);
25
    PORTB &= ~(1<<SPI_SCK);
26
  }
27

28

29
  RCK_PORT &= ~(1 << RCK_PIN);
30
  RCK_PORT |= (1 << RCK_PIN);
31

32
}
33

34
int main(void) {
35

36
  SPI_MasterInit();
37
  display_write(0b10101010);
38

39
  DDRD |= (1<<PD2);
40
  PORTD |= (1 << PD2);
41

42
  while (1);
43

44
}
45

46
void SPI_MasterInit(void) {
47
  /* Set MOSI and SCK output, all others input */
48
  DDR_SPI = (1 << SPI_MOSI) | (1 << SPI_SCK) | (1 << SPI_SS);
49
  
50
  RCK_DDR |= (1<<RCK_PIN);
51
  RCK_PORT |= (1<<RCK_PIN);
52
  PORTB &= ~(1<<SPI_SCK);
53
}

Irgendwas essentielles muss ich übersehen, sonst würde entweder 1 auch 
nicht funktionieren oder aber 3 auch klappen.
Mein Ziel ist es, es per Hardware SPI hinzubekommen.

Der µC wird über Bootloader programmiert, es hängt kein Programmer an 
SPI.
Hat jemand eine Idee?
Gast #1897026
also wenn da eine LED dran hängt dann brauchst du aber entweder eine 
high speed kamera oder ein "schnelles" auge:

 RCK_PORT &= ~(1 << RCK_PIN); //LEDs anmachen
  RCK_PORT |= (1 << RCK_PIN);



geht an und auch glecih wieder aus (kommt auf deine CPU Takfrequenc 
drauf an wie schnell aber ich schätze <1us )

bg
Gast #1897027
Okay,

es muss natürlich statt
1
#define DDR_SPI    PORTB
1
#define DDR_SPI    DDRB

heißen und so läufts dann auch!
Ich sitze da echt seit 5 Stunden dran :)
Gast #1897028
ggg schrieb:
> also wenn da eine LED dran hängt dann brauchst du aber entweder eine
> high speed kamera oder ein "schnelles" auge:

Das ist der "enable" Pin (Storage Clock), der die internen Flip Flops 
nach außen auf die Pins schaltet.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 16 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.