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
voidspi_shift(uint8_tdata1)
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.
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
@ 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.
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.
@ 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.
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.
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.
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
voidspi_shift(uint8_tdata1)
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.
@ 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.
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
intmain(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.
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.