Forum: Mikrocontroller und Digitale Elektronik Zählerstand 74hc4040 mit Schieberegister 74hc166 abfragen.


von Chris (Gast)


Lesenswert?

Hallo zusammen. Da ich selber nicht weiter komme, frage ich mal die 
Profis.
Ich habe drei verkettete 12bit Asynchronzähler mit 32768Hz getaktet, 
deren Zustände über 3 schieberegister par2ser abgefragt werden. Der 
Zähler läuft problemlos. Beim Einlesen in den μC bekomme ich allerdings 
Zufallszahlen. Kann mir jemand einen Tip geben wo ich mir hier Störungen 
einfangen könnte?

Überlegungen:
1. Pulldown Widerstände an den Ausgängen der Zähler
2. Entstörkondensator an Vcc der Schieberegister
3. Pullup an der Datenleitung der Schieberegister

Leider fehlt mir ein Oszi mit dem ich der Sache auf die Schliche kommen 
könnte.


Würde mich über den ein oder anderen Hinweis freuen.

: Verschoben durch Admin
von Route_66 H. (route_66)


Lesenswert?

Chris schrieb:
> Würde mich über den ein oder anderen Hinweis freuen.


Hallo!
Faulheit, Bequemlichkeit oder "Ich weis was, das Du nicht weist"?
Schaltung und Software sind ja wohl nicht zu viel verlangt?
Du erhältst sonst nur "Super"-Hinheise zu Zeile 42 und R42.

von Earl S. (Gast)


Lesenswert?

asynchrone Zähler kannst du nicht zu jedem beliebigen Zeitpunkt 
auslesen. Jede Stufe hat eine gewisse Verzögerung gegenüber der vorigen, 
so dass im schlechtesten Fall erst nach Durchlaufen aller Stufen der 
richtige Zählerstand an den Ausgängen anliegt. In der Zwischenzeit 
liegen deine "Zufallszahlen" an.

von ... (Gast)


Lesenswert?

1 / 32768 Hz sind ca. 30.5 us.

Wenn Du schlau bist, startest Du das Einlesen mit einer
Flanke die die Zaehler weiterschaltet.

Um die Durchlaufzeit durch die Zaehlerkette zu beruecksichtigen,
solltest Du noch ca. 1 us warten.

Dann hast Du noch rund 29 us Zeit die Schieberegister in den
Controller zu schieben.

von Christoph Hausch (Gast)


Angehängte Dateien:

Lesenswert?

Gebe zu, ich war ein wenig voreilig.
Hier als Ergänzung der Schaltplan und der Code. Alles zusammen befindet 
sich
im Moment auf nem Breadboard. Danke schon mal für die vorherigen 
Antworten.

Der aktuelle Zählerstand wird beim Setzen von PL in das Schieberegister 
geladen. Der Zähler zählt doch weiter ohne das Register zu beeinflussen 
so viel ich weiß.

Schaut euch mal mein Gebastel an. Danke schon mal für eure Mühe !
1
int PLOADPIN = 8;
2
int CLOCKPIN = 7;
3
int DATAPIN = 9;
4
int CEPIN = 6;
5
6
byte bitarray[24];
7
8
void setup(){
9
  Serial.begin(57600);  
10
  pinMode(DATAPIN, INPUT);
11
  pinMode(PLOADPIN, OUTPUT);
12
  pinMode(CLOCKPIN, OUTPUT);
13
  pinMode(CEPIN, OUTPUT);
14
15
  digitalWrite(CEPIN, HIGH);
16
  digitalWrite(PLOADPIN, HIGH);
17
  digitalWrite(CLOCKPIN, LOW);
18
}
19
20
void loop(){
21
  ShiftIn();
22
  delay(100);
23
}
24
25
void ShiftIn(){
26
  digitalWrite(PLOADPIN, LOW);      
27
  delayMicroseconds(10);
28
  digitalWrite(PLOADPIN, HIGH);
29
  delayMicroseconds(10);
30
31
  digitalWrite(CEPIN, LOW);
32
33
  for(int i = 0; i <= 23; i++){
34
    digitalWrite(CLOCKPIN, LOW);
35
    delayMicroseconds(10);
36
    digitalWrite(CLOCKPIN, HIGH);
37
    bitarray[i] = digitalRead(DATAPIN);
38
    delayMicroseconds(10);
39
  }
40
  digitalWrite(CEPIN, HIGH);
41
42
  //convert to decimal
43
  long num = 0;
44
  double msec = 0;
45
  long tempNUM = 0;
46
  for(int i = 0; i <= 23; i++){
47
    num = (pow(2, (23-i))*bitarray[i]);
48
    tempNUM = tempNUM + num;
49
  }
50
  msec = tempNUM / 32768;
51
  for (int i = 0; i <= 23; i++){
52
    Serial.print(bitarray[i]);
53
  }
54
  Serial.print("    ");
55
  Serial.println(tempNUM);
56
}

Ausgabe (Ausschnitt entspr. ca. 1500ms):

100000001001110001011011    8428617
010010101010101010101001    4893340
001010101010101010101100    2796196
101010101010101001010100    11184706
101010101010010101010100    11183426
101010101010110101010100    11185473
101010101011010101010100    11187521
101001010101010101010101    10835265
010101010101010100101011    5592347
010101010101011010101011    5592730
011010101010101010100100    6990487
100101010101010101101011    9786709
010101010101011010101011    5592730
001010101010101001010101    2796110

von Joe F. (easylife)


Lesenswert?

"Zufallszahlen" sicher nicht.

Vermutlich sind die oberen bits (die sich seltener ändernd) okay, und 
die unteren haben fehler.
Dann liegt es, wie schon gesagt, daran, dass du den Wert zu früh nach 
der Clock-Flanke in die Schieberegister übernimmst.

Im Datenblatt steht der Wert t_pd (Qn to Qn+1).
Den nimmst du für deine Versorgungsspannung und Temperaturbereich 
(max.-Wert)  12  3.

Angenommen das wären 100ns, darfst du den Zähler frühestens 3.6us nach 
der Clock auslesen.
Das reicht dann immerhin noch für ca. 270 KHz.

Da dein Schiebereigster ein parallel load signal hat, kannst du den 
aktuell anliegenden Zählerstand auf einen Schlag in das Schieberegister 
übernehmen.
Danach hast du genügend Zeit, die Daten aus dem Schieberegister 
raustackern zu lassen, solange PE_N high ist, werden keine neuen (sich 
verändernden) Daten vom Zähler übernommen.

Ich würde einfach kurz bevor der Zähler einen Clock-Impuls bekommt, die 
Schieberegister laden. Dann bist du auf der sicheren Seite.

von Joe F. (easylife)


Lesenswert?

Für den parallel load muss CEPIN und PLOADPIN low sein, und du dem 
Register eine Clock geben (low->high).
Danach dann PLOADPIN wieder auf high und die Daten raustackern.

Im Augenblick samplest du vermutlich Rauschen auf deinem offenen ersten 
seriellen Input des ersten Registers.
An diesen Pin solltest du einen Pullup oder pulldown legen.

Kannst ja mal gucken, ob du nur noch nullen bekommst, wenn du diesen Pin 
mal auf GND setzt.

: Bearbeitet durch User
von Joe F. (easylife)


Lesenswert?

Das Problem ist halt, dass dein uC nicht weiss, mit welchem Abstand er 
zur Clock sampled.

Mal doof gefragt: 33KHz sind ja nicht die Welt.
Kannst du nicht einfach das Eingangssignal auf einen Input des uC legen, 
und eine Interruptfunktion zum Zählen benutzen?
Die ist ja entsprechend kurz...

void interrupt_function()
{
  counter_value++;
}

: Bearbeitet durch User
von derguteweka (Gast)


Lesenswert?

Moin,

Abgesehen von den schon angesprochenen Problemen: Ist das wirklich so 
gewollt, dass der Q12 der 4040s jeweils nicht an einen 
Schieberegistereingang gefuehrt ist? Deren Resetpins so offen rumfliegen 
lassen, ist sicher auch nicht gut.

Gruss
WK

von Joe F. (easylife)


Lesenswert?

derguteweka schrieb:
> Abgesehen von den schon angesprochenen Problemen: Ist das wirklich so
> gewollt, dass der Q12 der 4040s jeweils nicht an einen
> Schieberegistereingang gefuehrt ist?

Hehe, good catch, total übersehen. 3 Schieberegister reichen natürlich 
nur für 24 Bit = 2 Counter.

von Chris (Gast)


Lesenswert?

Hallo Leute.
Vielen Dank für die schnelle Hilfe. Warum einfach wenns auch kompliziert 
geht. Den Impuls der RTC direkt über nen Interrupt zu zählen . . . Warum 
komm ich da net selber drauf. Da ich sonst keine zeitkritischen 
Funktionen im späteren Gesamtprogramm haben werde, ist das ne super 
Alternative. Werde die Möglichkeit mal im Zusammenhang mit dem Rest 
testen.

Danke nochmal. Euer Forum und die erfahrenen Leute hier haben mir schon 
oft und viel geholfen.

von Joe F. (easylife)


Lesenswert?


: Bearbeitet durch User
von Chris (Gast)


Lesenswert?

Danke für den Hinweis.
Ich nutze eine externe RTC inkl. Temperatursensor für sehr genaue 
Impulse da ich von dem Onboardcounter nicht so ganz überzeugt bin.

Im Ganzen wird die Schaltung zur Zeitmessung mit der Genauigkeit 1//100s 
eingesetzt. Da hier später noch andere Tolleranzen mit reinspielen, wie 
z.B. allein die Ansprechzeit der Lichtschranken von ca. 500 μs, will ich 
Fehler wo es nur geht minimieren. Ich bin sicher, die externe RTC ist 
genauer als der Onboardchip des Arduino.

von Chris (Gast)


Lesenswert?

Chris schrieb:
> Ich nutze eine externe RTC

Werde allerdings noch einen Frequenzteiler einsetzen, dann ist der 
Interrupt denke auch nicht so gefordert ;-)

von Chris (Gast)


Lesenswert?

@administrator

Der Thread kann geschlossen werden. Ich denke das Problem (Knoten im 
Hirn) ist behoben.

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.