Forum: Mikrocontroller und Digitale Elektronik SPI-Test 74HC595


von Dietmar P. (dietmar2)


Lesenswert?

Hallo,

ich taste mich an das SPI heran und habe wohl gleich einen Schritt ins 
Leere gemacht.

Die Hardware Hardware besteht aus dem µC Atmega 169 (Butterfly) und 
einem 74HC595, Ausgangsseitig habe ich 8 LED's.
Aus dem Datenblatt und Beispielen hier im Forum habe ich mir ein 
Testprogramm zusammen gestrickt.
Das Compilieren und Flashen (via ISP - Druckerschnittstelle) läuft ohne 
Feher, nur meine LED's rühren sich nicht.
Hier mein C-Programm. Kann mir jemand sagen wo da mein Fehler ist?
1
/* SPI-Test.c */
2
3
#include <stdio.h>
4
#include <avr/io.h>
5
#include <avr/interrupt.h>
6
#include "util/delay.h"
7
8
void spi_Masterinit (void); 
9
void spi_Mastershiftout(uint8_t data);
10
11
#ifndef F_CPU
12
#define F_CPU 10000000UL     // Takt CPU wird auf 1Mhz gesetzt
13
#endif
14
15
int main(void)
16
{  
17
  void spi_Masterinit (void) {
18
   // Set MOSI and SCK
19
   DDRB = (1<<DDB2)|(1<<DDB1);   // DDB2 is MOSI, DDB1 is SCK
20
   // enable|as master|CPHA|1/16clk 
21
   SPCR |= (1<<6)|(1<<4)|(1<<2)|(1<<0);
22
  }
23
24
  char data=170;
25
26
  while(1){ 
27
28
    void spi_Mastershiftout(char data){
29
     //=== Start transmission 
30
     SPDR = data;
31
     //=== Wait for transmission complete (bit7 in SPSR get 1) 
32
     while(!(SPSR & (1<<7))); //7=SPIF bit in SPSR
33
    }//spi_writetoshift
34
35
  }  //while 
36
   for(;;); 
37
} /* end main */

Dank für Eure Hilfe
Gruß
Dietmar

von Jens P. (picler)


Lesenswert?

Ob die SPI-Hardware des AVR den 595 ansteuern kann, weiß ich nicht. Auf 
jeden Fall ist der 595 nur ein simples serielles Schieberegister, bei 
dem ausgangsseitig ein paar Besonderheiten zu beachten sind. Es gibt 
einen Freigabeeingang, mit dem die Ausgänge aktiviert werden und ein 
Steuereingang für das Ausgangslatch. Damit kann man nach erfolgtem 
Schieben den Inhalt des SR an die Ausgänge schicken. Diese Lösung 
verhindert, dass die Ausgangspins während des Schiebens undefinierte 
Zustände einnehmen.

Ich vermut, dass dort dein Problem liegt, denn falls die Kommunikation 
mit den Controller nicht sauber läuft, würde zumindest irgendwas bei den 
LEDs passieren.

von Michael U. (amiga)


Lesenswert?

Hallo,

Pin /SS muß Ausgang sein oder wenn Eingang, dann auf L, damit der SPI im 
Master-Mode ist.

-> Datenblatt AVR

Gruß aus Berlin
Michael

von Kollektiv (Gast)


Lesenswert?

Genau, es muss der zweite CLK Pin beschaltet werden, und du brauchst den 
Latch Puls. Siehe: 
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister

Warum deklarierst du die Funktion innerhalb der main()?

von Peter D. (peda)


Lesenswert?

Du hast spi_Mastershiftout() etwas unüblich definiert. Funktionen 
definiert man besser außerhalb von Funktionen.

Aber Du rufst es nirgends auf.

Und Du muß noch RCLK takten, sonst wird nix übernommen.


Peter

von Kollektiv (Gast)


Lesenswert?

while(!(SPSR & (1<<7))); //7=SPIF bit in SPSR
geht auch so mit gcc:
 while(!(SPSR & (1<<SPIF)));

Die Prüfung wird sinnvollerweise vor dem SPDR-Zugriff gemacht, so 
vertrödelst Du ja den Vorteil der SPI Hardware - das unabhängige 
Arbeiten.
Dann muss aber das SPIF einmal gesetzt werden (sonst while->endlos). Im 
Tutorial erfolgt dazu  bei der Initialisierung ein dummy-read, da man 
das Bit nicht manuell schreiben kann.

von Marcus O. (marcus6100)


Lesenswert?

Dietmar P. schrieb:
> int main(void)
> {
>
>   void spi_Masterinit (void) {
>
[...]
>
>   }
>

>   while(1){
>     void spi_Mastershiftout(char data){

und das compiliert?

Du solltest Funktionen nicht schachteln.

Falls das wirklich compiliert, wird jedenfalls
spi_Mastershiftout nicht aufgerufen, weil es
nicht aufgerufen wird, sondern nur eine Definition
ist.

Außerdem must du noch den Slave Select (SS) Pin auf
Output schalten.

von Sven K. (svenk)


Lesenswert?

Hi,

also compilieren wird das wohl,
aber da wird mindestens mal ein Warning geschissen !
Aber wir wissen ja, Warnings muss man nicht lesen ;-)
Ebenso ist F_CPU nicht 1 Mhz sondern 10 Mhz.
Exemplarisch mal im Anhang wie es aussehen könnte.
Schliesse mich da den Vorpostern an.

#define F_CPU  1000000UL

#include <stdio.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include "util/delay.h"


void spi_Masterinit (void)
{
 ...........
}

void spi_Mastershiftout(char data)
{
 ............
}

int main(void)
{
  spi_Masterinit();

  unsigned char data=170;

  while(1){

    spi_Mastershiftout(data);

  }
}

von Dietmar P. (dietmar2)


Lesenswert?

Danke, danke,

für Eure hilfreichen Informationen.
Jetzt muss ich das alles erst einmal umsetzen und den SS einbauen.

Werde mich dann nochmals melden.

Gruß
Dietmar

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.