Forum: Mikrocontroller und Digitale Elektronik AD5241 digital Poti


von H. D. (lactobacillus)


Lesenswert?

Hallo,
Ich habe mir 2 AD5241 (1MOhm) zugelegt und erst einmal einen auf eine 
Adapterplatine fürs Breadboard gelötet. Zugegebenemaßen habe ich mich 
nicht sehr geschickt angestellt und er könnte etwas heiß geworden sein. 
Habe ihn dann zum Testen angeschlossen und den Wiper an 3.3V und 
Terminal A mit einem 100k an Masse. Befehle waren 0x40 + 0x00/0xFF. In 
beiden Fällen ist der Spannungfsabfall gleich und nur knapp über 1V. 
Versuche ich die Digitalen Outputs anzusprechen, funktioniert das 
tadellos.

Ich bin dann davon ausgegangen, dass ich den Ersten einfach beim Löten 
gekillt habe, also habe ich vorsichtig den 2. eingelötet. Dieser 
reagiert genau so wier der Erste.

Jetzt glaube ich, dass ich irgendetwas bei der Ansteuerung falsch mache.

PS: Der Standby-Pin ist auf 3.3V gelegt.

von Stefan S. (chiefeinherjar)


Lesenswert?

Mist... da habe ich doch gerade meine Glaskugel in die Spülmaschine 
gelegt und das volle Umwelt-Killer-Super-Blitz-Blank-Programm angemacht. 
So schnell werde ich sie also nicht zur Hand haben.
Da bleibt dir wohl nur noch übrig den *CODE* und den *Schaltplan* zu 
posten...

von H. D. (lactobacillus)


Lesenswert?

A:    100kOhm --- GND
W:    3.3V
B:    NC
VDD:  3.3V
SHDN: 3.3V
SCL:  MSP430G2553 mit Pullup
SDA:  MSP430G2553 mit Pullup
AD0:  GND
AD1:  GND
DGND: GND
VSS:  GND
O2:   NC
NC:   NC
O1:   NC

Code kommt, wenn ich wieder zu Hause bin.

von H. D. (lactobacillus)


Lesenswert?

Hier der Code:

1
#include <msp430g2553.h>
2
3
void printRes(void){
4
5
  UCB0CTL1 = UCSWRST;
6
  UCB0CTL0 = UCMODE_3 + UCMST + UCSYNC;      // I2C master mode
7
  UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset
8
  UCB0BR0 = 0x15;                          // < 400 kHz
9
  UCB0I2CSA = 0x2C;                       // address
10
  UCB0CTL1 &= ~UCSWRST;
11
  UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
12
13
  while (!(IFG2 & UCB0TXIFG));
14
15
  UCB0TXBUF = 0x40;                           // oder 0x58
16
  while (!(IFG2 & UCB0TXIFG));
17
  UCB0TXBUF = 0x00;                           // oder 0xFF
18
  while (!(IFG2 & UCB0TXIFG));
19
20
21
  UCB0CTL1 |= UCTXSTP;
22
}
23
24
25
void main(void){
26
    WDTCTL = WDTPW + WDTHOLD;
27
28
    DCOCTL = CALDCO_8MHZ;        //DCO setting = 8MHz
29
    BCSCTL1 = CALBC1_8MHZ;        //DCO setting = 8MHz
30
31
    // Configure Pins for I2C
32
    P1SEL |= BIT6 + BIT7;                  // Pin init
33
    P1SEL2 |= BIT6 + BIT7;                  // Pin init
34
35
    printRes();
36
37
    while(1);
38
39
}

von H. D. (lactobacillus)


Lesenswert?

Die Spülmaschine müsste ja jetzt fertig sein. Was sagt die Glaskugel?

von H. D. (lactobacillus)


Lesenswert?

Würde mich freuen, wenn jemand eine Idee hätte.

von Karl H. (kbuchegg)


Lesenswert?

H. D. schrieb:
> Die Spülmaschine müsste ja jetzt fertig sein. Was sagt die Glaskugel?

Das du
1
  UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition
2
3
  while (!(IFG2 & UCB0TXIFG));
4
5
  UCB0TXBUF = 0x40;                           // oder 0x58
6
  while (!(IFG2 & UCB0TXIFG));
7
  UCB0TXBUF = 0x00;                           // oder 0xFF
8
  while (!(IFG2 & UCB0TXIFG));
sehr mutig auf jegliche Fehlerüberprüfung verzichtest.

Das mag manchmal kein Beinbruch sein. Aber zumindest nach dem Senden der 
Adresse wäre es schon eine ziemlich gute Idee festzustellen, ob der 
Slave mit einem ACK geantwortet hat.

von Karl H. (kbuchegg)


Lesenswert?

>  UCB0TXBUF = 0x40;                           // oder 0x58


Wenn der MSP genau so funktioniert wie ein AVR, dann schreibt man hier 
bereits das vollständige erste Byte ins Register.
D.h. die um 1 Bit nach links verschobene Adresse und dem R//W Bit an der 
Bitposition 0.
Also 0x58 und nicht 0x40, wenn die AD1 bzw AD0 Leitung auf 0 verdrahtet 
sind.


Edit:
wieso eigentlich 0x40? 0x40 ist doch kompletter Nonsense. Wenn ich mir 
das Bitmuster 01011xx0 um 1 Bit nach rechts verschoben vorstelle, dann 
kommt da nie und nimmer 0x40 raus. Noch nicht mal annähernd. (für xx als 
AD1 bzw AD0 setz ich 00 ein)

von H. D. (lactobacillus)


Lesenswert?

Karl Heinz schrieb:
> Wenn der MSP genau so funktioniert wie ein AVR, dann schreibt man hier
> bereits das vollständige erste Byte ins Register.

Nee, ist anders. Die Adresse kommt nicht in den Buffer, sondern in 
UCB0I2CSA.
0x2C entspricht 00101100.
Dass man Daten senden möchte, sagt man mit UCB0CTL0 |= UCMST.

Die Adresse ist auch richtig, da die Digitalausgänge sagen was sie 
machen. Ich werde aber mal nachprüfen ob nach dem allerletzten Datenbyte 
evtl. ein NACK kommt.

von Karl H. (kbuchegg)


Lesenswert?

H. D. schrieb:
> Karl Heinz schrieb:
>> Wenn der MSP genau so funktioniert wie ein AVR, dann schreibt man hier
>> bereits das vollständige erste Byte ins Register.
>
> Nee, ist anders. Die Adresse kommt nicht in den Buffer, sondern in
> UCB0I2CSA.
> 0x2C entspricht 00101100.
> Dass man Daten senden möchte, sagt man mit UCB0CTL0 |= UCMST.
>
> Die Adresse ist auch richtig,

Ah. OK.
Dann ignorier bitte den Rest. da hab ich mich von der zufälligen 
Übereinstimmung deines auskommentierten Kommandobytes 0x58 mit der 
verschobenen Adresse 0x58 (= 0x2C + Write_Bit_0) voreilig hinreissen 
lassen. Mein Fehler.

von H. D. (lactobacillus)


Lesenswert?

Kann an keinem Punkt einen NACK finden. :-(

von H. D. (lactobacillus)


Lesenswert?

Es lag am ersten Befehl. Der midscale reset darf nicht gesetzt werden. 
Außerdem war der Widerstand in der Testschaltung 1MOhm statt 1kOhm.

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.