Forum: Mikrocontroller und Digitale Elektronik Analogmux am µC - was läuft schief?


von Alex (Gast)


Lesenswert?

Hallo,

Ich teste gerade einen HEF4051B an einem AVR µC
http://www.nxp.com/documents/data_sheet/HEF4051B.pdf

So wie ich das Datenblatt verstehe ist das ganze eigentlich sehr 
einfach:
Enable (E) auf active Low und die drei Eingänge S1-S3 mit einem 3Bit 
Wort belegen um Z auf einen der 8 Yn Ausgänge zu schalten.

Nun habe ich alles aufgebaut und den Controller programmiert - blos 
verhält sich der MUX nicht so wie er soll:

*Es wird immer nur der letzte im Code angesprochene Ausgang aufgemacht 
und dann gehalten (auch während beim neuen Loop der erste Ausgang dran 
wäre*
1
DDRA= (1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3); // MUX Control Signal (Output)
2
3
 while(1)
4
    {
5
    
6
    /* Pinbelegung
7
     PA3  Logic  34    MSB    S3
8
     PA2  Logic  35           S2
9
     PA1  Logic  36    LSB    S1
10
     PA0  Logic  37    Enable  E */
11
    
12
    // Test LED1 blinken
13
                LED1_on();        
14
    _delay_ms(500);
15
    LED1_off();
16
    _delay_ms(500);
17
    
18
    // Enable MUX und Y0 (0b000)
19
    PORTA &= ~((1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3));  
20
    _delay_ms(2000);
21
    
22
    // Disable MUX + wait
23
    PORTA |= (1<<PINA0);
24
    _delay_ms(2000);
25
    
26
    // Test LED2 blinken
27
    LED2_on();
28
    _delay_ms(500);
29
    LED2_off();
30
    _delay_ms(500);
31
    
32
    // Enable MUX und Y1 (0b001)
33
    PORTA &= ~((1<<PINA0) | (1<<PINA2) | (1<<PINA3));          
34
    PORTA |= (1<<PINA1);
35
    _delay_ms(2000);
36
    
37
    }

Was mache ich falsch?
Zum test läuft ein konstantes PWM Signal in Z, das ich zuerst auf Y0 und 
dann Y1 messen will.

Was ich messe: Das PWM Signal auf Y1 mit kurzer Unterbrechung, aber über 
den Zeitslot von Y0 hinweg.

von Nico (nico123)


Lesenswert?

Warum deaktivierst Du den Muxer zwischendrin?

Du schaltest LED1 an und wieder aus...Y0 aktiv...Muxer aus...LED2 an und 
wieder aus...Y1 aktiv und wieder von vorn.

Das ist nicht das, was Du haben willst (jedenfalls nicht nach deiner 
Erklärung)!!!

von Alex (Gast)


Lesenswert?

Ich deaktiviere in zwischendurch, weil ich auch den effekt sehen will. 
ich war zwischenzeitlich nicht sicher, ob beim HEF sowas wie ein 
shiftregister erst aktiviert werden muss, ist aber eh quatsch (zumindest 
nach Logikaufbau im Datenblatt).

Ich hatte es zwischenzeitlich auch ohne Deaktivierung, daran liegts 
zumindest leider nicht.

Merkwürdig ist, dass ich auch am Oszi einfach keine Pin-Highs sehe wenn 
sie kommen sollten (z.B. wenn durch E deaktiviert wird). Blos: ich habe 
keine kurzschlüsse, die pins gehen genau von µC zu HEF, keine kurzen, 
keine pull-up oder -down widerstände etc.

von Nico (nico123)


Lesenswert?

Kontrolliere nochmal die gesamte Schaltung, hast Du die 
Versorgungsspannung am Muxer dran mit Block-Kondensator?
Kannst Du denn dein Eingangssignal mit dem Oszi messen?

Zeig mal deine gesamte Schaltung!

von Alex (Gast)


Lesenswert?

Die gesamte Schaltung ist zu komplex, ich glaube das bringt hier nichts, 
sorry

Nur so viel: Versorgung stimmt, PWM-Testsignal stimmt, die Schaltung an 
sich funktioniert (hardwartechnisch) sehr sicher, ich kann die pins auch 
einzeln hochziehen dann klappt das. Überprüfen tu ich alles mit Oszi - 
es muss am code liegen, da bin ich ziemlich sicher :/

von Nico (nico123)


Lesenswert?

Dann miss doch mal die Steuersignale für den Muxer und schaue ob sie so 
sind wie sie sein sollen!

von Alex (Gast)


Lesenswert?

Noch ein TestCase:

Es werden nacheinander die Pins A1, A2 und A3 hochgezogen, A0 (Enable) 
ist dauerhaft Low, damit sollte der Mux schalten.

Nach PA1 haben wir am Mux Eingang anliegen:
0b001
Nach PA2 liegt
0b011
Nach PA3
0b111.

Das passiert auch (mit Oszi überprüft).

Erwarten würde ich nun, dass ich erst am Y1, dann an Y3 und dann an Y7 
mein Testsignal messen kann.
ABER:
Das Testsignal liegt durchgehend auf Y7!
1
while(1)
2
    {
3
    PORTA &= 0b11110000;
4
    
5
    /* Pinbelegung
6
     PA3        Logic      34    MSB    S3
7
     PA2        Logic      35        S2
8
     PA1        Logic      36    LSB    S1
9
     PA0        Logic      37    Enable  E */
10
    
11
    // Test LED1 blinken
12
        LED1_on();                              
13
    _delay_ms(500);
14
    LED1_off();
15
    _delay_ms(500);
16
    
17
18
    PORTA |= (1<<PINA1);
19
    _delay_ms(500);
20
    
21
    LED1_on();
22
    _delay_ms(500);
23
    LED1_off();
24
    _delay_ms(500);
25
    
26
    PORTA |= (1<<PINA2);
27
    _delay_ms(500);
28
    
29
    LED1_on();
30
    _delay_ms(500);
31
    LED1_off();
32
    _delay_ms(500);
33
    
34
    PORTA |= (1<<PINA3);
35
    _delay_ms(500);
36
        
37
    
38
        // Test LED2 blinken
39
    LED2_on();
40
        _delay_ms(500);
41
        LED2_off();
42
        _delay_ms(500);
43
    
44
    }

von Maxx (Gast)


Lesenswert?

Alex schrieb:
> PORTA &= ~((1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3));
>     _delay_ms(2000);
>
>     // Disable MUX + wait
>     PORTA |= (1<<PINA0);
>     _delay_ms(2000);
>
>     // Test LED2 blinken
>     LED2_on();
>     _delay_ms(500);
>     LED2_off();
>     _delay_ms(500);
>
>     // Enable MUX und Y1 (0b001)
>     PORTA &= ~((1<<PINA0) | (1<<PINA2) | (1<<PINA3));

Port A hat also immer auf P1..P2 eine 0. Du setzt sie nie auf 1
Mit &= kannst du keine Bits setzen nur löschen.

von Alex (Gast)


Lesenswert?

Maxx schrieb:
> Port A hat also immer auf P1..P2 eine 0. Du setzt sie nie auf 1
> Mit &= kannst du keine Bits setzen nur löschen.

das stimmt, ich lösche die bits, damit für Y0 am Port eine 0b000 
anliegt, für Y1 lösche ich alle bis auf PinA1, das setze ich ja danach 
mit |=

Alex schrieb:
> PORTA &= ~((1<<PINA0) | (1<<PINA2) | (1<<PINA3));
>     PORTA |= (1<<PINA1);

Sollte doch eigentlich am PORTA ein 0bxxxx0010 ergeben oder nicht?

von Nico (nico123)


Lesenswert?

Alex schrieb:
> Maxx schrieb:
>> Port A hat also immer auf P1..P2 eine 0. Du setzt sie nie auf 1
>> Mit &= kannst du keine Bits setzen nur löschen.
>
> das stimmt, ich lösche die bits, damit für Y0 am Port eine 0b000
> anliegt, für Y1 lösche ich alle bis auf PinA1, das setze ich ja danach
> mit |=
>
> Alex schrieb:
>> PORTA &= ~((1<<PINA0) | (1<<PINA2) | (1<<PINA3));
>>     PORTA |= (1<<PINA1);
>
> Sollte doch eigentlich am PORTA ein 0bxxxx0010 ergeben oder nicht?

Das passt schon! Da sollte der Maxx nochmal drüber nachdenken! ;-)

Ich würde sagen dein Muxer ist defekt, wenn Du die Signale richtig 
nachgemessen hast!
Was machst Du in der Funktion LEDx_on bzw LEDxoff?

von Alex (Gast)


Lesenswert?

Nico ... schrieb:
> Was machst Du in der Funktion LEDx_on bzw LEDxoff?

da läuft das einfachste vom einfachsten ;)
1
void LED1_on()
2
 {
3
   PORTA |= (1<<PINA4);
4
 }
5
 
6
 void LED1_off()
7
 {
8
   PORTA &= ~(1<<PINA4);
9
 }
10
 
11
 void LED2_on()
12
 {
13
   PORTA |= (1<<PINA5);
14
 }
15
 
16
 void LED2_off()
17
 {
18
   PORTA &= ~(1<<PINA5);
19
 }

Allerdings denke ich gerade doch über die Beschaltung nach...

Mal eine kurze Frage an euch: Wenn ihr ins datenblatt schaut (erster 
Post): Wie würdet ihr bei +5V und GND die Pins VEE, VSS und VDD 
beschalten?

Vielleicht ist mir da etwas dummes passiert, das schaue ich mir jetzt 
mal an...

von Maxx (Gast)


Lesenswert?

Nico ... schrieb:
> Da sollte der Maxx nochmal drüber nachdenken! ;-)

Jo. Hab die Zeile übersehen.

von Nico (nico123)


Lesenswert?

Alex schrieb:
> Mal eine kurze Frage an euch: Wenn ihr ins datenblatt schaut (erster
> Post): Wie würdet ihr bei +5V und GND die Pins VEE, VSS und VDD
> beschalten?

Vss ist GND. Vee und Vdd sind 5V.

von Alex (Gast)


Lesenswert?

Zur Beschaltung:

Ich habe VSS = VEE = GND und VDD = +5V. Das entspricht auch den "test 
circuits" im datenblatt. Allerdings hat mich gerade aus dem konzept 
gebracht:

"VEE and VSS are the supply voltage connections for the switches" klingt 
ja nach oberem und unteren Limit. Außerdem hat mir google eben das hier 
gezeigt:

http://blogs.iad.zhdk.ch/color-light-hs11/analoger-multiplexer/

und der schaltet VEE auf VDD...

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:

>
> Mal eine kurze Frage an euch: Wenn ihr ins datenblatt schaut (erster
> Post): Wie würdet ihr bei +5V und GND die Pins VEE, VSS und VDD
> beschalten?

Blöde Frage.
So wie im Datenblatt angegeben
1
Symbol Pin Description
2
...
3
VEE     7   supply voltage
4
VSS     8   ground supply voltage
5
6
VDD    16   supply voltage

alle 'supply voltage' kommen nach +5V.
alle 'ground supply voltage' kommen auf GND

Wie denn auch sonst.

Hastr du wieder mal nicht alles angeschlossen?

: Bearbeitet durch User
von Alex (Gast)


Lesenswert?

Karl Heinz schrieb:
> Hastr du wieder mal nicht alles angeschlossen?

Doch, blos falsch. :P

Karl Heinz schrieb:
> Blöde Frage.

Stimmt.

von Route_66 (Gast)


Lesenswert?

Hallo!
Was ist im datenblatt unverständlich, wenn für Ron Vee auf 0V und VDD 
auf 5 V stehen?

von Nico (nico123)


Lesenswert?

Anscheinend kommt Vee wirklich auf GND. Oder sehe ich das falsch? Das 
ist verwirrend!
In den ganzen characteristics-Daten wird Vss=Vee angenommen!

: Bearbeitet durch User
von Route_66 (Gast)


Lesenswert?

VEE kommt bei unipolarer Spannung auf GND, bei bipolarer an eine 
negative Vorspannung.

von Karl H. (kbuchegg)


Lesenswert?

Kann ich dir nicht sagen.

Aus dem Datenblatt
1
VDD and VSS are the supply voltage connections for the digital
2
control inputs (S1 to S3, and E). The VDD to VSS range is 3 V to 15 V.
3
The analog inputs/outputs (Y0 to Y7, and Z) can swing between VDD as
4
a positive limit and VEE as a negative limit. VDD  VEE may not
5
exceed 15 V. Unused inputs must be connected to VDD, VSS, or another
6
input. For operation as a digital multiplexer/demultiplexer, VEE is
7
connected to VSS (typically ground). VEE and VSS are the supply
8
voltage connections for the switches.

Zusammen mit dem Blockschaltbild der internen Baugruppen, ist das 
eigentlich meiner Meinung nach recht eindeutig, warum es da 3 Anschlüsse 
gibt

Vss ist für alle der 0-Bezug, also GND
Vdd ist für alle Baugruppen das positive Maximum
Vee ist für die 'Treiberstufe' das negative Minimum

d.h für den Logikteil ist Vcc und Vss zuständig.
Die Spannung am Ausgang wird über Vdd und Vee generiert, damit der 
Baustein auch negative Spannungen (man denke an AUdio-Sachen) 
multiplexen kann.

Brauche ich das nicht, dann eben Vee an Vss.

Wo ist da jetzt das Problem?

: Bearbeitet durch User
von Nico (nico123)


Lesenswert?

Karl Heinz schrieb:
> Wo ist da jetzt das Problem?

VEE = supply voltage ist für mich verwirrend.
Aber ich habs jetzt verstanden.

Das bringt aber Alex nicht weiter, denn so hat er es richtig 
angeschlossen!

von Holm T. (Gast)


Lesenswert?

PortA am AVR ist nicht zufällig der JTAG Port und inaktiv?
..oder AVCC offen?

Gruß

Holm

von Alex (Gast)


Lesenswert?

Route_66 schrieb:
> VEE kommt bei unipolarer Spannung auf GND, bei bipolarer an eine
> negative Vorspannung.


Karl Heinz schrieb:
> Vss ist für alle der 0-Bezug, also GND
> Vdd ist für alle Baugruppen das positive Maximum
> Vee ist für die 'Treiberstufe' das negative Minimum

Naja so hatte ich das eigentlich auch verstanden, mein negatives Minimum 
sollte halt GND sein. Blos ist das ja dann mit

Karl Heinz schrieb:
> alle 'supply voltage' kommen nach +5V.
> alle 'ground supply voltage' kommen auf GND
>
> Wie denn auch sonst.

nicht ganz im einklang. und mit 
http://blogs.iad.zhdk.ch/color-light-hs11/analoger-multiplexer/ auch 
nicht aber ich weiß ja nicht ob dessen schaltung so lief wie sie sollte.

Anyway: Ich habs grade umgelötet und sehe nun, dass mein PWM Signal 
einen netten 4V Offset hat und ALLE ausgänge des HEF durchschalten und 
zwar einen schön hässlichen Sägezahn..

von Alex (Gast)


Lesenswert?

Holm Tiffe schrieb:
> PortA am AVR ist nicht zufällig der JTAG Port und inaktiv?
> ..oder AVCC offen?

Beides nope. :)

von Alex (Gast)


Lesenswert?

Nico ... schrieb:
> Das bringt aber Alex nicht weiter, denn so hat er es richtig
> angeschlossen!

Ja so ist es dann wohl, ich löte mal zurück.
Und Mein Ursprungsproblem ist dann wohl nicht gelöst ;)

von Nico (nico123)


Lesenswert?

GND von Controller und Muxer sind verbunden?
Auf dem Muxer steht auch wirklich 4051?

von Alex (Gast)


Lesenswert?

Nico ... schrieb:
> GND von Controller und Muxer sind verbunden?
> Auf dem Muxer steht auch wirklich 4051?

Ja und Ja (HEF4051BT)

von Alex (Gast)


Lesenswert?

Nochmal zurück auf den Code:

Dass da etwas nicht stimmt, kann ich ausschließen? Haltet ihr den für 
richtig?

Wie gesagt:

Alex schrieb:
> Es werden nacheinander die Pins A1, A2 und A3 hochgezogen, A0 (Enable)
> ist dauerhaft Low, damit sollte der Mux schalten.
>
> Nach PA1 haben wir am Mux Eingang anliegen:
> 0b001
> Nach PA2 liegt
> 0b011
> Nach PA3
> 0b111.
>
> Das passiert auch (mit Oszi überprüft).
>
> Erwarten würde ich nun, dass ich erst am Y1, dann an Y3 und dann an Y7
> mein Testsignal messen kann.
> ABER:
> Das Testsignal liegt durchgehend auf Y7!

1
 while(1)
2
    {
3
    PORTA &= 0b11110000;
4
    
5
    /* Pinbelegung
6
     PA3        Logic      34    MSB    S3
7
     PA2        Logic      35        S2
8
     PA1        Logic      36    LSB    S1
9
     PA0        Logic      37    Enable  E */
10
    
11
    // Test LED1 blinken
12
        LED1_on();                              
13
    _delay_ms(500);
14
    LED1_off();
15
    _delay_ms(500);
16
    
17
18
    PORTA |= (1<<PINA1);
19
    _delay_ms(500);
20
    
21
    LED1_on();
22
    _delay_ms(500);
23
    LED1_off();
24
    _delay_ms(500);
25
    
26
    PORTA |= (1<<PINA2);
27
    _delay_ms(500);
28
    
29
    LED1_on();
30
    _delay_ms(500);
31
    LED1_off();
32
    _delay_ms(500);
33
    
34
    PORTA |= (1<<PINA3);
35
    _delay_ms(500);
36
        
37
    
38
        // Test LED2 blinken
39
    LED2_on();
40
        _delay_ms(500);
41
        LED2_off();
42
        _delay_ms(500);
43
44
    
45
    
46
    }

Die Beschaltung schien/scheint ja zu stimmen (lag ich da also doch 
richtig), je nachdem was ich auf den µC flashe wird aber immer nur der 
letzte (summarische) Ausgang des HEF geschaltet, ist ja nur in diesem 
Fall Y7.

Active Low Enable so wie es im Datenblatt verwendet wird bedeutet doch: 
Einmal low gehalten funktioniert der MUX im Pass-Through, jede S1-S3 
Kombination sollte sich sofort auf die Ausgänge auswirken. Oder?

von Nico (nico123)


Lesenswert?

Alex schrieb:
> Active Low Enable so wie es im Datenblatt verwendet wird bedeutet doch:
> Einmal low gehalten funktioniert der MUX im Pass-Through, jede S1-S3
> Kombination sollte sich sofort auf die Ausgänge auswirken. Oder?

Ja, so ist es richtig.
Dein Eingangssignal ist ein PWM-Signal? Wo kommt es her, ist die Masse 
mit angeschlossen und welche Frequenz hat es?

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:
> Nochmal zurück auf den Code:
>
> Dass da etwas nicht stimmt, kann ich ausschließen? Haltet ihr den für
> richtig?

Ja, halte ich für richtig.

Ausserdem: wenn du direkt im IC an den Pins die richtigen Signale an den 
Multiplexer-Auswahl Pins siehst und auch Enable korrekt bedient wird, 
dann ist es letzten Endes egal, ob dein Programm jetzt 'richtig' ist 
oder nicht. Den IC interessiert das ja letzten Endes nicht wirklich. Der 
kümmert sich ja nur um seine Eingänge.

Wenn du dir nicht über den Weg traust (was ok ist), dann geh halt so 
vor: nimm den IC aus der Schaltung raus. Häng ihm an den 
Mux-Auswahl-Eingängen ein paar Umschalter drann, an die Yn Eingänge ein 
paar konstante Spannungen (paar Potis als Spannungsteiler) und dann 
schaltest du eben händisch. Muss ja genau so gehen und du hast erst mal 
ausser dem IC alle anderen Fehlerquellen ausgeschlossen.

Mach ich sowieso meistens mit neuen IC, die ich nicht kenne und die 
keine Hochfrequenz brauchen :-)
Hat sich bewährt, erst mal händisch durchzuprobieren, wie da die 
Zusammenhänge sind. Auf einmal versteht man dann auch Schieberegister 
wunderbar, wenn man selber den Schalter (oder Taster mit Pullup) 
betätigen muss.

: Bearbeitet durch User
von Alex (Gast)


Lesenswert?

Also ich habe den µC port einfach mal auf Eingang (high impedance) 
geschaltet und die S1-3 Pins des MUX händisch auf 5 volt gelegt, dann 
klappt alles. Der HEF ist also funktional und richtig beschaltet.

Dann nochmal den µC getestet: Es scheint so zu sein, dass der µC eben 
NICHT alle Pins hochzieht, wenn er das laut code eigentlich tun sollte.
Ich versteh's nicht

von Alex (Gast)


Lesenswert?

Ach ist ja interessant.
1
DDRA = 0b00111111;

anstatt
1
DDRA= (1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3);    // MUX Control Signal (Output)
2
DDRA= (1<<PINA4) | (1<<PINA5);

und es funktioniert...

Port directions kann man so also nicht setzen?

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:
> Ach ist ja interessant.
>
>
1
DDRA = 0b00111111;
>
> anstatt
>
>
1
DDRA= (1<<PINA0) | (1<<PINA1) | (1<<PINA2) | (1<<PINA3);    // MUX 
2
> Control Signal (Output)
3
> DDRA= (1<<PINA4) | (1<<PINA5);
>

Gratuliere. MIt der 2-ten Zuweisung hast du gerade die erste Zuweisung 
rückgängig gemacht. Die Pins sind jetzt wieder Eingang. Mit den Ausgaben 
auf PORTA schaltest du nur noch den Pullup zu und wieder weg.

Oder erwartest du im Ernst, dass nach
1
   i = 5;
2
   i = 127;

nach der 2.ten Zuweisung noch irgendwas von der 5 'überlebt' hat?

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Gratuliere. MIt der 2-ten Zuweisung hast du gerade die erste Zuweisung
> rückgängig gemacht. Die Pins sind jetzt wieder Eingang. Mit den Ausgaben
> auf PORTA schaltest du nur noch den Pullup zu und wieder weg.

Allerdings frage ich mich jetzt:
Was hast du eigentlich dann am Oszi gesehen? Denn laut deinen Aussagen, 
stimmen ja die Pegel an den MUX-Eingängen S1-S3

: Bearbeitet durch User
von Alex (Gast)


Lesenswert?

Nein, das stimmt. Der Fehler ist wohl durch weglassen des &= / |= 
passiert...

Und mal wieder über verknotete Schnürsenkel gestolpert, trotzdem 
glücklich.

von Alex (Gast)


Lesenswert?

Karl Heinz schrieb:
> Was hast du eigentlich dann am Oszi gesehen? Denn laut deinen Aussagen,
> stimmen ja die Pegel an den MUX-Eingängen S1-S3

Ich habe inzwischen den Controller ca. 20 mal geflasht und alles 
mögliche getestet, da haben dann auch die ausgänge mal gestimmt. in dem 
Fall vielleicht sogar weil ich die LEDs einmal rausgenommen hatte (und 
damit die directions nicht überschrieben)..

von Karl H. (kbuchegg)


Lesenswert?

Alex schrieb:
> Nein, das stimmt. Der Fehler ist wohl durch weglassen des &= / |=
> passiert...
>
> Und mal wieder über verknotete Schnürsenkel gestolpert, trotzdem
> glücklich.

Tja.
Was du noch lernen sollst:
Poste IMMER dein komplettes Programm und nicht nur Ausschnitte. Denn der 
Fehler wäre um 10:38 bereits aufgefallen.

von Alex (Gast)


Lesenswert?

Danke, das merke ich mir wirklich.

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.