Analogmux am µC - was läuft schief?

Gast #3413732
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.
Gast #3413777
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.
Gast #3413797
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 :/
Gast #3413809
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
    }
Gast #3413813
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.
Gast #3413822
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?
#3413831
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?
Gast #3413845
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...
Gast #3413853
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...
#3413856
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?
#3413883
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?
Gast #3413905
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..
Gast #3413943
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?
#3413946
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?
#3413947
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.
Gast #3414019
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
Gast #3414025
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?
#3414031
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?
#3414042
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
Gast #3414048
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)..

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren