Forum: Compiler & IDEs spdr mit avr


von Udo S. (Firma: allround) (1udo1)


Lesenswert?

Hallo,

wenn ein Byte in das Register SPDR geschrieben wird, dann beginnt 
automatisch die Übertragung an den Slave. Der SHIFT-Takt wird vom AVR 
selber generiert.

MEGA8

Meine Frage:

1
void spi_shift(uint8_t data1)
2
{
3
        SPDR = data1;            //=== Start transmission
4
  
5
  while(!(SPSR & (1<<SPIF))); // warten, bis Übertragung zu Ende ist
6
7
        PORTB=1<<PB2;                 // Store
8
}


Generiert der AVR den /SS PIN ebenfalls eigenständig? Auf dem 
Oszilloskope kann ich kein LOW am PIN /SS sehen.


In meinem Programm, welches funktioniert, ist der PIN /SS nicht auf LOW 
gesetzt, sondern hat permanent HIGH-Pegel laut Oszilloskop.

von Oliver S. (oliverso)


Lesenswert?

Zu dem Prozessor gibt es ein Datenblatt. In den steht ein eigenes 
(kurzes) Kapitel über den SS-Pin, und wie der wann wie bedient werden 
muß.

RTFM

Oliver

von Falk B. (falk)


Lesenswert?

@ Udo Scharnitzki (Firma: allround) (1udo1)

>wenn ein Byte in das Register SPDR geschrieben wird, dann beginnt
>automatisch die Übertragung an den Slave. Der SHIFT-Takt wird vom AVR
>selber generiert.

Ja.


>Generiert der AVR den /SS PIN ebenfalls eigenständig?

Nein, muss man per Software machen.

>Auf dem
>Oszilloskope kann ich kein LOW am PIN /SS sehen.

>In meinem Programm, welches funktioniert, ist der PIN /SS nicht auf LOW
>gesetzt, sondern hat permanent HIGH-Pegel laut Oszilloskop.

Weil du ihn nicht auf LOW setzt.

von Udo S. (Firma: allround) (1udo1)


Lesenswert?

Falk Brunner schrieb:
>
>>Generiert der AVR den /SS PIN ebenfalls eigenständig?
>
> Nein, muss man per Software machen.
>
Das man per Software den /SS auf LOW setzen muss habe ich gelesen. Aber 
warum funktioniert mein Programm, obwohl ich an keiner Stelle PB5 (/SS) 
auf LOW setze. Im Beispiel des Datenblattes wurde das auch nicht 
gemacht.

Hier das kleine komplette Testprogramm. PB5 wird nirgendwo auf LOW 
gesetzt.

Ich setze nur PB2, um das SHiftRegister des 74HCT595 auf den Ausgang zu 
legen.
1
// SPI mit 74HCT595 2 Bytes  an 2 ICs 74HCT595
2
3
#define F_CPU  12000000UL
4
#include <stdio.h>
5
#include <avr/io.h>
6
#include <avr/interrupt.h>
7
8
volatile uint8_t data1=3, data2=3, count;
9
10
11
//#########################################################################
12
13
void spi_shift(uint8_t data1, uint8_t data2)
14
{
15
  
16
  SPDR = data1;    //=== Start transmission
17
  
18
  while(!(SPSR & (1<<SPIF))); // warten, bis Übertragung zuende ist
19
  
20
  SPDR=data2;
21
  
22
  while(!(SPSR & (1<<SPIF))); // warten, bis Übertragung zuende ist
23
  
24
  PORTB=1<<PB2;// Store
25
  
26
  
27
}
28
//########################################################################
29
30
void HC595Init()
31
{
32
DDRB = (1<<DDB2)|(1<<DDB3)|(1<<DDB5);   // DDB2 ist SS DDB3 ist MOSI, DDB5 ist SCK
33
    
34
SPCR |= (1<<SPE) | (1<<MSTR) | (1<<CPHA) | (1<<CPOL) | (1<<SPR0);// enable | master | CPHA | 1/16clk
35
36
}
37
//############################################################################
38
39
int main(void)
40
{
41
  HC595Init();
42
  while(1)
43
  {
44
    spi_shift(data1,data2);
45
  }
46
}

von Falk B. (falk)


Lesenswert?

@ Udo Scharnitzki (Firma: allround) (1udo1)

>Das man per Software den /SS auf LOW setzen muss habe ich gelesen. Aber
>warum funktioniert mein Programm,

Woher soll ich das wissen? Ich kenne deine Schaltung doch gar nicht. 
Siehe Netiquette.

>obwohl ich an keiner Stelle PB5 (/SS)
>auf LOW setze. Im Beispiel des Datenblattes wurde das auch nicht
>gemacht.

Nach dem Reset ist es garantiert LOW. Darum geht das 1. Mal.

Lass man deine Funktion mit Pause zweimal laufen. Das 2. Mal geht sie 
nicht.

von Oliver S. (oliverso)


Lesenswert?

Udo Scharnitzki schrieb:
> Das man per Software den /SS auf LOW setzen muss habe ich gelesen.

Wo denn?

zum Master Mode steht das hier im Datenblatt:
1
When the SPI is configured as a Master (MSTR in SPCR is set), the user can determine the
2
direction of the SS pin.
3
If SS is configured as an output, the pin is a general output pin which does not affect the SPI
4
system. Typically, the pin will be driving the SS pin of the SPI Slave.
5
If SS is configured as an input, it must be held high to ensure Master SPI operation.
6
...

Oliver

von Udo S. (Firma: allround) (1udo1)


Lesenswert?

Falk Brunner schrieb:
> @ Udo Scharnitzki (Firma: allround) (1udo1)
>
>>Das man per Software den /SS auf LOW setzen muss habe ich gelesen. Aber
>>warum funktioniert mein Programm,
>
> Woher soll ich das wissen? Ich kenne deine Schaltung doch gar nicht.
> Siehe Netiquette.
>
>>Ich habe oben geschrieben, dass!!! es funktioniert. Netiquette erfüllt? oder 
nicht!!
>
> Nach dem Reset ist es garantiert LOW. Darum geht das 1. Mal.
>
> Lass man deine Funktion mit Pause zweimal laufen. Das 2. Mal geht sie
> nicht.

Habe 20 bis 30 Mal Bytes rübergeschickt--- alles ok. das Programm 
funktioniert. Deshalb verstehe ich nicht, warum /SS gesetzt werden muss. 
Es geht komischerweise auch ohne LOW setzen.

von Karl H. (kbuchegg)


Lesenswert?

Udo Scharnitzki schrieb:

> funktioniert. Deshalb verstehe ich nicht, warum /SS gesetzt werden muss.
> Es geht komischerweise auch ohne LOW setzen.

Ob das komisch ist oder nicht, kann man ohne Programmcode nicht 
entscheiden.

Tatsache ist, dass es bei einem auf Output gesetzten SS-Pin völlig 
wurscht ist, ob der Pin auf Low oder auf High ist. Die SPI Einheit im 
Mega8 arbeitet bei einem auf OUtput gesetzten SS-Pin als Master so wie 
sie soll. Unabhängig vom Pegel des SS-Pins.

Daher: Hast du SS auf Ausgang gesetzt?
Ja?
Dann ist es wurscht (für den Mega), ob der Pin auf Low oder auf High 
ist.

Da du aber anscheinend die RCLK (die du Store nennst) Leitung vom 595 an 
diesen Pin angeschlossen hast, ist es für den 595 NICHT wurscht, welcher 
Pegel vorliegt. Bzw. eigentlich welche Flanke dort gezeigt wird.

von Karl H. (kbuchegg)


Lesenswert?

PS:

Hier wäre es gut, den Pegel am 'STore' des 595 gleich wieder zurück zu 
nehmen. Und es wäre auch gut, tatsächlich nur den einen Pin zu 
verändern, der zum 'Store' des 595 führt.
1
void spi_shift(uint8_t data1)
2
{
3
  SPDR = data1;            //=== Start transmission
4
  
5
  while(!(SPSR & (1<<SPIF))); // warten, bis Übertragung zu Ende ist
6
7
  PORTB |= 1<<PB2;                 // Store
8
  PORTB &= ~( 1<<PB2);
9
}

Solche Port-Rundumschlag Aktionen, mit Zuweisung zum kompletten Port 
ohne Rücksicht auf Verluste, sind ein recht sicherer Stolperstein für 
die Zukunft.

von Falk B. (falk)


Lesenswert?

@ Udo Scharnitzki (Firma: allround) (1udo1)

>Habe 20 bis 30 Mal Bytes rübergeschickt--- alles ok.

KAUM. In deinem Programm wird EINMALIG zwei Bytes gesendet und ENMALIG 
PB2 auf HIGH gesetzt.

Wenn du dein Programm 30 mal mit neuen Werten kompilierst und neu 
startest, ist das was ANDERES, als im Programm 30 mal die Funktion 
spi_shift(data1,data2) aufzurufen.

von Karl H. (kbuchegg)


Lesenswert?

Falk Brunner schrieb:
> @ Udo Scharnitzki (Firma: allround) (1udo1)
>
>>Habe 20 bis 30 Mal Bytes rübergeschickt--- alles ok.
>
> KAUM. In deinem Programm wird EINMALIG zwei Bytes gesendet und ENMALIG
> PB2 auf HIGH gesetzt.
>
> Wenn du dein Programm 30 mal mit neuen Werten kompilierst und neu
> startest, ist das was ANDERES, als im Programm 30 mal die Funktion
> spi_shift(data1,data2) aufzurufen.

Yep.
Das ist daher ein typischer Fall von: Das Testprogramm ist scheisse. Es 
testet nicht das, was es soll.
1
int main(void)
2
{
3
  HC595Init();
4
  while(1)
5
  {
6
    spi_shift(data1,data2);
7
8
    data2++;
9
    if( data2 == 0)
10
      data1++;
11
12
    _delay_ms( 100 );
13
  }
14
}
so sieht das dann schon viel besser aus. Entweder die Ausgänge zählen 
hoch oder sie tun das nicht. In Udo's Originalversion tun sie es nicht.

von Karl H. (kbuchegg)


Lesenswert?

Udo Scharnitzki schrieb:

> warum funktioniert mein Programm, obwohl ich an keiner Stelle PB5 (/SS)

> Hier das kleine komplette Testprogramm. PB5 wird nirgendwo auf LOW
> gesetzt.

PB5?
Wieso PB5?

Laut deinem Kommentar, ist PB5 die Clock Leitung.
SS ist, wieder laut deinem Kommentar
> DDRB = (1<<DDB2)|(1<<DDB3)|(1<<DDB5);   // DDB2 ist SS DDB3 ist MOSI, DDB5 ist 
SCK

auf PB2 zu finden?


Mehr Sorgfalt! Sonst erleidest du ganz schnell ganz entsetzlich 
Schiffbruch. Wnn du schon Kommentare schreibst, dann müssen die auch 
stimmen! Wenn es eine Möglichkeit gibt, keinen Kommentar zu benötigen 
(zb indem man den Pins per #define 'sprechende Namen' gibt) dann ist 
diese Version vorzuziehen und der Kommentar einzusparen. Ein
1
#define SS   PB2
2
#define MOSI PB3
3
#define SCK  PB5
4
...
5
6
  DDRB = (1<<SS)|(1<<MOSI)|(1<<SCK);
braucht beim DDR keinen Kommentar. Im besten Fall erzählt er mir nichts 
neues. Im schlimmsten Fall wäre er einfach nur falsch.

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.