Forum: Mikrocontroller und Digitale Elektronik 2x Atmega8 SPI Schaltung / Raspberry Pi - Atmega8 SPI Schaltung


von Patrick (Gast)


Lesenswert?

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

von Thomas E. (thomase)


Lesenswert?

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
von Robin S. (der_r)


Lesenswert?

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
von Patrick (Gast)


Lesenswert?

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! ;)

von Patrick (Gast)


Lesenswert?

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.

von Robin S. (der_r)


Lesenswert?

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
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Patrick (Gast)


Lesenswert?

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
}

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Patrick (Gast)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
Noch kein Account? Hier anmelden.