Forum: Mikrocontroller und Digitale Elektronik 74HC165 auslesen C


von Markus C. (ljmarkus)


Lesenswert?

Hallo..

ich stehe gerade etwas auf dem Schlauch, so schweer kann es ja 
eigendlich nicht sein einen HC165 auszulesen.

AVR = mega8

Pinbelegung:

Pin1(-PL) = PB6
Pin2(CP) = PB5(SCK)
Pin9(Q7) = PB4(MISO)
Pin10 und 15 fest auf GND

Ich finde gerade keinen Ansatzt das Teil auszulesen in C.
in Value_HC165 soll der eingelesene Wert stehen.

Hätte von euch einer einen Code für mich ?


Vielen Dank, Markus

von Karl H. (kbuchegg)


Lesenswert?

Markus C. schrieb:
> Hallo..
>
> ich stehe gerade etwas auf dem Schlauch, so schweer kann es ja
> eigendlich nicht sein einen HC165 auszulesen.

An welcher Stelle hast du Schwierigkeiten?

Hier steht eigentlich ganz gut, was du alles machen musst.
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister#Porterweiterung_f.C3.BCr_Eing.C3.A4nge


  PL einmal kurz 0/1 toggeln. Dabei sollte CLK auf 1 stehen

Damit sind die Daten im Schieberegister.

Danach mit 8 Clock-Pulsen die Bits rausschieben. (Clock Enable nicht 
vergessen). Vom Pin-Register im µC den jeweils nächsten Wert auslesen 
und mit einer << Operationen und einmaskieren und zu einem Byte 
zusammensetzen. Das macht man sinnvollerweise in einer Schleife.

Fertig.
Also: Wobei hast du Probleme?

von Route_66 (Gast)


Lesenswert?

Was hast Du denn schon? Eventuell können wir den Fehler finden.

von Markus C. (ljmarkus)


Lesenswert?

Hi.

hier mein Code ausschnitt:
1
void read_HC165(char* pBytes, char num_bytes)
2
{
3
  PORTB |= (1<<PB5);    //SCK = 0;
4
  PORTB |= (1<<PB6);    // PB6 = 0;
5
  PORTB &= ~(1<<PB6);    // PB6 = 1;
6
  
7
  for (char i=0; i<num_bytes; ++i)
8
  {
9
  *pBytes = 0;
10
  DDRB &= ~(1<<PB4);    // PB4 als Eingang
11
  PORTB &= ~(1<<PB4);    // Pullup aus
12
    
13
  for (char j=0; j<8; ++j)
14
  {
15
      *pBytes |= PINB4;
16
      if (j<7) *pBytes<<=1;
17
      PORTB &= ~(1<<PB5);  //SCK = 1;
18
      PORTB |= (1<<PB5);  //SCK = 0;
19
  }
20
  ++pBytes;
21
  }
22
}

lg, markus

von Route_66 (Gast)


Lesenswert?

>  PORTB |= (1<<PB6);    // PB6 = 0;
  PORTB &= ~(1<<PB6);    // PB6 = 1;

setzt PB6 genau umgekehrt

von Markus C. (ljmarkus)


Lesenswert?

Hi.

jo da hast Du Recht. Habe ich geändert überall.

wenn ich in der Main aufrufe:


unsigned int value_165;

read_HC165(value_165,8);


bekomme ich folgende Medlung:
makes pointer from integer without cast


lg, markus

von Codebegugger (Gast)


Lesenswert?

dann schau dir die Zeile in einem Code mal genauer an:
1
void read_HC165(char* pBytes, char num_bytes)

von Codebegugger2 (Gast)


Lesenswert?

und überprüfe dein Aufruf:
1
read_HC165(value_165,8);
;

von Karl H. (kbuchegg)


Lesenswert?

Codebegugger2 schrieb:
> und überprüfe dein Aufruf:
>
>
1
read_HC165(value_165,8);
;

Und wenn du das dann korregiert hast, solltest du dir die Frage stellen, 
was wohl passiert, wenn du ab der Startadresse eines unsigned int 8 
Bytes schreiben lässt.

Das
1
  for (char j=0; j<8; ++j)
2
  {
3
      *pBytes |= PINB4;
4
      if (j<7) *pBytes<<=1;
5
      PORTB &= ~(1<<PB5);  //SCK = 1;
6
      PORTB |= (1<<PB5);  //SCK = 0;
7
  }

sieht auch nicht richtig aus
1
  for (char j=0; j<8; ++j)
2
  {
3
      *pBytes <<= 1;
4
      if( PINB & ( 1 << PB4 ) )
5
        *pBytes |= 0x01;
6
      PORTB &= ~(1<<PB5);  //SCK = 1;
7
      PORTB |= (1<<PB5);  //SCK = 0;
8
  }

Hmm. Ich weiss jetzt nicht auswändig, ob der Clock Puls vor oder nach 
dem Abfragen des Pins kommen muss.

von Markus C. (ljmarkus)


Lesenswert?

hmm, sehe da gerade nix. Außer das value_HC165 als unsigned int gesetzt 
ist. auch wenn ich es als char mach geht es nicht.

lg, markus

von Karl H. (kbuchegg)


Lesenswert?

Markus C. schrieb:
> hmm, sehe da gerade nix. Außer das value_HC165 als unsigned int gesetzt
> ist. auch wenn ich es als char mach geht es nicht.

Deine Funktion will die Adresse(!) haben, ab der sie das Gelesene 
ablegen soll. Du gibst ihr den Inhalt von value_165

Wieviele Schieberegister hast du da eigentlich kaskadiert? Wenn es nur 
eines ist, dann kann man die Funktion auch einfacher schreiben mit der 
Signatur
1
unsigned char read_HC165(void)
2
{
3
  unsigned char result;
4
5
  ...
6
7
  return result;
8
}

und dann
1
  value_165 = read_HC165();

von Markus C. (ljmarkus)


Lesenswert?

Hallo..

ich habe nur 1 Schieberegister drann.


lg, markus

von Karl H. (kbuchegg)


Lesenswert?

Markus C. schrieb:
> Hallo..
>
> ich habe nur 1 Schieberegister drann.

Wozu dann der Rundumschlag mit der Monsterroutine ?

(Lass mich raten: Weil das dort wo du sie geklaut hast, auch so war :-)

von Markus C. (ljmarkus)


Lesenswert?

ja irgendwie schon....

von Karl H. (kbuchegg)


Lesenswert?

Markus C. schrieb:
> ja irgendwie schon....

Daran ist nichts verwerfliches. Aber gewöhn dir an, Code nicht einfach 
so zu übernehmen sondern ihn zu überfliegen und zu überlegen, wie er 
funktioniert. Vor allen bei so kleinen Routinen.

von Karl H. (kbuchegg)


Lesenswert?

Karl heinz Buchegger schrieb:

> Hmm. Ich weiss jetzt nicht auswändig, ob der Clock Puls vor oder nach
> dem Abfragen des Pins kommen muss.

Danach. Das ist im Code schon richtig so. (Bis auf die Kommentare. Die 
sind definitiv falsch)

von Markus C. (ljmarkus)


Lesenswert?

es soll auch nur 1 Schieberegister bleiben.

1
unsigned char read_HC165(void)
2
3
{
4
  unsigned char result;
5
6
  ...
7
8
  return result;
9
}

value_HC165 = read_HC165();

so hatte ich mir das vorgestellt nur finde mich da nicht so richtig 
zurecht gerade.



lg, markus

von Markus C. (ljmarkus)


Lesenswert?

Karl heinz Buchegger schrieb:

> Hmm. Ich weiss jetzt nicht auswändig, ob der Clock Puls vor oder nach
> dem Abfragen des Pins kommen muss.

>Danach. Das ist im Code schon richtig so. (Bis auf die Kommentare. Die
>sind definitiv falsch)


jetzt komme ich total durcheinander.


lg, markus

von Karl H. (kbuchegg)


Lesenswert?

Markus C. schrieb:
> Karl heinz Buchegger schrieb:
>
>> Hmm. Ich weiss jetzt nicht auswändig, ob der Clock Puls vor oder nach
>> dem Abfragen des Pins kommen muss.
>
>>Danach. Das ist im Code schon richtig so. (Bis auf die Kommentare. Die
>>sind definitiv falsch)
>
>
> jetzt komme ich total durcheinander.

Sieh dir den Code an

  PORTB |= (1<<PB5);  //SCK = 0;

Das setzt doch nicht den Pin auf 0!
Das setzt ihn auf 1!

Also muss irgendetwas falsch sein. Entweder der Code oder der Kommentar.

von Markus C. (ljmarkus)


Lesenswert?

Der Kommentar ist richtig. Hatte das im Code Falsch.

von Karl H. (kbuchegg)


Lesenswert?

Markus C. schrieb:

> so hatte ich mir das vorgestellt nur finde mich da nicht so richtig
> zurecht gerade.

Red doch nicht um den heissen Brei herum :-) Ich bin nicht so dämlich, 
wie mein Getippe aussieht :-)

1
unsigned char read_HC165( void )
2
{
3
  unsigned char result = 0;
4
5
  // Clock auf 1 halten
6
  PORTB |= (1<<PB5);
7
8
  // ein 0/1 Puls auf der PL Leitung. Der 165 übernimmt die
9
  // externen Datenleitungen ins SR
10
  PORTB &= ~(1<<PB6);
11
  PORTB |= (1<<PB6);
12
  
13
  // Datenleitung auf Eingang, Pullup aus
14
  DDRB &= ~(1<<PB4);
15
  PORTB &= ~(1<<PB4);
16
17
  // und die 8 Bit abholen    
18
  for( unsigned char j = 0; j < 8; ++j )
19
  {
20
    result <<= 1;
21
    if( PINB & ( 1 << PB4 ) )
22
      result |= 0x01;
23
24
    // nächstes Bit aus dem SR mit einem 0/1 Puls raustakten
25
    PORTB &= ~(1<<PB5);
26
    PORTB |= (1<<PB5);
27
  }
28
29
  return result;
30
}


Versuch wenigstens jetzt zu verstehen wie das funktioniert und 
vergleiche mit dem Datenblatt des 165, wie sich der Hersteller die 
Benutzung vorgestellt hat.

von Markus C. (ljmarkus)


Lesenswert?

Hi.

danke!

ich werde das Genau durchgehen und mal mit dem Datenblatt vergeleichen 
damit ich das Verstehe. Es funktioniert aber.



Danke, Markus

von Milan M. (milance)


Lesenswert?

Hallo zusammen,
muss ich noch etwas definieren, bei mir geht es nicht.
ich habe einen atmega2560

Gruss
milan

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.