C: Problem mit Schieberegister 74HC595 (Ausgänge immer HIGH)

OP #2513438
Lesenswert?
• ▲
▼
Hallo,

ich möchte mit einem Attiny45 ein Schieberegister ansteuern.
Leider bekomme ich das noch nicht ganz gebacken...
Und zwar habe ich an jedem der 8 Ausgangspins des Registers eine LED 
hängen.
Aktuell leuchten immer alle LEDs. Selbst wenn ich vorher nichtmal 
serpa_init() oder serpa_out() aufrufe.
Liegt es womöglich an meiner Verkabelung?
PB3=STCP/RCK
PB4=CLK/SCK/SHCP
PB5=SER/DS
MR direkt auf +5V
OE direkt auf GND

Hier mein C-Code (wahrscheinlich aber nicht das Problem, siehe unten):
1
/* Quelle: http://www.rn-wissen.de/index.php/Portexpander_am_AVR#Mit_SPI-Hardware_2 */
2

3
/* SERiell nach PArallel (serpa) via Software */
4
#include <avr/io.h>
5
#include "serpa.h"
6

7
#define SET(port,b) (port) |= (1<<(b))
8
#define CLR(port,b) (port) &= ~(1<<(b))
9

10
/* Array fuer die Daten */
11
unsigned char serpa[SERPA_SIZE];
12

13
void serpa_init (void)
14
{
15
    /* Verwendete Ports auf OUT */
16
  /* PB3=STCP/RCK, PB4=CLK/SCK/SHCP, PB5=SER/DS
17
  MR auf +5V
18
  OE auf GND */
19
  DDRB = (1 << DDB3) | (1 << DDB4) | (1 << DDB5);
20

21
    /* SCR und RCK auf definierten Level HIGH */
22
    SET (PORTB, PB4);
23
    SET (PORTB, PB3);
24
}
25

26
void serpa_out (void)
27
{
28
    unsigned char anz = SERPA_SIZE;
29
    unsigned char* serp = serpa+SERPA_SIZE;
30

31
    do
32
    {
33
        unsigned char bits;
34
        unsigned char data = *--serp;
35

36
        /* 8 Bits pro Byte rausschieben */
37
        for (bits = 8; bits > 0; bits--)
38
        {
39
            CLR (PORTB, PB5);
40
            if (data & 0x80)
41
            {
42
                SET (PORTB, PB5);
43
            }
44

45
            data <<= 1;
46
            /* Strobe an SCK schiebt Daten im Gaensemarsch */
47
            /* um 1 Position weiter durch alle Schieberegister */
48
            CLR (PORTB, PB4);
49
            SET (PORTB, PB4);
50
        }
51
    }
52
    while (--anz > 0);
53

54
    /* Strobe an RCK bringt die Daten von den Schieberegistern in die Latches */
55
    CLR (PORTB, PB3);
56
    SET (PORTB, PB3);
57
}
58

59
int main(void) {
60
  serpa_init();
61
  while (1) {
62
    serpa[0]=0b10000001;
63
    serpa_out();
64
  }
65
}

Da es aber unabhängig vom Programm zu sein scheint, tippe ich eher auf 
einen Verkabelungsfehler.
Passt das mit MR auf 5V und OE auf GND (habe da einfach jeweils eine 
Drahtbrücke gesteckt)?

Vielen Dank für die Hilfe.
Gast #2513470
Lesenswert?
• ▲
▼
AVR-Tutorial: Schieberegister

> Passt das mit MR auf 5V und OE auf GND (habe da einfach jeweils eine
> Drahtbrücke gesteckt)?

Ja.

Wie ist SERPA_SIZE definiert?
Dein main() geht von 1 aus.

> Und zwar habe ich an jedem der 8 Ausgangspins des Registers eine LED
> hängen.
> Aktuell leuchten immer alle LEDs. Selbst wenn ich vorher nichtmal
> serpa_init() oder serpa_out() aufrufe.
> Liegt es womöglich an meiner Verkabelung?

Wohlmöglich, leider sehen wir die nicht, weil der Schaltplan fehlt.

Bist du sicher, dass das richtige Programm im AVR ist und du nicht 
ständig das falsche HEX-File flashst ("beliebtes" AVR-Studio Problem).
OP #2513682
Lesenswert?
• ▲
▼
SERPA_SIZE habe ich auf 1 gestellt.

Die passende Datei wird auch übertragen
(mit der zusätzlichen serpa.h muss ich ja nichts mehr machen, wenn ich 
die als zusätzliches File dazugelegt habe und der Compiler auch keine 
Fehler auswirft, oder?)

Habe den Controller gerade auch nochmal komplett gelöscht und jetzt nur 
unter "Flash" das Hexfile draufgeladen (Controller war vorher nämlich 
bei einem anderen Textprojekt im Einsatz)

Habe eben auch einen Schaltplan entworfen und ihn angehängt.

Wie gesagt: Es leuchten einfach alle LEDs...
(Später ist normal eh nur eine an, weshalb die hier direkt am 74HC595 
hängen)
Angehängte Dateien:
Gast #2513709
Lesenswert?
• ▲
▼
SET (PORTB, PB4);
verschieb  das mal am Anfang der Schleife, und wenn die schleife beendet 
wurd.
1
     for (bits = 8; bits > 0; bits--)
2
        {
3
            SET (PORTB, PB4);
4
            CLR (PORTB, PB5);
5
            if (data & 0x80)
6
            {
7
                SET (PORTB, PB5);
8
            }
9

10
            data <<= 1;
11
            /* Strobe an SCK schiebt Daten im Gaensemarsch */
12
            /* um 1 Position weiter durch alle Schieberegister */
13
            CLR (PORTB, PB4);
14
          
15
        }
16
    }
17
    while (--anz > 0);
18
     SET (PORTB, PB4);
OP #2513727
Lesenswert?
• ▲
▼
Oh, den Reset-Widerstand im Schaltplan ganz vergessen.
Aso das hab ich garnicht bedacht (außerdem hängt dann SER ja immer über 
den Widerstand an +5V...)
umsteck und umprogrammier
Hach, ja...ES GEHT :)

Dankeschön. Ich hätte jetzt noch ewig gesucht^^
Schönen Sonntag noch an alle :)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren