mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 74HC595 ohne SPI


Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich benötige mal Eure Hilfe, ich versuche schon den ganzen Tag die 
Routine zur Ansteuerung eines 74HC595 ohne SPI ans laufen zu bekommen.

Im Simulator sieht es gut aus, aber technisch kommt nichts an.

Header:
/* SERiell nach PArallel (serpa) im SPI-Protokoll */
#ifndef _COM74HC595_H_
#define _COM74HC595_H_

/* 4 Bytes (32 Ports) */
#define COM74HC595_SIZE 1

#define PORT_COM74HC595 PORTB
#define PORT_SER     PB0    //74HC595 PIN 14
#define PORT_SCK     PB1    //74HC595 PIN 11
#define PORT_RCK     PB2    //74HC595 PIN 12

#define DDR_COM74HC595  DDRB
#define DDR_SER     DDB0  //74HC595 PIN 14
#define DDR_SCK     DDB1  //74HC595 PIN 11
#define DDR_RCK     DDB2  //74HC595 PIN 12

extern unsigned char com74hc595[];
extern void Com74hc595_out();
extern void Com74hc595_init();

#endif /* _COM74HC595_H_ */

Main:
#include <avr/io.h>
#include "Com74hc595.h"

/* Array fuer die Daten */
unsigned char com74hc595[ COM74HC595_SIZE ];

void Com74hc595_init()
{
    /* Verwendete Ports auf OUT */
  DDR_COM74HC595 |= ( 1 << DDR_SER);
  DDR_COM74HC595 |= ( 1 << DDR_SCK);
  DDR_COM74HC595 |= ( 1 << DDR_RCK);


  PORT_COM74HC595 &= ~(1<<PORT_SER);
    /* SCR und RCK auf definierten Level HIGH */
  PORT_COM74HC595 |= (1<<PORT_SCK);
  PORT_COM74HC595 |= (1<<PORT_RCK);
}

void Com74hc595_out()
{
    unsigned char anz = COM74HC595_SIZE;
    unsigned char* serp = com74hc595 + COM74HC595_SIZE;

    do
    {
        unsigned char bits;
        unsigned char data = *--serp;

        /* 8 Bits pro Byte rausschieben */
        for (bits = 8; bits > 0; bits--)
        {
            PORT_COM74HC595 &= ~(1<<PORT_SER);
            if (data & 0x80)
            {
                PORT_COM74HC595 |= (1<<PORT_SER);
            };

            data <<= 1;
            /* Strobe an SCK schiebt Daten im Gaensemarsch */
            /* um 1 Position weiter durch alle Schieberegister */
            PORT_COM74HC595 &= ~(1<<PORT_SCK);
            PORT_COM74HC595 |= (1<<PORT_SCK);
        }
    }
    while (--anz > 0);

    /* Strobe an RCK bringt die Daten von den Schieberegistern in die Latches */
  PORT_COM74HC595 &= ~(1<<PORT_RCK);
  PORT_COM74HC595 |= (1<<PORT_RCK);
}
 
int main(void)
{
    Com74hc595_init();

    com74hc595[0] = 0x1;
    com74hc595[1] = 0x1;
    com74hc595[2] = 0x1;
    com74hc595[3] = 0x1;
    com74hc595[4] = 0x0;
    com74hc595[5] = 0x0;
    com74hc595[6] = 0x0;
    com74hc595[7] = 0x0;

    Com74hc595_out();     

    while(1)
    {
    }
 
    return 0;
}


Der Ursprungscode stammt übringends von hier:

http://www.roboternetz.de/wissen/index.php/Portexp...

Danke für jeden Tip.

Gruß
Frank

Autor: Christian Z. (christianz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dir ist klar, dass die Routine nur die 8 Bits aus com74hc595[0] ausgibt?

Autor: Ekschperde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define COM74HC595_SIZE 1

> unsigned char com74hc595[ COM74HC595_SIZE ];

passt nicht zu:

>   com74hc595[0] = 0x1;
>   com74hc595[1] = 0x1;
>   com74hc595[2] = 0x1;
>   com74hc595[3] = 0x1;
>   com74hc595[4] = 0x0;
>   com74hc595[5] = 0x0;
>   com74hc595[6] = 0x0;
>   com74hc595[7] = 0x0;

Es gibt nämlich nur:

>   com74hc595[0] = 0x1;

Da steht das ganze Byte für den 595 drin.

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke,
das wars, wenn man sich nicht jeden Tag mit c beschäftigt, interpretiert 
man bestimmte Warnings des Compilers falsch.

Der Fehler ist entstanden durch ein Warnining, in der Zuweisung:
com74hc595[0] = 0x00000001;

korrekt muss es natürlich heißen

com74hc595[0] = 0b00000001;

dann funktionierts.

Danke
Gruß
Frank

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant. Ist nämlich exakt das gleiche.

Autor: Christian Z. (christianz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn
com74hc595[0] = 0x00000001;

nicht funktioniert, aber
com74hc595[0] = 0b00000001;

schon, dann ist Dein C-Compiler kaputt.

Übrigens: Die Zeilen
com74hc595[1] = 0x1;
com74hc595[2] = 0x1;
com74hc595[3] = 0x1;
com74hc595[4] = 0x0;
com74hc595[5] = 0x0;
com74hc595[6] = 0x0;
com74hc595[7] = 0x0;

haben keinen (von Dir gewünschten) Effekt.

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
com74hc595[0] = 0x00000000;
Com74hc595_out();     
sleep();
com74hc595[0] = 0x00000001;
Com74hc595_out();     
sleep();
com74hc595[0] = 0x00000010;
Com74hc595_out();     
sleep();
com74hc595[0] = 0x00000100;
Com74hc595_out();     

ist nicht das selbe wie
com74hc595[0] = 0b00000000;
Com74hc595_out();     
sleep();
com74hc595[0] = 0b00000001;
Com74hc595_out();     
sleep();
com74hc595[0] = 0b00000010;
Com74hc595_out();     
sleep();
com74hc595[0] = 0b00000100;
Com74hc595_out();     

in der ersten Variante erhalte in in dieser Zeile einen Warning

com74hc595[0] = 0x00000100;

warning: large integer implicity truncated to unsigned type

Vielleicht kann mir jemand erklären warum?

Ich kann natürlich falsch liegen, aber "0x" ist doch Hex- und "0b" 
Binärschreibweise oder?

Gruß
Frank

Autor: Joachim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>in der ersten Variante erhalte in in dieser Zeile einen Warning
>com74hc595[0] = 0x00000100;
>warning: large integer implicity truncated to unsigned type

Weil ein CHARacter nur 8 Bit hat, 0x00000100 aber 9.

Autor: Bobby (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
0x100 passt nicht in ein Byte...

Autor: Christian Z. (christianz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar. Ich habe ja nicht geschrieben, dass
com74hc595[0] = 0x00000100;

das selbe wäre wie
com74hc595[0] = 0b00000100;

sondern nur, dass 0x1 == 0b1 ist. Das eine ist eine hexadezimale 
Darstellung, das andere eine binäre (die übrigens kein Standard-C ist).

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, ich dachte ich wäre blöd.

Deshalb ist der Wert 0x00000001 = 0b00000001 aber in der Verwendung mit 
dem Rest der Routine nicht korrekt.

Die Definition von com74hc595 ist unsigned char com74hc595 also maximal 
1 Byte.

Aber mal eine andere Frage, wie setzte ich elegant ein Bit in einem 
unsigned char bzw. nehme das Bit wieder raus.

Gruß
Frank

Autor: Christian Z. (christianz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank Link wrote:

> Aber mal eine andere Frage, wie setzte ich elegant ein Bit in einem
> unsigned char bzw. nehme das Bit wieder raus.

Das hast Du doch schon oben in Deinem Code stehen: Setzen mit
byte |= (1 << BITNR)

löschen mit
byte &= ~(1 << BITNR)

Autor: Matthias Kölling (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz verstehe ich es immer noch nicht.
Wenn
#define COM74HC595_SIZE 1
dann sind doch
com74hc595[1] = 0x1;
com74hc595[2] = 0x1;
com74hc595[3] = 0x1;
com74hc595[4] = 0x0;
com74hc595[5] = 0x0;
com74hc595[6] = 0x0;
com74hc595[7] = 0x0;
undefinierte Speicherzugriffe.
Oder sehe ich das falsch?


Gruß Matthias

Autor: Sven (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Matthias:

> Oder sehe ich das falsch?

Nein, siehst Du ganz richtig.
Array ist nur auf ...[0] definiert..

Gruß Sven

P.S.: Also mit dem Posting #1.

Autor: Frank Link (franklink)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sag ja, ich habe mich am Anfang von dem Warning des Compilers 
irritieren lassen, mein Fehler.

Jetzt läuft die ganze Sache rund.

Gruß
Frank

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.