mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 74HC165 auslesen C


Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht 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

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

Bewertung
0 lesenswert
nicht 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-Tutori...


  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?

Autor: Route_66 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hast Du denn schon? Eventuell können wir den Fehler finden.

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi.

hier mein Code ausschnitt:
void read_HC165(char* pBytes, char num_bytes)
{
  PORTB |= (1<<PB5);    //SCK = 0;
  PORTB |= (1<<PB6);    // PB6 = 0;
  PORTB &= ~(1<<PB6);    // PB6 = 1;
  
  for (char i=0; i<num_bytes; ++i)
  {
  *pBytes = 0;
  DDRB &= ~(1<<PB4);    // PB4 als Eingang
  PORTB &= ~(1<<PB4);    // Pullup aus
    
  for (char j=0; j<8; ++j)
  {
      *pBytes |= PINB4;
      if (j<7) *pBytes<<=1;
      PORTB &= ~(1<<PB5);  //SCK = 1;
      PORTB |= (1<<PB5);  //SCK = 0;
  }
  ++pBytes;
  }
}

lg, markus

Autor: Route_66 (Gast)
Datum:

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

setzt PB6 genau umgekehrt

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Codebegugger (Gast)
Datum:

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

Autor: Codebegugger2 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und überprüfe dein Aufruf:
read_HC165(value_165,8);
;

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

Bewertung
0 lesenswert
nicht lesenswert
Codebegugger2 schrieb:
> und überprüfe dein Aufruf:
>
>
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
  for (char j=0; j<8; ++j)
  {
      *pBytes |= PINB4;
      if (j<7) *pBytes<<=1;
      PORTB &= ~(1<<PB5);  //SCK = 1;
      PORTB |= (1<<PB5);  //SCK = 0;
  }

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

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

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht 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

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

Bewertung
0 lesenswert
nicht 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
unsigned char read_HC165(void)
{
  unsigned char result;

  ...

  return result;
}

und dann
  value_165 = read_HC165();

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo..

ich habe nur 1 Schieberegister drann.


lg, markus

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

Bewertung
0 lesenswert
nicht 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 :-)

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja irgendwie schon....

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

Bewertung
0 lesenswert
nicht 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.

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

Bewertung
0 lesenswert
nicht 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)

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
es soll auch nur 1 Schieberegister bleiben.

unsigned char read_HC165(void)

{
  unsigned char result;

  ...

  return result;
}

value_HC165 = read_HC165();

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



lg, markus

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht 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

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

Bewertung
0 lesenswert
nicht 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.

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Kommentar ist richtig. Hatte das im Code Falsch.

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

Bewertung
0 lesenswert
nicht 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 :-)

unsigned char read_HC165( void )
{
  unsigned char result = 0;

  // Clock auf 1 halten
  PORTB |= (1<<PB5);

  // ein 0/1 Puls auf der PL Leitung. Der 165 übernimmt die
  // externen Datenleitungen ins SR
  PORTB &= ~(1<<PB6);
  PORTB |= (1<<PB6);
  
  // Datenleitung auf Eingang, Pullup aus
  DDRB &= ~(1<<PB4);
  PORTB &= ~(1<<PB4);

  // und die 8 Bit abholen    
  for( unsigned char j = 0; j < 8; ++j )
  {
    result <<= 1;
    if( PINB & ( 1 << PB4 ) )
      result |= 0x01;

    // nächstes Bit aus dem SR mit einem 0/1 Puls raustakten
    PORTB &= ~(1<<PB5);
    PORTB |= (1<<PB5);
  }

  return result;
}


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

Autor: Markus C. (ljmarkus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi.

danke!

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



Danke, Markus

Autor: Milan M. (milance)
Datum:

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

Gruss
milan

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.