SPI schieberegister

Gast #2121741
Lesenswert?

Hallo!
Ich versucher gerade mein erstes gcc programm zu schreiben und hab 
anscheinend irgendwo einen fehler drin.
in meiner schaltung habe ich einen ATMega16 und eine Schieberegister.

http://img844.imageshack.us/i/schaltung12.png/

Das ist meine schaltung (den rest einfach mal wegdenken...)

und jetzt wollt ich mal ein programm schreiben, das einfach nur jedes 2. 
LED im schieberegister leuchten lasst. (nur mal zu testzwecken)
1
#include <avr/io.h>
2
#define RCK PB4
3
#define SIN PB5
4
#define SCK PB7
5

6
int main(void)
7
{
8
  DDRB = (1 << RCK) | (1 << SIN) | (1 << SCK);
9
  PORTB = (1<<RCK) | (1 << PB6);
10
  SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL);
11
  SPSR |= (1 << SPI2X);
12

13
  char data = 0b01010101;
14
  while(1)
15
  {
16
    SPDR = data;
17

18
    while (!(SPSR & (1 << SPIF)));
19

20
    SPDR;
21
    PORTB &= ~(1<<RCK);
22
    PORTB |= (1<<RCK);
23
  }  
24
}

aber mit dem programm leuchten immer alle 8 LEDs
Gast #2122299
Lesenswert?

Se Sk. schrieb:
> Wieso das "SPDR;" vor dem RCK-Strobe?

jo, mach das mal raus! die sollte eigentlich nichts tun, vielleicht 
wurde sie sogar wegoptimiert.

außerdem glaube ich, das RCK muss eine positive Flanke zum speichern 
bekommen. Also die beiden Zeilen vom Strobe bei Gelegenheit vertauschen. 
Dürfte aber bei dem kleinen Programm nichts machen

wie CPOL eingestellt ist, ist bei mir egal, kannst also auch auf default 
lassen für die reine Ausgabe.

Das delay ist nicht nötig.



Was mich wundert, ist dass du sagst, dass ALLE LEDs immer leuchten. 
Könnte es nicht sein, dass das Programm einfach funktioniert und du die 
LEDs zufälligerweise genau so falsch angeschlossen hast, dass alle immer 
an sind? Versuch doch mal andere Kombinationen für data...?
Gast #2122329
Lesenswert?

Hab das programm neu geschrieben:
1
unsigned char sternschnuppe_data=0b00000001;
2

3
void init_sternschnuppe(void)
4
{
5
  DDRB |= (1<<RCK) | (1<<SIN) | (1<<SCK);
6
  PORTB |= (1<<RCK);
7
  SPCR = (1 << SPE) | (1<<MSTR);
8
  SPSR |= (1<<SPI2X);
9
}
10

11
void write_sternschnuppe(void)
12
{
13
  SPDR = sternschnuppe_data;
14
    while (!(SPSR & (1 << SPIF)));
15
  PORTB |= (1<<RCK);
16
  PORTB &= ~(1<<RCK);
17
}

und im main dann nit und write noch vor der mainloop aufgerufen. (dann 
sollte sich das doch auch nicht ändern?)

und noch immer leuchten alle LEDs.
#2122441
Lesenswert?

so. habs jetzt an 5V angeschlossen mit einem 100ohm widerstand. jetzt 
blinkts nurnoch am anfang einmal kurz auf, wenn ich einsteck. aber 
irgendwas dürft mit dem programm wieder nicht passen :-/ hab probiert 
das write_sternschnuppe nur vor der main-loop aufzurufen und auch in der 
main-loop (kein unterschied).
Gast #2122444
Lesenswert?

Armin schrieb:
> Se Sk. schrieb:
>> Wieso das "SPDR;" vor dem RCK-Strobe?
>
> jo, mach das mal raus! die sollte eigentlich nichts tun, vielleicht
> wurde sie sogar wegoptimiert.

SPDR sollte als Register eine volatile Variable sein und kann daher 
nicht wegoptimiert werden. Durch diese Zeile wird SPDR lesen und der 
gelesene Wert ignoriert.
#2122547
Lesenswert?

jakob m. schrieb:
> warum funktioniert das eigentlich mit den 12V nicht? sollte doch auch
> funktionieren, wenn ich einen passenden widerstand einbau?
Eigentlich ganz logisch:
- SR-Ausgang ist LOW => 12V-0V = 12V über LED+Vorwiderstand => leuchtet
- SR-Ausgang ist HIGH => 12V-5V = 7V über LED+Vorwiderstand => leuchtet 
auch

Dadurch leuchtet die LED in beiden Zuständen, die Unterschiede in der 
Helligkeit dürften so gering sein, dass du sie nicht bemerkst. Wurde 
auch weiter oben schon geschrieben...

Wenn du die LEDs an 5V anschließt, hast du:
- SR-Ausgang LOW => 5V-0V = 5V über LED+Vorwiderstand => LED leuchtet
- SR-Ausgang HIGH => 5V-5V = 0V über LED+Vorwiderstand => LED leuchtet 
nicht

Tada... ;)

MfG Stefan
#2122549
Lesenswert?

jakob m. schrieb:
> warum funktioniert das eigentlich mit den 12V nicht? sollte doch auch
> funktionieren, wenn ich einen passenden widerstand einbau?
>
> Edit: kann es sein, dass es zu problemen kommt, wenn die kabel (vom µC
> zum schieberegister) etwas länger sind? (ca. 1,5m)

Möglich, aber nicht sehr wahrscheinlich.

Zeig doch mal dein komplettes jetziges Programm.
#2122570
Lesenswert?

so mal das aktueller programm:
1
#define RCK PB4
2
#define SIN PB5
3
#define SCK PB7
4

5
extern unsigned char sternschnuppe_data;
6

7
extern void init_sternschnuppe(void);
8
extern void write_sternschnuppe(void);
1
unsigned char sternschnuppe_data=0b11110000;
2

3
void init_sternschnuppe(void)
4
{
5
  DDRB |= (1<<RCK) | (1<<SIN) | (1<<SCK);
6
  PORTB |= (1<<RCK);
7
  SPCR = (1 << SPE) | (1<<MSTR);
8
  SPSR |= (1<<SPI2X);
9
}
10

11
void write_sternschnuppe(void)
12
{
13
  SPDR = sternschnuppe_data;
14
    while (!(SPSR & (1 << SPIF)));
15
  //SPDR;
16
  PORTB |= (1<<RCK);
17
  PORTB &= ~(1<<RCK);
18
}
1
int main(void)
2
{
3

4
  init_sternschnuppe();
5
  //write_sternschnuppe();
6
  while(1)
7
  {
8
    write_sternschnuppe();
9
  }  
10
}

hab schon alle kombinationen probiert (nur am anfang write, nur in der 
schleife write, beides, mit spdr; ohne spdr;)

jetzt hab ich gerade die richtigen leds zum leuchten gebracht, wie ich 
den ISP stecker im laufenden betrieb angesteckt hab. wie ich dann den 
strom wieder aus/eingesteckt hab wars wieder weg...

Ok. mir is gerade das massekabel von buchsenstecker abgerissen. vll hats 
ja deshalb probleme gegeben ...
#2122581
Lesenswert?

Bitte auch mal die echte aktuelle Schaltung zeigen. Die im ersten Post 
kann ja schon mal nicht gestimmt haben. Dort sind 4 LED gegen Masse 
angeschlossen. Und die haben mich zuerst vom Antworten abgehalten, denn 
dass die oberen immer leuchten würden, habe ich gleich gesehen, konnte 
mir aber nicht erklären, warum auch die unteren 4 leuchten sollten. Wer 
weiß, was da noch so alles anders ist.
#2122610
Lesenswert?

Hab leider keinen aktuelleren schaltplan. aber die LEDs sind jetzt mit 
(+) am 7805 angehängt und mit (-) über einen 100ohm widerstand an den 
ausgängen vom schieberegister.

ich glaub ich hab jetzt nurnoch irgendwo eine schlechte verbindung 
(schlecht gelötet) weil wenn ich die kleine platine nimm (auf der das 
schieberegister und die leds draufgelötet sind und biss hin und her 
beweg leuchten manchmal die 4 LEDs auf

Edit: ok vll isses doch was anderes. Wenn ich direkt von oben auf die 
leds schau seh ich, dass sie leicht flackern ( nur die 4, die ich auf 1 
hab)

Wenn ich jetzt den ISP stecker einsteck (zum eval board) dann leuchten 
die 4 LEDs solange, bis die betriebs-LED vom evalboard leuchtet. dann 
isses wieder vorbei. allerdings solange sie leuchten leuchten sie 
richtig stark.
#2122772
Lesenswert?

grad was neues probiert, und das funktionier auch nicht:
1
void init_sternschnuppe(void)
2
{
3
  DDRB |= (1<<RCK) | (1<<SIN) | (1<<SCK);
4
  //PORTB |= (1<<RCK);
5
  //SPCR = (1 << SPE) | (1<<MSTR);
6
  //SPSR |= (1<<SPI2X);
7
}
8

9
void write_sternschnuppe(void)
10
{
11
  //SPDR = sternschnuppe_data;
12
  PORTB |= (1<<SIN);
13
  PORTB |= (1<<SCK);
14
  PORTB &= ~(1<<SCK);
15
  PORTB |= ~(1<<SIN);
16
  PORTB |= (1<<SCK);
17
  PORTB &= ~(1<<SCK);
18
  PORTB |= (1<<SCK);
19
  PORTB &= ~(1<<SCK);
20
  PORTB |= (1<<SCK);
21
  PORTB &= ~(1<<SCK);
22
  PORTB |= (1<<SCK);
23
  PORTB &= ~(1<<SCK);
24
  PORTB |= (1<<SCK);
25
  PORTB &= ~(1<<SCK);
26
  PORTB |= (1<<SCK);
27
  PORTB &= ~(1<<SCK);
28
  PORTB |= (1<<SCK);
29
  PORTB &= ~(1<<SCK);
30
    //while (!(SPSR & (1 << SPIF)));
31
  //SPDR;
32
  PORTB |= (1<<RCK);
33
  PORTB &= ~(1<<RCK);
34
}
#2122777
Lesenswert?

Schreib dir jeweils eine Funktion die ein 0-Bit ausgibt bzw ein 1 Bit 
ausgibt, mach ein _delay_ms( 1000 ) zwischen die einzelnen Schritte (so 
dass der Transfer extrem langsam abläuft) und dann geh mit einem 
Messgerät (oder zuätzlichen LED) auf die Steuerbeinchen des 595 und sieh 
nach, was dort ankommt.
1
void OutOne()
2
{
3
  PORTB |= (1<<SIN);
4

5
  _delay_ms( 1000 );
6

7
  PORTB |= (1<<SCK);
8

9
  _delay_ms( 1000 );
10

11
  PORTB &= ~(1<<SCK);  
12

13
  _delay_ms( 1000 );
14
}
15

16
void OutZero()
17
{
18
  PORTB &= ~(1<<SIN);
19

20
  _delay_ms( 1000 );
21

22
  PORTB |= (1<<SCK);
23

24
  _delay_ms( 1000 );
25

26
  PORTB &= ~(1<<SCK);  
27

28
  _delay_ms( 1000 );
29
}
30

31
void write_sternschnuppe(void)
32
{
33
  OutOne();
34
  OutZero();
35
  OutOne();
36
  OutZero();
37
  OutOne();
38
  OutZero();
39
  OutOne();
40
  OutZero();
41

42
  PORTB |= (1<<RCK);
43
  _delay_ms( 1000 );
44
  PORTB &= ~(1<<RCK);
45
  _delay_ms( 1000 );
46
}
#2123171
Lesenswert?

1
int main(void)
2
{
3
  
4
  //init_sternschnuppe();
5
  //write_sternschnuppe();
6
  DDRB |= (1<<PB4);
7
  DDRB |= (1<<PB5);
8
  DDRB |= (1<<PB7);
9
  PORTB &= ~(1<<PB5);
10
    _delay_ms(2000);
11
    PORTB |= (1<<PB7);
12
    PORTB &= ~(1<<PB7);
13
    PORTB |= (1<<PB7);
14
    PORTB &= ~(1<<PB7);
15
    PORTB |= (1<<PB7);
16
    PORTB &= ~(1<<PB7);
17
    PORTB |= (1<<PB7);
18
    PORTB &= ~(1<<PB7);
19
    PORTB |= (1<<PB7);
20
    PORTB &= ~(1<<PB7);
21
    PORTB |= (1<<PB7);
22
    PORTB &= ~(1<<PB7);
23
    PORTB |= (1<<PB7);
24
    PORTB &= ~(1<<PB7);
25
    PORTB |= (1<<PB7);
26
    PORTB &= ~(1<<PB7);
27
    
28
    
29
    
30
    PORTB |= (1<<PB4);
31
    _delay_ms(2000);
32
    PORTB &= ~(1<<PB4);
33
    _delay_ms(2000);
34
  while(1)
35
  {
36
    
37
    //write_sternschnuppe();
38
  }  
39
}

das lasst jetzt alle LEDs leuchten
allerdings hab ich da angst, dass ich meinen 7805 kill... der wird schon 
ziemlich heiß, wenn die auch nur kurz alle leuchten.. (was hoffentlich 
nicht das problem sein sollt, weil sowieso immer nur 1-2 davon leuchten 
sollen (wird ein lauflicht)
#2124009
Lesenswert?

kaum funktioniert mal was kommt auch schonwieder das nächste problem.
nach dem letzten überspielen hat ponyprog den µC nicht mehr erkannt...
d.h. wenn ich auf lesen gehe sagt er, dass nix an com3 angeschlossen ist 
(ist es aber) und die LEDs fangen auch zum blinken an (was sie vorher 
auch schon gemacht haben) eigentlich dürfte ich an den fuses nichts 
geändert haben, weil ich immer vor dem überschreiben ein load gemacht 
hab.
#2130866
Lesenswert?

So.. Hab neuen µC gekauft und alles neu gelötet.
1
#define RCK PB4
2
#define SIN PB5
3
#define SCK PB7
4

5

6
int main(void)
7
{
8
  DDRB = (1<<PB4)|(1<<PB5)|(1<<PB7);
9
    
10
  PORTB |= (1<<SIN);
11
  _delay_ms(10);
12
  
13
  PORTB |= (1<<SCK);
14
  _delay_ms(10);
15
  PORTB &= ~(1<<SCK);
16
  _delay_ms(10);
17
  
18
  PORTB |= (1<<SCK);
19
  _delay_ms(10);
20
  PORTB &= ~(1<<SCK);
21
  _delay_ms(10);
22
  
23
  PORTB |= (1<<SCK);
24
  _delay_ms(10);
25
  PORTB &= ~(1<<SCK);
26
  _delay_ms(10);
27
  
28
  PORTB |= (1<<SCK);
29
  _delay_ms(10);
30
  PORTB &= ~(1<<SCK);
31
  _delay_ms(10);
32
  
33
  PORTB &= ~(1<<SIN);
34
  _delay_ms(10);
35
  
36
  PORTB |= (1<<SCK);
37
  _delay_ms(10);
38
  PORTB &= ~(1<<SCK);
39
  _delay_ms(10);
40
  
41
  PORTB |= (1<<SCK);
42
  _delay_ms(10);
43
  PORTB &= ~(1<<SCK);
44
  _delay_ms(10);
45
  
46
  PORTB |= (1<<SCK);
47
  _delay_ms(10);
48
  PORTB &= ~(1<<SCK);
49
  _delay_ms(10);
50
  
51
  PORTB |= (1<<SCK);
52
  _delay_ms(10);
53
  PORTB &= ~(1<<SCK);
54
  _delay_ms(10);
55
  
56
  PORTB |= (1<<RCK);
57
  _delay_ms(10);
58
  PORTB &= ~(1<<RCK);
59
  _delay_ms(10);
60
  
61
  
62
  while(1)
63
  {}
64

65
  return 0;
66
}

das is ein programm zum testen. allerdings leuchten da auch alle 8 LEDs 
und nicht nur die 4, die ich will..
hab auch schon durchgetestet. die anschlüsse stimmen alle und er setzt 
sie auch auf high, wenn ichs ihm sag..
#2133848
Lesenswert?

Ok. habs jetzt soweit, dass das funktioniert:
1
void OutOne()
2
{
3
  PORTB |= (1<<SIN);
4

5
  _delay_ms( 1000 );
6

7
  PORTB |= (1<<SCK);
8

9
  _delay_ms( 1000 );
10

11
  PORTB &= ~(1<<SCK);  
12

13
  _delay_ms( 1000 );
14
}
15

16
void OutZero()
17
{
18
  PORTB &= ~(1<<SIN);
19

20
  _delay_ms( 1000 );
21

22
  PORTB |= (1<<SCK);
23

24
  _delay_ms( 1000 );
25

26
  PORTB &= ~(1<<SCK);  
27

28
  _delay_ms( 1000 );
29
}
30

31
void write_sternschnuppe(void)
32
{
33
  OutOne();
34
  OutZero();
35
  OutOne();
36
  OutZero();
37
  OutOne();
38
  OutZero();
39
  OutOne();
40
  OutZero();
41

42
  PORTB |= (1<<RCK);
43
  _delay_ms( 1000 );
44
  PORTB &= ~(1<<RCK);
45
  _delay_ms( 1000 );
46
}

aber mit spi hab ichs immer noch nicht zum laufen gebracht..

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