Forum: Mikrocontroller und Digitale Elektronik Code fehler bei 74hc165 kette (einzelner geht)


von Martin K. (thereallife)


Lesenswert?

Moin moin,
ich habe ein kleines Problem mit meiner Kette von 74hc165er.
den ersten kann ich auslesen, allerdings nicht die 3 restlichen.
(Sie funktionieren allerdings, das weiß ich weil ich im Code mal 
spaßeshalber i<24 gemacht habe. Dann funktioniert der 2&3te 74hc165 
jedoch nicht mehr der erste.

Ich hab scheinbar also irgendwie nen denkfehler in meiner Routine, komme 
aber nicht drauf. Denke aber das jmd der etwas geübter ist den Fehler 
schnell entdeckt.

Mein Setup:
Prozessor ATmega32A
74hc165 mit tastern und drehencodern

Hier mal mein Code:
1
void Pulse165Clock()
2
{
3
  CLOCK165_low();
4
  CLOCK165_high();
5
}
6
////////////////////////////////////////////////////////////////////
7
void Pulse165Parallel()
8
{
9
  PARALLEL165_low(); // Erst null dann high! WICHTIG!!!
10
  PARALLEL165_high();
11
}
12
////////////////////////////////////////////////////////////////////
13
#if 0
14
void ShiftIn(int *var)
15
{
16
  for (unsigned char a = 0; a < 4; ++a)
17
  {
18
    CLOCK165_high();
19
    Pulse165Parallel();
20
    for (unsigned char i = 0; i < 8; ++i)
21
    {
22
      *var <<= 1;
23
      if (DATA165_read())
24
      *var |= 0x01;
25
      Pulse165Clock();
26
    }
27
    CLOCK165_low();
28
  }
29
}
30
#endif
31
////////////////////////////////////////////////////////////////////
32
static uint8_t DATA165_read(void)
33
{
34
  if (PINB & _BV(DATA165_PIN))
35
  {
36
    return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
37
  }
38
  else
39
  return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
40
}
41
////////////////////////////////////////////////////////////////////
42
uint32_t ShiftIn(void)
43
{
44
  uint32_t shiftResult;
45
  for (unsigned char a = 0; a < 4; ++a)
46
  {
47
    CLOCK165_high();
48
    Pulse165Parallel();    
49
    for (unsigned char i = 0; i < 8; ++i) 
50
    {
51
      shiftResult |= DATA165_read();
52
      shiftResult <<= 1;
53
      Pulse165Clock();
54
    }
55
    CLOCK165_low();
56
  }
57
  return shiftResult;
58
}

Main Routine:
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#ifndef F_CPU
4
#define F_CPU 8000000UL
5
#endif
6
#include <stdio.h>
7
#include <util/delay.h>
8
#include "ShiftOut.h"
9
#include "ShiftIn.h"
10
#include "UART.h"
11
#include "Encoder.h"
12
#define LED1  PA1
13
#define LED_DDR  DDRA
14
#define LED_PORT  PORTA
15
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18
void prtbin(unsigned byte)
19
{
20
  for(char i=0; i<32; i++) printf("%u",(byte>>(32-i))& 0x0001);
21
}
22
 
23
int main(void)
24
{
25
  stdout = &mystdout;
26
  long baud = 9600UL;
27
  UART_Init(baud);
28
  InitShiftIn();
29
  int v165 = 0;
30
  InitShiftOut();
31
  setup_Encoder();
32
  while(1)
33
  {
34
    v165 = ShiftIn();
35
    ShiftOut(v165);
36
    get_Encoder_data(v165);
37
    read_Encoder();
38
    prtbin(v165);
39
    printf("\n");
40
  }
41
}

Ich weiß (jedenfalls wurde es mir erklärt) das man eigentlich keine 
Funktionen in includes schreiben soll. Jedoch ist es für mich als Anfang 
erstmal einfacher so um etwas mehr überblick zu behalten.

Vielen Dank im Vorraus!

Beste Grüße
Martin

von Karl H. (kbuchegg)


Lesenswert?

Martin Kathke schrieb:


> ////////////////////////////////////////////////////////////////////
> uint32_t ShiftIn(void)
> {
>   uint32_t shiftResult;
>   for (unsigned char a = 0; a < 4; ++a)
>   {
>     CLOCK165_high();
>     Pulse165Parallel();


Du willst nur ein einziges mal ALLEN 165-ern einen Parallel Load Pulse 
geben.
Danach wird nur noch rein-geshiftet.
Auch die Sache mit dem Clock ist dubios.
Du fummelst mir da zwischenzeitlich zu viel an den beiden Pins rum. 
Bedenke: Für die Bausteine zählt jede Flanke, egal wo und wie die im 
Programm entsteht. D.h. du fummelst da quer im Programm nicht an den 
CLock Leitungen rum um sie definiert auf 0 oder 1 zu setzen, es sei denn 
du willst absichltich einen Puls erzeugen. Du setzt die Clock Leitung 
(und die Parallel Load) einmalig am Programmanfang auf 1 und dann bleibt 
sie auch auf 1, es sei denn du willst gewollt einen Puls erzeugen.
Alles andere hat irgendwo das Äquivalent eines epilleptischen Anfalls, 
bei dem man seine Pins (und das was die an der externen Beschaltung 
auslösen) nicht mehr unter Kontrolle hat.
1
 ////////////////////////////////////////////////////////////////////
2
 uint32_t ShiftIn(void)
3
 {
4
   uint32_t shiftResult;
5
6
   // CLOCK165_high bzw. Pulse165High kann man hier aufrufen, muss man
7
   // aber nicht. Wenn man sich als Programmierer mit sich selbst
8
   // einig ist, dass die beiden Leitungen grundsätzlich immer auf 1
9
   // zu stehen haben und das am Programmanfang sicher stellt, dann
10
   // ist das auch gut
11
   CLOCK165_high();  // Sicherheitshalber. Die Clock Leitung wird
12
                     // im Programm grundsätzlich auf High gehalten
13
   Pulse165High();   // ditto
14
15
   // an alle 165-er: Jetzt die 8 parallelen Eingänge einlesen
16
   Pulse165Parallel();
17
18
   // alles 4 Bausteine haben ihre Werte von extern übernommen
19
   // mal sehen, was sie rein bekommen haben
20
   for (unsigned char a = 0; a < 4; ++a)
21
   {
22
     for (unsigned char i = 0; i < 8; ++i)
23
     {
24
       shiftResult |= DATA165_read();
25
       shiftResult <<= 1;
26
       Pulse165Clock();
27
     }
28
   }
29
30
   // an dieser Stelle stehen Clock bzw ParallelLoad auf jeden Fall
31
   // wieder auf high. Dies ist durch die Art und Weise wie die Pulse
32
   // erzeugt werden, automatisch gewährleistet.
33
34
   return shiftResult;
35
}


Das hier ist auch doppelt gemoppelt
1
static uint8_t DATA165_read(void)
2
{
3
  if (PINB & _BV(DATA165_PIN))
4
  {
5
    return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
6
  }
7
  else
8
  return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
9
}

wenn PINB & _BV(DATA165_PIN) in der Abfrage TRUE ergibt, dann kennst du 
bereits das Ergebnis, das die Funktion zurückgeben muss. Das kann dann 
nur noch 1 sein, weil ja der Pin auf 1 gewesen sein muss, ansonsten wäre 
das Ergebnis deer Abfage nicht TRUE gewesen
1
static uint8_t DATA165_read(void)
2
{
3
  if (PINB & _BV(DATA165_PIN))
4
    return 1;
5
6
  return 0;
7
}

oder kürzer geschrieben (wobei ich mir nicht sicher bin, ob ich das hier 
tun würde. Die Version mit dem expliziten if ist hier fein)
1
static uint8_t DATA165_read(void)
2
{
3
  return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
4
}

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Generell:
Ich hab nichts gegen Funktionen. Ganz im Gegenteil.
Aber an dieser Stelle finde ich es keine so gute Idee, für die Erzeugung 
der Pulse eigene Funktionen zu schreiben. Ich denke das versteckt hier 
zu viel Information, die aber eigentlich vital ist. Ich würde es so 
schreiben
1
void InitShiftIn(void)
2
{
3
  ... Data Register einstellen ...
4
5
   // sicherstellen, dass alle wichtigen Leitungen den 'Ruhe'Pegel haben
6
   CLOCK165_high();
7
   Pulse165High();
8
}
9
10
11
////////////////////////////////////////////////////////////////////
12
 uint32_t ShiftIn(void)
13
 {
14
   uint32_t shiftResult;
15
16
   // an alle 165-er: Jetzt die 8 parallelen Eingänge einlesen
17
   Pulse165Low();
18
   Pulse165High();
19
20
   // alles 4 Bausteine haben ihre Werte von extern übernommen
21
   // mal sehen, was sie rein bekommen haben
22
   for (unsigned char a = 0; a < 4; ++a)
23
   {
24
     for (unsigned char i = 0; i < 8; ++i)
25
     {
26
       if (PINB & _BV(DATA165_PIN))
27
         shiftResult |= 0x0001;
28
29
       shiftResult <<= 1;
30
31
       CLOCK165_Low();
32
       CLOCK165_high();
33
     }
34
   }
35
36
   return shiftResult;
37
}

Dadurch sieht man in dieser dann doch schon recht low-Level-Funktion 
besser, wie die Pulspolaritäten eigentlich sind.
Man kann sich nämlich auch durch zuviele Funktion ein Ei legen. 
Irgendwann nimmt die Übersicht dann nicht mehr zu, sondern ab, weil man 
die wesentlichen Informationen über zu viele Funktionen verteilt hat.

: Bearbeitet durch User
von Vlad T. (vlad_tepesch)


Lesenswert?

Anmerkung zum Naming:
es hat sich bewährt für Funktionsgruppen (wie es dieser PiSo-SR-Treiber 
ja ist) Präfixe anstelle von Suffixes zu verwenden.

So sieht man auf den ersten Blick, dass die Funktionen zusammengehören 
und auch die Code-Vervollständigung funktioniert besser.

Pulse165Clock    -> SR165_pulseClock
Pulse165Parallel -> SR165_pulseParallel
ShiftIn          -> SR165_shiftIn
DATA165_read     -> SR165_readData

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Und noch eine Anmerkung zu dem was Vlad gesagt hat:
Selbst wenn du das nicht machst, achte darauf wenigstens ein konistentes 
Benamungsschema zu haben

Entweder die Funtkionen heissen
  Pulse165Low();
und
  Clock165Low();

oder sie heissen
  Pulse165_Low();
und
  Clock165_Low();

(also entweder überall ein _ rein oder nirgends)

Und auch auf Konsistenz in den Schreibweisen bzgl. Gross- und 
Kleinschreibung achten!

Das alles hat Auswirkungen darauf, wie leicht man Code schreiben bzw. 
lesen kann bzw. wieviele blödsinnige Tippfehler man in der ersten 
Version macht. Wenn du quer durch die Bank bei 5 Funktionen 5 
unterschiedliche Schemata benutzt, dann wird man wahnsinnig dabei sich 
daran zuerinnern, welches Schema jetzt das richtige ist. Überhaupt dann, 
wenn man dann irgenwan nicht 5 Funktionen sondern 50 hat, die alle 
irgendwie ihr eigenes Modul Namensschema haben.

: Bearbeitet durch User
von Martin K. (thereallife)


Lesenswert?

Danke euch aufjedenfall für eure Tipps und Hilfen!

das ich den allen nach 8 Bits nen Pulse aufn Parallel Pin gegeben habe 
war ein reiner denkfehler... Irgendwie war ich der Meinung die brauchen 
das um die neuen daten zu übernehmen...

Das mit den zuvielen Funktionen habe ich beherzigt und korregiert auch 
die Namen habe ich nun einheitlich gestaltet. Allerdings waren für mich 
die mit _ makros, ohne waren funktionen...

Jetzt habe ich allerdings das Problem das die letzten bits "fliegen" sie 
springen ständig von null auf 1 etc, Daten vom eigentlichen drücken bzw 
drehen übernimmt er garnicht mehr bis auf eine seite von einem 
Drehencoder...

Das mit den Namen wie Vlad sie geschrieben hat werde ich ändern wenn es 
läuft, wenn ich jetzt noch neue Namen gebe komm ich bei der Fehlersuche 
glaube ich etwas sehr durcheinander^^

Hier der Code:
1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
//Include File fuer Shift In (74hc165)                            //////////////////////////////////////////////////////////////////
3
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4
/*
5
int main(void)
6
{
7
  InitShiftIn();
8
  int v165 = 0;
9
  while(1)
10
  {
11
    v165 = ShiftIn();
12
  }
13
}
14
*/
15
#define DATA165_PIN      PB6
16
#define DATA165_PORT    PORTB
17
#define DATA165_DDR      DDRB
18
////////////////////////////
19
#define CLOCK165_PIN    PA5
20
#define CLOCK165_PORT    PORTA
21
#define CLOCK165_DDR    DDRA
22
#define CLOCK165_high()    (CLOCK165_PORT |= _BV(CLOCK165_PIN))
23
#define CLOCK165_low()      (CLOCK165_PORT &= ~_BV(CLOCK165_PIN))
24
////////////////////////////
25
#define PARALLEL165_PIN    PA4
26
#define PARALLEL165_PORT    PORTA
27
#define PARALLEL165_DDR     DDRA
28
#define PARALLEL165_high()  (PARALLEL165_PORT |= _BV(PARALLEL165_PIN))
29
#define PARALLEL165_low()   (PARALLEL165_PORT &= ~_BV(PARALLEL165_PIN))
30
////////////////////////////////////////////////////////////////////
31
void InitShiftIn()
32
{
33
  PARALLEL165_DDR |= _BV(PARALLEL165_PIN);
34
  CLOCK165_DDR |= _BV(CLOCK165_PIN);
35
  DATA165_DDR &= ~_BV(DATA165_PIN);
36
  DATA165_PORT &= ~_BV(DATA165_PIN);
37
  CLOCK165_high();
38
  PARALLEL165_high();
39
}
40
////////////////////////////////////////////////////////////////////
41
void Pulse165_Clock()
42
{
43
  CLOCK165_low();
44
  CLOCK165_high();
45
}
46
////////////////////////////////////////////////////////////////////
47
void Pulse165_Parallel()
48
{
49
  PARALLEL165_low(); // Erst null dann high! WICHTIG!!!
50
  PARALLEL165_high();
51
}
52
////////////////////////////////////////////////////////////////////
53
#if 0
54
void ShiftIn(int *var)
55
{
56
  PARALLEL165_low();
57
  PARALLEL165_high();
58
  for (unsigned char a = 0; a < 4; ++a)
59
  {
60
    for (unsigned char i = 0; i < 8; ++i)
61
    {
62
      *var <<= 1;
63
      if (PINB & _BV(DATA165_PIN))
64
        *var |= 0x01;
65
        CLOCK165_low();
66
        CLOCK165_high();
67
    //  if (DATA165_read())
68
    //  *var |= 0x01;
69
    //  Pulse165Clock();
70
    }
71
  }
72
}
73
#endif
74
////////////////////////////////////////////////////////////////////
75
static uint8_t DATA165_read(void)
76
{
77
  if (PINB & _BV(DATA165_PIN))
78
  {
79
    return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
80
  }
81
  else
82
  return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
83
}
84
////////////////////////////////////////////////////////////////////
85
uint32_t ShiftIn(void)
86
{
87
  uint32_t shiftResult;
88
  PARALLEL165_low();
89
  PARALLEL165_high();
90
//  Pulse165Parallel();  
91
  for (unsigned char a = 0; a < 4; ++a)
92
  {
93
    for (unsigned char i = 0; i < 8; ++i) 
94
    {
95
      if (PINB & _BV(DATA165_PIN))
96
        shiftResult |= 0x0001;
97
        shiftResult <<= 1;
98
        CLOCK165_low();
99
        CLOCK165_high();
100
      //shiftResult |= DATA165_read();
101
      //shiftResult <<= 1;
102
      //Pulse165Clock();
103
    }
104
  }
105
  return shiftResult;
106
}

von Karl H. (kbuchegg)


Lesenswert?

Martin Kathke schrieb:

> Das mit den zuvielen Funktionen habe ich beherzigt und korregiert auch
> die Namen habe ich nun einheitlich gestaltet. Allerdings waren für mich
> die mit _ makros, ohne waren funktionen...

Für Makros hat sich weltweit eingebürgert, dass Makros grundsätzlich 
komplett in Grossbuchstaben geschrieben werden. Und auch umgekehrt: 
Alles was komplett in Grossbuchstaben geschrieben ist, ist ein Makro.

Das ist so ziemlich die einzige Konvention, an die sich weltweit 
Millionen von C Programmierer problemlos halten.

> Jetzt habe ich allerdings das Problem das die letzten bits "fliegen" sie
> springen ständig von null auf 1 etc

Du kannst mal probieren, die Pulse etwas zu verlängern. Wenn genügend 
viele Bausteine kaskadiert sind, die natürlich alle an ein und derselben 
CLock Leitung hängen, dann ist irgendwann mal Schluss mit lustig. Die 
Flanken verschleifen dann zu stark.

Also: kurze delays zwischen demjeweiligen Low und dem darauffolgenden 
High mal rein.
Zu Testzwecken kannst du da ruhig auch schon mal in den 
Millisekundenbereich oder noch höher vorstossen (auch Sekunden oder 
Minuten sind kein Problem - Tip: das lässt sich beim Debuggen zb gut 
benutzen indem man ein paar LED an die Leitungen hängt und so langsam 
taktet, dass man als Mensch verfolgen kann was passiert)

Wenn das nichts bringt, dann sieh dir deine Verkabelung an. 
Wackelkontakte, schlechte Kontakte. irgendsowas in dieser Richtung.

: Bearbeitet durch User
von Martin K. (thereallife)


Lesenswert?

Karl Heinz schrieb:
> Makros grundsätzlich
> komplett in Grossbuchstaben geschrieben werden.

alles klar, werde ich mir einprägen.

5ms delay zwischen hab ich zwischen die einzelnen pulse gelegt. Selbes 
resultat. Wenn ich allerdings nur den ersten 165er auslese habe ich kein 
problem. Dieser ist auch am weitesten entfernt.
Nach dazu kommt auch nur noch eine 1 von einer seite der drehencoder an 
(alle werden gegen gnd) gezogen daher müssten dort 10x1 im normalfall 
stehen.

Ich arbeite auf einer Platine. Der Schaltplan wurde
mehrmals überprüft und da ich heute schon die drehencoder auslesen 
konnte, gehe ich mal nicht davon aus das dort ein wackler oder ähnliches 
enstehen konnte da die platine auch nicht bewegt wurde.
Bei bedarf kann ich allerdings auch mal eagle schalt und boardplan 
hochladen.

Ist das ganze eventuell ein Variablen fehler?
Ist irgendeine zu klein? meines erachtens nicht, aber ich bin auch noch 
ein anfänger und überseh vill was :D

/edit

da fällt mir grade ein, es kann gut sein das ein paar daten eingänge 
fliegend sind. Das letzte 165bauteil geht nämlich mit 7 data ins an ein 
lötpunkt welcher so vorgegsehen ist damit man ihn mit masse oder gnd 
verbinden kann. Dies soll später dazu da sein damit ich meiner platine 
einmalig eine adresse zuweisen kann (für I²C)

Diese 7 pins sind momentan also fliegend... was aber nicht erklärt warum 
keine daten von den andern sachen reinkommen...

/edit 2
nehme ich die for schleife mit dem a<4 raus,
und bleibe beim i bei einer 8, kann ich meine taster auslesen ( diese 
sind am ersten 165)
ersetze ich die 8 mit einer 24 so bekomme ich meine drehencoder 9 von 10
1en von den drehencodern (PIN A oder PIN B vom obersten drehencoder 
fehlt scheinbar)
165 Nummer 1 hat die 8 Taster
165 Nummer 2 hat die ersten 4 drehencoder
165 Nummer 3 hat den 5ten Drehencoder
165 Nummer 4 hat die "Lötschalter"(ich weiß leider nicht das fachwort 
für soetwas)

mit einem i<32 fangen die werte wieder an zu springen und lediglich ein 
PIN a oder b vom 5ten drehencoder kommt an (pin a oder b heißt einer von 
beiden, ich weiß nur nicht welcher).

: Bearbeitet durch User
von Martin K. (thereallife)


Lesenswert?

Hier mal nen Auszug aus meiner Printf ausgabe:
-128
000000000111111111000000

um es nen bssl übersichtlicher zu machen:
-128
00 00 00 00 01 11 11 11 11 00 00 00
Er haut zwar 24 bits raus, allerdings sind die meiner meinung nach 
verschoben. Gans links müssten 8 nullen vor den 1en kommen und nicht 
6...

es scheint also irgendwas schief zu gehen... Vielleicht bringt das ja 
jmd auf die richtige fährte ;)

von Vlad T. (vlad_tepesch)


Lesenswert?

dann leg doch mal ein (oder mehrere) eindeutigeres Muster an deine 
Eingänge.

: Bearbeitet durch User
von Martin K. (thereallife)


Lesenswert?

Es ist defenetiv ein Code Fehler.

ist nur die Frage wo...

ich habs mal so ausprobiert:
1
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2
//Include File fuer Shift In (74hc165)                            //////////////////////////////////////////////////////////////////
3
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4
/*
5
int main(void)
6
{
7
  InitShiftIn();
8
  int v165 = 0;
9
  while(1)
10
  {
11
    v165 = ShiftIn();
12
  }
13
}
14
*/
15
#define DATA165_PIN      PB6
16
#define DATA165_PORT    PORTB
17
#define DATA165_DDR      DDRB
18
////////////////////////////
19
#define CLOCK165_PIN    PA5
20
#define CLOCK165_PORT    PORTA
21
#define CLOCK165_DDR    DDRA
22
#define CLOCK165_high()    (CLOCK165_PORT |= _BV(CLOCK165_PIN))
23
#define CLOCK165_low()      (CLOCK165_PORT &= ~_BV(CLOCK165_PIN))
24
////////////////////////////
25
#define PARALLEL165_PIN    PA4
26
#define PARALLEL165_PORT    PORTA
27
#define PARALLEL165_DDR     DDRA
28
#define PARALLEL165_high()  (PARALLEL165_PORT |= _BV(PARALLEL165_PIN))
29
#define PARALLEL165_low()   (PARALLEL165_PORT &= ~_BV(PARALLEL165_PIN))
30
////////////////////////////////////////////////////////////////////
31
void InitShiftIn()
32
{
33
  PARALLEL165_DDR |= _BV(PARALLEL165_PIN);
34
  CLOCK165_DDR |= _BV(CLOCK165_PIN);
35
  DATA165_DDR &= ~_BV(DATA165_PIN);
36
  DATA165_PORT &= ~_BV(DATA165_PIN);
37
  CLOCK165_high();
38
  PARALLEL165_high();
39
}
40
////////////////////////////////////////////////////////////////////
41
void Pulse165_Clock()
42
{
43
  CLOCK165_low();
44
  CLOCK165_high();
45
}
46
////////////////////////////////////////////////////////////////////
47
void Pulse165_Parallel()
48
{
49
  PARALLEL165_low(); // Erst null dann high! WICHTIG!!!
50
  PARALLEL165_high();
51
}
52
////////////////////////////////////////////////////////////////////
53
#if 0
54
void ShiftIn(int *var)
55
{
56
  PARALLEL165_low();
57
  PARALLEL165_high();
58
  for (unsigned char a = 0; a < 3; ++a)
59
  {
60
    for (unsigned char i = 0; i < 8; ++i)
61
    {
62
      *var <<= 1;
63
      if (PINB & _BV(DATA165_PIN))
64
        *var |= 0x01;
65
        CLOCK165_low();
66
        CLOCK165_high();
67
    //  if (DATA165_read())
68
    //  *var |= 0x01;
69
    //  Pulse165Clock();
70
    }
71
  }
72
}
73
#endif
74
////////////////////////////////////////////////////////////////////
75
static uint8_t DATA165_read(void)
76
{
77
  if (PINB & _BV(DATA165_PIN))
78
  {
79
    return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
80
  }
81
  else
82
  return (PINB & _BV(DATA165_PIN)) ? 1 : 0;
83
}
84
////////////////////////////////////////////////////////////////////
85
uint32_t ShiftIn1(void)
86
{
87
  uint32_t shiftResult;
88
  PARALLEL165_low();
89
  PARALLEL165_high();
90
//  Pulse165Parallel();  
91
    for (unsigned char i = 0; i < 8; ++i) 
92
    {
93
      if (PINB & _BV(DATA165_PIN))
94
        shiftResult |= 0x0001;
95
        shiftResult <<= 1;
96
        CLOCK165_low();
97
        CLOCK165_high();
98
      //shiftResult |= DATA165_read();
99
      //shiftResult <<= 1;
100
      //Pulse165Clock();
101
    }
102
  return shiftResult;
103
}
104
uint32_t ShiftIn2(void)
105
{
106
  uint32_t shiftResult;
107
  PARALLEL165_low();
108
  PARALLEL165_high();
109
  //  Pulse165Parallel();
110
    for (unsigned char a = 0; a < 8; ++a)
111
    {
112
      CLOCK165_low();
113
      CLOCK165_high();
114
    }
115
  for (unsigned char i = 0; i < 8; ++i)
116
  {
117
    if (PINB & _BV(DATA165_PIN))
118
    shiftResult |= 0x0001;
119
    shiftResult <<= 1;
120
    CLOCK165_low();
121
    CLOCK165_high();
122
    //shiftResult |= DATA165_read();
123
    //shiftResult <<= 1;
124
    //Pulse165Clock();
125
  }
126
  return shiftResult;
127
}
128
uint32_t ShiftIn3(void)
129
{
130
  uint32_t shiftResult;
131
  PARALLEL165_low();
132
  PARALLEL165_high();
133
  //  Pulse165Parallel();
134
  for (unsigned char a = 0; a < 16; ++a)
135
  {
136
    CLOCK165_low();
137
    CLOCK165_high();
138
  }
139
  for (unsigned char i = 0; i < 8; ++i)
140
  {
141
    if (PINB & _BV(DATA165_PIN))
142
    shiftResult |= 0x0001;
143
    shiftResult <<= 1;
144
    CLOCK165_low();
145
    CLOCK165_high();
146
    //shiftResult |= DATA165_read();
147
    //shiftResult <<= 1;
148
    //Pulse165Clock();
149
  }
150
  return shiftResult;
151
}

Main Routine
1
#include <avr/io.h>
2
#include <avr/interrupt.h>
3
#ifndef F_CPU
4
#define F_CPU 8000000UL
5
#endif
6
#include <stdio.h>
7
#include <util/delay.h>
8
#include "ShiftOut.h"
9
#include "ShiftIn.h"
10
#include "UART.h"
11
#include "Encoder.h"
12
#define LED1  PA1
13
#define LED_DDR  DDRA
14
#define LED_PORT  PORTA
15
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
16
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
17
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
18
void prtbin(unsigned byte)
19
{
20
  for(char i=0; i<8; i++) printf("%u",(byte>>(8-i))& 0x0001);
21
}
22
 
23
int main(void)
24
{
25
  stdout = &mystdout;
26
  long baud = 9600UL;
27
  UART_Init(baud);
28
  InitShiftIn();
29
  uint8_t v165 = 0;
30
  uint8_t v165_1 = 0;
31
  uint8_t v165_2 = 0;
32
  InitShiftOut();
33
  setup_Encoder();
34
  while(1)
35
  {
36
    v165 = ShiftIn1();
37
    v165_1 = ShiftIn2();
38
    v165_2 = ShiftIn3();
39
    ShiftOut(v165);
40
    get_Encoder_data(v165);
41
    read_Encoder();
42
    printf("%d \n", v165);
43
    prtbin(v165);
44
    prtbin(v165_1);
45
    prtbin(v165_2);
46
    printf("\n");
47
  }
48
}

so bekomme ich alle werte (fast) fast richtig raus. das einzigste was 
falsch ist, ist das nun beim 5ten drehencoder das erste bit fehlt. änder 
ich allerdings beim shift in 1 die 8 auf ne 7 und beim shift 2 die 16 
auf ne 15, ist dieses bit wieder da, dafür fehlt dann alerdings das 
letzte vom drehencoder 4 :D

es liegt also irgendwas im code krum... die spannende frage ist nur was 
:D

von Karl H. (kbuchegg)


Lesenswert?

1
void prtbin(unsigned byte)
2
{
3
  for(char i=0; i<8; i++) printf("%u",(byte>>(8-i))& 0x0001);
4
}

7 - i

von Karl H. (kbuchegg)


Lesenswert?

Ich würds auch mit Vlad halten

Den ganzen KLimbim in der Aussenbeschaltung runter und erst mal für 
gesicherte Verhältnisse sorgen.

Dazu ALLE (!) Eingänge ALLER (!) 165 mit Masse verbinden.
Die Ausgabe (es reicht dazu völlig aus, EINE EINZIGE EInlsefunktion zu 
haben, die alle 4 165 einliest) muss überall ein 0 Bit haben.

Dann fange ich bei einem Eingang (systematisch: erster Eingang vom 
ersten 165) an und lege den von Masse auf Vcc. In der Ausgabe muss an 
der entsprechenden Stelle eine 1 auftauchen.

Dann der nächste Eingang: von Masse auf Vcc gehen. Eine weitere 1 muss 
auftauchen.


Das wäre mein Vorgehen: sytematisch und erst mal nichts dem Zufall 
überlassen. Floatende Eingänge darf es da schon mal überhaupt nicht 
geben. Genausowenig wie mich da erst mal eine Encoder-Auswertung 
interessiert.
Im Endeffekt zeigt sich praktisch immer, das man mit einem derartigen 
systematischen Vorgehen schneller zum Ziel kommt als mit wildem 
unstrukturiertem RUmprobieren mit Drehencodern von denen man nicht weiss 
(ok, ich hier nicht weiss), ob die überhaupt sauber angeschlossen sind.

und ja. Zum Probieren teste ich die Schaltung erst mal auf einem 
Steckbrett aus, ehe ich mir eine Platine ätze.

ZUm Code. Der sieht meiner Meinung nach in Ordnung aus.
Entweder hast du bei der Ausgabe noch irgendwo einen Hund drinnen, oder 
es ist ein Hardware Problem.

Aber dieses wilde, unstrukturierte Probieren mit 'bei einem IC gehst, 
bei dreien nicht', bringt dich nicht weiter. IMHO ist das nur vertane 
Zeit in der man das Problem auch sinnvoll systematisch angehen könnte, 
in dem man erst mal an den Eingängen für kontrollierte gesicherte 
Verhätlnisse sorgt, die nicht noch von irgendwelcher zusätzlicher 
Hardware abhängen. Eine simple Drahtbrücke zu GND oder Vcc sorgt genau 
dafür. Blöd natürlich, wenn man den Steckbrett-Schritt übersprungen hat 
und jetzt nichts mehr einfach ändern kann.

: Bearbeitet durch User
von Vlad T. (vlad_tepesch)


Lesenswert?

Karl Heinz schrieb:
> Um Code. Der sieht meiner Meinung nach in Ordnung aus.
> Entweder hast du bei der Ausgabe noch irgendwo einen Hund drinnen, oder
> es ist ein Hardware Problem.

weiß nicht, ob ich gerade auf dem Schlauch stehe, aber werden nicht die 
ganzen Bits nach dem Einlesen des letzten fälschlicherweise 
hochgeschoben? Hier sollte doch nur noch das Bit kopiert werden und 
nicht mehr alles weggeshiftet. das heißt, alles ist eins zu weit oben 
und das erste bit rutscht schon in das 4. Byte rein.

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Vlad Tepesch schrieb:
> Karl Heinz schrieb:
>> Um Code. Der sieht meiner Meinung nach in Ordnung aus.
>> Entweder hast du bei der Ausgabe noch irgendwo einen Hund drinnen, oder
>> es ist ein Hardware Problem.
>
> weiß nicht, ob ich gerade auf dem Schlauch stehe, aber werden nicht die
> ganzen Bits nach dem Einlesen des letzten fälschlicherweise
> hochgeschoben? Hier sollte doch nur noch das Bit kopiert werden und
> nicht mehr alles weggeshiftet.

(nachdenk)
ja, da hast du recht.
Mit systeamtischem Vorgehen hätte man das schon gesehen, dass das 
falsche Bit auf 1 geht.

Muss also heissen
1
  for (unsigned char i = 0; i < 8; ++i)
2
  {
3
    shiftResult <<= 1;
4
5
    if (PINB & _BV(DATA165_PIN))
6
      shiftResult |= 0x0001;
7
8
    CLOCK165_low();
9
    CLOCK165_high();
10
  }

Und ich bin mir auch nicht sicher, ob man nach dem Parallel Load erst 
mal einen Clock Puls braucht oder nicht. Aber auch das würde man sehen, 
wenn man systematisch vorgeht und nicht gleich in die vollen in der 
Annahme, dass schon alles stimmen wird.

Was aber auf keinen Fall sein kann, dass irgendwelche Bits klappern, so 
wie es im Ausgangsposting noch der Fall war.

: Bearbeitet durch User
von Martin K. (thereallife)


Lesenswert?

Ich wollte grade schreiben das immer das erste bit fehlt...
Deine Lösung war jetzt aber richtig :) nun läuft alles

danke euch

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.