www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik atmega32 & 74HC595 Schieberegister


Autor: Hanoii (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

versuche schon den ganzen Tag erfolglos mein 74HC595 vernünftig 
anzusteuern. Habe einfach mal drauf los getestet und probiert aber denke 
mal dass ich einfach Denkfehler oder Wissenslücken habe. Vielleicht kann 
ja mal einer drüber schauen und Tipps geben

spi.h
#ifndef SPIF
#define SPIF 7
#endif

unsigned char spi(unsigned char data)
{
SPDR=data;
while ((SPSR & (1<<SPIF))==0);
return SPDR;
}

main.c
#ifndef F_CPU
#warning "F_CPU war noch nicht definiert, wird nun mit 3686400 definiert"
#define F_CPU 16000000UL     /* Quarz mit 3.6864 Mhz  */
#endif


#include <avr\io.h>
#include <util\delay.h>
#include "spi.h"


#define DD_MOSI     PINB5

#define DD_SCK     PINB7

#define DDR_SPI    PORTB

void SPI_MasterInit(void)

{

// Set MOSI and SCK output, all others input

DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);

// Enable SPI, Master, set clock rate fck/16

SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);

}



int main(void) {

SPI_MasterInit();


  while (1)
      {
        PORTB |= (1<<PB4);
      // Place your code here
          spi(0xff);
   _delay_ms(2000);
   spi(0);
   _delay_ms(2000);
      PORTB &= ~(1<<PB4);
      
      };


}

Benutze einen atmega32 und ja ich weiss alles etwas wirsch aber wäre 
trotzdem über Hilfe dankbar.

Gruß Snaper

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hanoii schrieb:

> DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
>
> // Enable SPI, Master, set clock rate fck/16
>
> SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);

Aus dem Gedächtnis:
Du musst auch SS auf Ausgang setzen, sonst ist dein SPI kein Master.
Aber schau zur Sicherheit noch mal ins Datenblatt.

Autor: Hanoii (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay,

das habe ich zwar nicht bedacht aber dennoch ist leider noch keine 
Besserung in Sicht.

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schaltung? Was klappt eigentlich genau nicht?

Autor: Zwölf Mal Acht (hacky)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zum Einen kann man die Signale hinreichend langsam setzten, sodass man's 
auch nachmessen kann, zum Anderen gibt es auch oszilloskope.

Autor: Joachim B. (jojo84)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre auch meine Frage gewesen, was eigentlich nicht geht...

Ich hatte an meiner Schieberegisterkaskade über zwei Tage rumgedoktort, 
bis ich feststellen mußten, daß ich einen Lötfehler drin hatte... -_O

Edit: schaue er auch bitte hier (falls noch nicht geschehen):
http://www.mikrocontroller.net/articles/AVR-Tutori...

Autor: Hanoii (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also es sieht wie folgt aus. Wenn ich einen 74HC595 dran habe dann 
funktioniert es jedoch nicht mehr wenn ich 2 kaskadierte dran habe...

Bevor wieder die Frage kommt was icht genau funktioniert möchte ich 
diese natürlich vorher klären. ;) Und zwar kommt mehr oder weniger an 
den Ports nur "Mist" an. Wenn ich z.b. serpa[0] = 0xff; serpa[1] = 0xff; 
schreibe dann sollten ja alle Ports durchschalten aber es sind nur 
vereinzelt LEDs an bzw werden nur einzelne Ports durchgeschaltet. 
Atmega32 @16Mhz wird genutzt. Für Hilfe wäre ich sehr dankbar.

Folgenden Code nehme ich dazu:
serpa.h
/* SERiell nach PArallel (serpa) im SPI-Protokoll */
#ifndef _SERPA_H_
#define _SERPA_H_

/* 4 Bytes (32 Ports) */
#define SERPA_SIZE 2 
/* Das muss auf 1 sein, wenn man nur ein Schieberegister benutzt ... das wir dauch bei dem serp-- und so benutzt.*/

extern unsigned char serpa[];
extern void serpa_out (void);
extern void serpa_init (void);

#endif /* _SERPA_H_ */

//SERPA.h ende ------------------------


schiebe.c
#ifndef F_CPU
#define F_CPU 16000000UL
#endif

// SERiell nach PArallel (serpa) mit Hardware-Unterstuetzung 
#include <avr/io.h>
#include "serpa.h"
#include <util\delay.h>

unsigned char serpa[SERPA_SIZE];
unsigned char maske(unsigned char input);

// Array fuer die Daten 

void serpa_init (void)
{

   DDRB=0xff;
   PORTB |= (1<<PB4);

   // !!! SS muss OUT sein, damit SPI nicht in Slave-Mode wechselt !!! 
   // entfaellt, falls PORT_RCK = PORT_SS 

   // SPI als Master 
   // High-Bits zuerst 
   // SCK ist HIGH wenn inaktiv 
   SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL);
  
   // pullup an MISO vermeidet Floaten 
   PORTB |=(1<<PB6);

   // maximale Geschwindigkeit: F_CPU / 2 
   SPSR |= (1 << SPI2X);
}

void serpa_out (void)
{
   
   unsigned char anz = SERPA_SIZE;
   unsigned char* serp = serpa+SERPA_SIZE;

   do
   {
      unsigned char data = *--serp;

      // SPDR schreiben startet Uebertragung 
      SPDR = data;

      // warten auf Ende der Uebertragung für dieses Byte 
      while (!(SPSR & (1 << SPIF)));

      // clear SPIF durch Lesen von SPDR 
      SPDR;
   }
   while (--anz > 0);
  

   // Strobe an RCK bringt die Daten von den Schieberegistern in die Latches 
   PORTB &=~ (1<<PB4);
   PORTB |= (1<<PB4);
}

int main (void)
{
  serpa_init();
  while(1)
  {
    

  serpa[0] = 0xff;
  serpa[1] = 0xff;
  serpa_out();
  }
}

unsigned char maske(unsigned char input)
{
  return 0xFF ^ input;
}
  


Autor: Hanoii (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So langsam schließe ich einen Softwarefehler aus also das Problem ist, 
dass die Nullen nahezu "verschluckt" werden. Wenn ich auf beide 0xff 
schreibe, dann gehen alle an aber sobald ich eine Null drin habe geht es 
den Bach runter und es kommen ziemlich "wilde" Zustände zum vorschein. 
Woran könnte dies liegen?

Ein Oszi habe ich leider nicht sodass ich mir das Signal nicht richtig 
angucken kann leider.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was passiert, wenn du hier

>    // maximale Geschwindigkeit: F_CPU / 2
>   SPSR |= (1 << SPI2X);

probehalber mal weniger Vollgas gibst?

Autor: Hanoii (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe den Fehler beheben können und zwar war die Lösung des Rätsels 
folgende:

Die Vcc und GNDs der beiden einzelnen ICs weiter weg stecken und 
möglichst IC nahe jedem der beiden ICs ein Entstörkondensator spendiert. 
Ergo war wohl etwas zu viel "Noise" auf der Leitung und das macht sich 
bei denen wohl schnell bemerkbar. Habe ich aber nur durch Zufall herraus 
gefunden da ich die Schaltung nochmal neu gesteckt habe.

Naja aus Fehlern lernt man. :)

Aber vielen dank für eure Tipps.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.