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
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?
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
> PORTB |= (1<<PB6); // PB6 = 0;
PORTB &= ~(1<<PB6); // PB6 = 1;
setzt PB6 genau umgekehrt
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
dann schau dir die Zeile in einem Code mal genauer an:
1 | void read_HC165(char* pBytes, char num_bytes) |
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.
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
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(); |
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 :-)
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.
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)
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
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
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.
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.
Hi. danke! ich werde das Genau durchgehen und mal mit dem Datenblatt vergeleichen damit ich das Verstehe. Es funktioniert aber. Danke, Markus
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.