74HC595 ohne SPI

OP #870610
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:
1
/* SERiell nach PArallel (serpa) im SPI-Protokoll */
2
#ifndef _COM74HC595_H_
3
#define _COM74HC595_H_
4

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

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

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

18
extern unsigned char com74hc595[];
19
extern void Com74hc595_out();
20
extern void Com74hc595_init();
21

22
#endif /* _COM74HC595_H_ */

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

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

7
void Com74hc595_init()
8
{
9
    /* Verwendete Ports auf OUT */
10
  DDR_COM74HC595 |= ( 1 << DDR_SER);
11
  DDR_COM74HC595 |= ( 1 << DDR_SCK);
12
  DDR_COM74HC595 |= ( 1 << DDR_RCK);
13

14

15
  PORT_COM74HC595 &= ~(1<<PORT_SER);
16
    /* SCR und RCK auf definierten Level HIGH */
17
  PORT_COM74HC595 |= (1<<PORT_SCK);
18
  PORT_COM74HC595 |= (1<<PORT_RCK);
19
}
20

21
void Com74hc595_out()
22
{
23
    unsigned char anz = COM74HC595_SIZE;
24
    unsigned char* serp = com74hc595 + COM74HC595_SIZE;
25

26
    do
27
    {
28
        unsigned char bits;
29
        unsigned char data = *--serp;
30

31
        /* 8 Bits pro Byte rausschieben */
32
        for (bits = 8; bits > 0; bits--)
33
        {
34
            PORT_COM74HC595 &= ~(1<<PORT_SER);
35
            if (data & 0x80)
36
            {
37
                PORT_COM74HC595 |= (1<<PORT_SER);
38
            };
39

40
            data <<= 1;
41
            /* Strobe an SCK schiebt Daten im Gaensemarsch */
42
            /* um 1 Position weiter durch alle Schieberegister */
43
            PORT_COM74HC595 &= ~(1<<PORT_SCK);
44
            PORT_COM74HC595 |= (1<<PORT_SCK);
45
        }
46
    }
47
    while (--anz > 0);
48

49
    /* Strobe an RCK bringt die Daten von den Schieberegistern in die Latches */
50
  PORT_COM74HC595 &= ~(1<<PORT_RCK);
51
  PORT_COM74HC595 |= (1<<PORT_RCK);
52
}
53
 
54
int main(void)
55
{
56
    Com74hc595_init();
57

58
    com74hc595[0] = 0x1;
59
    com74hc595[1] = 0x1;
60
    com74hc595[2] = 0x1;
61
    com74hc595[3] = 0x1;
62
    com74hc595[4] = 0x0;
63
    com74hc595[5] = 0x0;
64
    com74hc595[6] = 0x0;
65
    com74hc595[7] = 0x0;
66

67
    Com74hc595_out();     
68

69
    while(1)
70
    {
71
    }
72
 
73
    return 0;
74
}

Der Ursprungscode stammt übringends von hier:

http://www.roboternetz.de/wissen/index.php/Portexpander_am_AVR#Makros.2C_Datenstrukturen.2C_Funktionen

Danke für jeden Tip.

Gruß
Frank
Gast #870618
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.
OP #870629
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:
1
com74hc595[0] = 0x00000001;

korrekt muss es natürlich heißen

1
com74hc595[0] = 0b00000001;

dann funktionierts.

Danke
Gruß
Frank
#870638
Lesenswert?

Wenn
1
com74hc595[0] = 0x00000001;

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

schon, dann ist Dein C-Compiler kaputt.

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

haben keinen (von Dir gewünschten) Effekt.
OP #870674
Lesenswert?

Hallo,
1
com74hc595[0] = 0x00000000;
2
Com74hc595_out();     
3
sleep();
4
com74hc595[0] = 0x00000001;
5
Com74hc595_out();     
6
sleep();
7
com74hc595[0] = 0x00000010;
8
Com74hc595_out();     
9
sleep();
10
com74hc595[0] = 0x00000100;
11
Com74hc595_out();

ist nicht das selbe wie
1
com74hc595[0] = 0b00000000;
2
Com74hc595_out();     
3
sleep();
4
com74hc595[0] = 0b00000001;
5
Com74hc595_out();     
6
sleep();
7
com74hc595[0] = 0b00000010;
8
Com74hc595_out();     
9
sleep();
10
com74hc595[0] = 0b00000100;
11
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
Gast #870683
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.
OP #870695
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
Gast #870713
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

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