Hallo zusammen, nach einiger Zeit hat es mich dann doch wieder gepackt das Thema uC. Ein paar kleine Schaltungen habe ich mir wieder aufbauen können. Macht halt wieder echt Spaß! Jetzt möchte ich für den Anfang 2x Atmega8 per SPI verbinden. Da gleich die erste Frage. Reichen für die beiden Atmegas die Grundschaltung + ein Quarz beim Master oder muss der Slave auch ein Quarz haben? Benötige ich sonst noch Bauteile? Wenn dann soweit alles läuft, dann möchte ich einen der Atmega8 an meinem Pi anschließen per SPI. Projekt ist ganz einfach eine Heizkörpersteuerung. Den Pi brauche ich dann für meine Logs die UI und Netzwerk etc. Mein Atmega8 soll dann die Aufgabe haben die Temp. zu messen, und den Motor vom Thermostat zu steuern. Im Grunde genommen recht simple. Da ich mich mit dem Pi nicht so richtig auskenne, habe ich da noch ein paar Fragen. Ich habe gelesen, das der Pi nur mit 3,3V angesteuert werden kann. Die Atmega8 haben aber 5V. Passt ja nicht. Was kann ich da tun? 2te Frage ist, ist dann der Pi der Master und der Atmega8 der Slave oder umgekehrt? Hoffe ihr könnt mir bis dahin diese Fragen beantworten. Beste Dank Patrick
Patrick schrieb: > oder muss der Slave auch ein Quarz haben? Nein. Grundsätzlich brauchen beide keinen. Patrick schrieb: > Benötige ich sonst noch Bauteile? Evtl. ein paar Widerstände, damit ISP funktioniert. Patrick schrieb: > Was kann ich da tun? Einen anderen Controller nehmen. Wenn es unbedingt die alte Gurke sein muß, gibt es den Atmaga8a. Der kann von 2,7 bis 5,5V betrieben werden. Patrick schrieb: > 2te Frage ist, ist dann der Pi der Master und der Atmega8 der Slave oder > umgekehrt? Das ist egal.
:
Bearbeitet durch User
Patrick schrieb: > Ein paar kleine Schaltungen habe ich mir wieder aufbauen können. > Macht halt wieder echt Spaß! Na dann, willkommen zurück ;-) > Da gleich die erste Frage. Reichen für die beiden Atmegas die > Grundschaltung + ein Quarz beim Master oder muss der Slave auch ein > Quarz haben? Nein, eigentlich braucht keiner einen Quarz, da SPI ein synchroner Bus ist, d.h. die Taktleitung vom Master sagt den Slaves, wann ein Bit anliegt. Das Timing ist in dieser Hinsicht also "beliebig" und muss nicht wie bei UART möglichst wenig vom gewünschten Wert abweichen. Siehe auch https://www.mikrocontroller.net/articles/Serial_Peripheral_Interface > Benötige ich sonst noch Bauteile? Nein, s.o. Ich würde allerdings vielleicht eher über den UART oder I2C nachdenken, aber das ist Geschmackssache. Gehen tut auch SPI. > Ich habe gelesen, das der Pi nur mit 3,3V angesteuert werden kann. > Die Atmega8 haben aber 5V. Passt ja nicht. > Was kann ich da tun? Schau mal hier: http://www.mikrocontroller.net/articles/Pegelwandler Ansonsten könntest du auch einen neueren Mega kaufen (z.B. den Mega88), der funktioniert auch mit 3,3V. > 2te Frage ist, ist dann der Pi der Master und der Atmega8 der Slave oder > umgekehrt? Theoretisch ist das egal, da bei einer Übertragung immer beide Richtungen senden, sprich die Inhalte der SPI-Datenregister beider Teilnehmer werden getauscht. Soweit ich weiß, gibt es aber keinen Slave-Treiber für den Pi, sodass es wohl auf den Master herauslaufen wird. Edit: Da war wer schneller...
:
Bearbeitet durch User
Dann erst einmal vielen Dank für die Antworten. Dann werde ich mir mal den Artikel zum Pegelwandler durchlesen. Evtl. ist es das was ich brauche. Ansonsten werde ich schauen das ich einen anderen Avr bekomme der dann besser passt. PS: Schön wieder hier zu sein! ;)
Ich werde mir 2x Atmega88 holen und dazu noch einen Spannungswandler auf 3,3V kaufen. Damit kann ich dann sicherer Arbeiten und habe weniger Aufwand.
Beachte aber, falls deine vorhandene Spannung 5V beträgt, dass man für 5V -> 3,3V einen Low Dropout Regler nehmen muss. Beispiel: LM1117 - 3.3 Bei den "üblichen" Reglern muss die Eingangsspannung eine ganze Ecke höher sein als die Ausgangsspannung, damit sie richtig funktionieren. Alternativ könntest du die 3,3V auch einfach vom Raspberry Pi abzapfen.
:
Bearbeitet durch User
Patrick schrieb: > Jetzt möchte ich für den Anfang 2x Atmega8 per SPI verbinden. DAS ist schon generell eine überaus schlechte Idee. Denn durch diesen synchronen Bus muss der Slave immer sofort auf den Master reagieren. Das wird dir noch (wie anderen auch schon) Probleme machen. Sieh dich dazu einfach mal hier im Forum um... Ich würde für die Kommunikation zwischen µCs einen asynchronen Bus wie z.B. eine serielle Schnitte (RS232 auf mit Logikpegeln) nehmen.
:
Bearbeitet durch Moderator
Vielleicht wird es mir Probleme bereiten (gehe mal stark davon aus), aber ich will es dennoch versuchen. Das Protokoll ist wichtig. Ich habe mal eine Frage zum Code. Der Code ist jetzt stark vereinfacht. Die Kommentare die ich gemacht habe, könnt ihr mir sagen ob ich das jetzt so richtig verstanden habe.
1 | ###### Master ######
|
2 | |
3 | #ifndef F_CPU
|
4 | #define F_CPU 16000000UL
|
5 | #endif
|
6 | |
7 | #include <avr/io.h> |
8 | #include <util/delay.h> |
9 | #include <avr/interrupt.h> |
10 | |
11 | #define ACK 0x7E
|
12 | #define LONG_TIME 10000
|
13 | |
14 | |
15 | void spi_init_master (void) |
16 | {
|
17 | DDRB = (1<<5)|(1<<3); |
18 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0); |
19 | }
|
20 | |
21 | //Senden und empfangen
|
22 | unsigned char spi_tranceiver (unsigned char data) |
23 | {
|
24 | SPDR = data; //data wird in das SPDR geschoben |
25 | while(!(SPSR & (1<<SPIF) )); //Daten werden zum Slave gesendet und Daten werden vom Slave empfangen |
26 | return(SPDR); //Empfange Daten werden zurückgegeben |
27 | }
|
28 | |
29 | |
30 | void led_blink (uint16_t i) |
31 | {
|
32 | for (; i>0; --i) |
33 | {
|
34 | PORTD|=(1<<0); |
35 | _delay_ms(100); |
36 | PORTD=(0<<0); |
37 | _delay_ms(100); |
38 | }
|
39 | }
|
40 | |
41 | int main(void) |
42 | {
|
43 | spi_init_master(); |
44 | DDRD |= 0x01; |
45 | |
46 | unsigned char data; |
47 | uint8_t x = 0; |
48 | |
49 | while(1) |
50 | {
|
51 | data = 0x00; |
52 | data = spi_tranceiver(++x); |
53 | if(data == ACK) { |
54 | led_blink(x); |
55 | }
|
56 | else { |
57 | led_blink(LONG_TIME); |
58 | }
|
59 | _delay_ms(500); |
60 | }
|
61 | }
|
1 | ###### Slave ######
|
2 | |
3 | #ifndef F_CPU
|
4 | #define F_CPU 16000000UL
|
5 | #endif
|
6 | |
7 | #include <avr/io.h> |
8 | #include <avr/interrupt.h> |
9 | #include <util/delay.h> |
10 | #include "lcd.h" |
11 | |
12 | #define ACK 0x7E
|
13 | |
14 | void spi_init_slave (void) |
15 | {
|
16 | DDRB=(1<<6); |
17 | SPCR=(1<<SPE); |
18 | }
|
19 | |
20 | //Senden und empfangen
|
21 | unsigned char spi_tranceiver (unsigned char data) |
22 | {
|
23 | SPDR = data; //data wird in das SPDR geschoben |
24 | while(!(SPSR & (1<<SPIF) )); //Daten werden zum Master gesendet und Daten werden vom Master empfangen |
25 | return(SPDR); //Empfange Daten werden zurückgegeben |
26 | }
|
27 | |
28 | int main(void) |
29 | {
|
30 | spi_init_slave(); |
31 | unsigned char data, buffer[10]; |
32 | DDRA = 0x00; |
33 | PORTA = 0xFF; |
34 | while(1) |
35 | {
|
36 | data = spi_tranceiver(ACK); |
37 | itoa(data, buffer, 10); |
38 | _delay_ms(20); |
39 | }
|
40 | }
|
Patrick schrieb: > Die Kommentare die ich gemacht habe, könnt ihr mir sagen ob ich das > jetzt so richtig verstanden habe. Nein. Weißt du, was SPI ist? Das sind nur gekoppelte Schieberegister. Siehe z.B. dort das Bild in der Mitte: http://www.lothar-miller.de/s9y/archives/15-SPI.html Der Slave "sendet" da gar nichts. Das, was der Slave anzubieten hat, wird irgendwann vom Master "abgeholt". Wenn du also ein schlaues SPI Protokoll aufbaust, dann geht das so, dass der Master mit dem SPI Frame, den er jetzt sendet, vom Slave die Antwort auf den vorigen Request erhält. Der Witz dabei ist, dass du ständig versetzt bist: du bekommst zwar "sofort" mit jedem Bit, das der Master sendet, eines vom Slave zurück (weil Schieberegister), aber dieses Bit kann nicht die Reaktion auf die derzeit laufende "Anfrage" sein, weil die dem Slave ja noch gar nicht bekannt ist. Wie gesagt: du wirst stolpern. Und zur Zeit wackelst du schon, weil dir der Ablauf nicht klar ist. Dabei ist jetzt noch gar kein Protokoll, sondern nur irgendwelche abstrakten undefinierten Daten unterwegs... BTW: das wichtigste Signal zur Synchronisation ist der Slaveselect, der dem Slave sagt: "jetzt gehts los" und "jetzt sind wir fertig". Ohne den wirst du keine stabile Kommunikation hinbekommen, denn ein einzelner EMV-Spike (dein Nachbar schaltet das Licht ein) bringt den SPI zuverlässig ausser Tritt.
:
Bearbeitet durch Moderator
Nun Danke erst einmal für die Antwort. Du hast recht damit das ich vermutlich nicht alles über SPI weiß. Ich bin kein Ingenieur für Elektronik. Bin halt nur jemand der sich ein bisschen mit der Thematik auseinander setzen will um kleine Projekte umzusetzen. Das mit dem Senden und empfangen hast du vermutlich nicht so richtig verstanden. Es ist in der Tat ein "Senden" und "Empfangen" und das kann sowohl der Master als auch der Client. Hast du in deinem Artikel auch selber geschrieben. Das es gleichzeitig passiert hat ja nix damit zu tun das Daten gesenden und empfangen werden von beiden Seiten. Das die Kommunikation nur vom Master aus geht ist mir bewusst. Das der Salve im Grunde genommen einen Schritt hinter her ist. Naja man kann es halten wie man will. Auf der einen Seite ja wenn man etwas bestimmtes abfragen, dann kann man das erst im 2ten Schritt tun. Wenn jetzt wenig meinem Falle nur Sensordaten abgefragt werden, das ist mir das egal. Dann bekomme ich immer die aktuellsten Daten. Deswegen ist das Protokoll wichtig.
Patrick schrieb: > Es ist in der Tat ein "Senden" und "Empfangen" und das kann sowohl der > Master als auch der Client. Nein, das timmt so nicht: es sendet nur und ausschließlich der Master. Nur der gibt den Takt an. Und Alles andere hängt irgendwie an diesem Takt. Es ist also in der Tat ein einfaches "Durchschieben" von Datenpaketen. > Hast du in deinem Artikel auch selber geschrieben. Wenn man das so falsch verstehen kann, werde ich die Wort von "zu senden" nach "zu übertragen" ändern. Denn "senden" impliziert Aktivität: wenn ich ein Paket "versende", muss ich aktiv werden. Etwas anderes ist aber, wenn ich das Paket nur vorbereite und zum "abholen" betreitstelle. Dann ist der eigentlich Pakettransfer eine rein passive Sache (und ich muss nicht mal zu Hause sein beim "versenden"). Und selbst der Master "empfängt" auch nicht (im passiven Sinne), sondern er bekommt die Daten vom Slave nur dann, wenn er aktiv eine Übertragung durchführt. > Dann bekomme ich immer die aktuellsten Daten. Nicht unbedingt. Denn du "bekommst" vom Sensor ja gar nichts, sondern du musst es dir ständig abholen. Wenn du z.B. einen Näherungssensor einmal pro Sekunde abfrägst und der dann immer "frei" meldet, dann kann es gut sein, dass der zwischendurch für eine halbe Sekunde belegt war, du das aber gar nicht mitbekommen hast. Du musst jetzt also den Sensor vom Master aus viel, viel schneller abfragen oder den Slave intelligent machen, dass der sich dieses "belegt" merkt. Bei einer asynchronen Schnittstelle wäre dann einfach mit dem "belegt" Pegel ein Telegramm abgesetzt worden und du hättest nichts verpasst.
:
Bearbeitet durch Moderator
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.