Forum: Mikrocontroller und Digitale Elektronik ATXmega32A4 & MCP4018 I²C dig. Poti Problem


von MOBA 2. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich komme einfach nicht mehr weiter. Ich versuche ein digitales Poti 
(MCP4018) anzusprechen. Das soll via I²C gehen. Prozessor ATXmega32A4 @ 
32Mhz. Anbei mal mein Codeschnipsel (nutze die Atmel Lib für I²C):
1
TWI_MasterInit(&twiMaster, &TWIC, TWI_MASTER_INTLVL_HI_gc, TWI_BAUD(F_CPU, 100000));    //init i2c & digit poti
2
  sei();
3
4
  uint8_t data[2] = {128, 125};
5
6
  while (1)
7
  {
8
    wdt_reset();
9
    TWI_MasterWrite(&twiMaster, 0x2F, &data[0], 2);
10
    _delay_ms(50);
11
  }
12
13
14
15
16
ISR(TWIC_TWIM_vect)
17
{
18
  TWI_MasterInterruptHandler(&twiMaster);
19
}


Ich verstehe es echt nicht. Ich habe bereits mal auf einem ATXmega256A3 
einen Slave programmiert für I²C, dass ging super. Es soll ganz simpel 
sein, ich will nur schreiben und fertig. Kein Lesen und nichts. Mir 
reicht es, einfach das Poti zu verändern (Lautstärkeänderung).

Das Poti habe ich (hoffe/denke) ich richtig eingelötet. Da war ein 
kleiner Punkt drauf das habe ich als PIN1 gedeutet. Auch so, zwischen 
den Wiper liegt ja das DAC-Signal an, ich habe ca. halbe Lautstärke 
(sollte also wirklich apssen vom einlöten).

Vom Anschluss her:

Pin1 = 3,3V
PIN2 = GND
PIN3 = SCL
PIN4 = SDA
PIN5 = Richtung Audioverstärker Eingang
PIN6 = DAC_Ausgang vom XMega



Nach dem Reset bekomme ich ein Start-Bit erzeugt, dann war es dass. Es 
geht nichts mehr. Ich muss den Controller resetten, dann wieder das 
Start-Bit (bzw. das was man im Bild sieht) und wieder nichts.

Das Status-Register ist dabei auch permanent 1. Ich bin überfragt, er 
müsste ja doch wenigstens die Adresse aussenden, wenn dann kein ACK 
kommt okay, dann liegt es am MCP4018 aber warum bricht der denn schon 
direkt nach dem Start ab?!


Edit:

Nach dem Reset der MCU kommt das Signal vom Bild, Statusregister ist 2 
(DIR Bit gesetzt => Read operation?!?! Darf ja nicht sein, müsste ja 0 
sein (Write OP)

Danach ist vorbei, Status Register ist die ganze Zeit 18 (DIR weiterhin 
gesetzt, RXACK gesetzt (Receive ACK fehler)


So wie ich das sehe, will der Empfangen, ich nutze aber nur 
Sende-Befehle.
Aber selbst wenn es so wär, die Adresse müsste er ja trzd. rausschicken 
und oder sehe ich das falsch?

von Bastian W. (jackfrost)


Lesenswert?

Der Pegel deine "gelben" Leitung ist komisch, normal müsste der Pegel ja 
wegen dem Pullup im Leerlauf high sein. Sind beide Pullups eingelötet ?

Es ist ja das Busbusy gesetzt, damit macht der XMega nicht mehr weiter 
bis der Bus wieder auf Leerlauf gesetzt wird.

Gruß JackFrost

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

MOBA 2. schrieb:
> PIN6 = DAC_Ausgang vom XMega
Warum rechnest du dann nicht die Spannung vor der Ausgabe einfach 
"kleiner"?
Das, was du machst ist ja wie beim Auto "immer Vollgas fahren und die 
Geschwindigkeit mit der Bremse variieren"...

von MOBA 2. (Gast)


Lesenswert?

Lothar M. schrieb:
> MOBA 2. schrieb:
>> PIN6 = DAC_Ausgang vom XMega
> Warum rechnest du dann nicht die Spannung vor der Ausgabe einfach
> "kleiner"?
> Das, was du machst ist ja wie beim Auto "immer Vollgas fahren und die
> Geschwindigkeit mit der Bremse variieren"...


Ich weiß das hatte ich mal gemacht, aber fand ich nicht so gut, man hat 
die Stufen irgendwie gemerkt, daher will ich nun das Poti nutzen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

MOBA 2. schrieb:
> Ich weiß das hatte ich mal gemacht, aber fand ich nicht so gut, man hat
> die Stufen irgendwie gemerkt
Dann war da im Programm noch ein Fehler drin. Den solltest du finden und 
beheben.

Mit dem DAC kannst du nämlich prinzipiell feiner auflösen, der DAC hat 
immerhin 12 Bit, das sind 5 Bit mehr als das Poti...

von MOBA 2. (Gast)


Lesenswert?

Bastian W. schrieb:
> Der Pegel deine "gelben" Leitung ist komisch, normal müsste der Pegel ja
> wegen dem Pullup im Leerlauf high sein. Sind beide Pullups eingelötet ?
>
> Es ist ja das Busbusy gesetzt, damit macht der XMega nicht mehr weiter
> bis der Bus wieder auf Leerlauf gesetzt wird.
>
> Gruß JackFrost

Danke für die Antwort

Beide Pull-Ups sind drin, die sind auch im Idle high, das war nachdem er 
bereits angelaufen war, danach sind die low weil Fehler. Dann hatte ich 
µC resettet und daher kommt das.

Gelb ist Daten, Blau ist Takt wenn ich mich nicht irre.


Okay wenn State = Busbusy ist, dann erklärt das, warum er das nicht mehr 
wiederholt, aber es erklärt nicht, warum nach Start abgebrochen wird, 
wenigstens die Adresse müsste doch rausgesendet werden. Ich verstehe das 
einfach nicht. Wenn ich nach dem Fehler den State wieder auf IDLE setze 
wird er das wiederholen dann, aber über die Start Condition komme ich 
nicht hinaus.

von Bastian W. (jackfrost)


Lesenswert?

MOBA 2. schrieb:
> Okay wenn State = Busbusy ist, dann erklärt das, warum er das nicht mehr
> wiederholt, aber es erklärt nicht, warum nach Start abgebrochen wird,
> wenigstens die Adresse müsste doch rausgesendet werden. Ich verstehe das
> einfach nicht. Wenn ich nach dem Fehler den State wieder auf IDLE setze
> wird er das wiederholen dann, aber über die Start Condition komme ich
> nicht hinaus.

Das Problem ist wenn Start nicht richtig gesendet werden kann weil eine 
der beiden Leitungen schon low ist , dann bricht der xMega ab, da er 
nicht der Master auf dem Bus ist.

Ich hatte das Problem bei einem FRAM, wenn ich den µC resettet hatte 
während er was aus dem FRAM ausgelesen hat. Der FRAM war hat noch ein 
Bit auf dem Bus gelegt und dann gings nicht mehr.

Ist bei dir SDA oder SCL low ?

Wie hast du die beiden Pins konfiguriert ? Wired_And ?

Das ist von dem FRAM auf einem xMega32e5. page_adress ist die I2C 
Adresse incl. dem R/W-Bit. Adress ist das dann die Speicherzelle.
1
void twi_write(TWI_t *twiname, uint8_t *writeData,uint8_t page_adress,uint8_t Adress, uint8_t bytes,bool fixed){
2
3
  uint8_t i;
4
  TWIC_MASTER_CTRLC &= ~((1<<TWI_MASTER_ACKACT_bp));
5
  twiname->MASTER.ADDR = page_adress;
6
  while (!(TWIC.MASTER.STATUS & TWI_MASTER_WIF_bm));
7
  if(TWIC_MASTER_STATUS & (1<<TWI_MASTER_ARBLOST_bp))
8
  {
9
    twiname->MASTER.CTRLA = 0;
10
    PORTC.DIRSET = PIN1_bm;
11
    for(uint8_t i=0;i<9;i++)
12
    {
13
      PORTC.OUTSET = PIN1_bm;
14
      _delay_us(20);
15
      PORTC.OUTCLR = PIN1_bm;
16
      _delay_us(20);
17
    }
18
    PORTC.DIRCLR = PIN1_bm;
19
    twiname->MASTER.CTRLA = TWI_MASTER_ENABLE_bm;
20
    twiname->MASTER.STATUS = TWI_MASTER_ARBLOST_bm | TWI_MASTER_BUSERR_bm;
21
    twiname->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
22
    TWIC.MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
23
    twiname->MASTER.ADDR = page_adress;
24
    if(TWIC_MASTER_STATUS & (1<<TWI_MASTER_ARBLOST_bp));
25
    
26
  }
27
  twiname->MASTER.DATA = Adress;       // write word addr
28
  while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
29
  for(i=0;i<bytes;i++){
30
    if(!fixed)             // write data 
31
    twiname->MASTER.DATA =writeData[i];
32
    else
33
    twiname->MASTER.DATA =writeData[0];
34
    while(!(twiname->MASTER.STATUS&TWI_MASTER_WIF_bm));
35
  }
36
  TWIC.MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
37
}

von MOBA 2. (Gast)


Lesenswert?

Lothar M. schrieb:
> MOBA 2. schrieb:
>> Ich weiß das hatte ich mal gemacht, aber fand ich nicht so gut, man hat
>> die Stufen irgendwie gemerkt
> Dann war da im Programm noch ein Fehler drin. Den solltest du finden und
> beheben.
>
> Mit dem DAC kannst du nämlich prinzipiell feiner auflösen, der DAC hat
> immerhin 12 Bit, das sind 5 Bit mehr als das Poti...

Ich hatte das so berechnet:


DacOut = DacSample * Volume / 100.

von MOBA 2. (Gast)


Lesenswert?

Bastian W. schrieb:
> Das Problem ist wenn Start nicht richtig gesendet werden kann weil eine
> der beiden Leitungen schon low ist , dann bricht der xMega ab, da er
> nicht der Master auf dem Bus ist.
Sollte aber der Master sein eigentlich....

> Ich hatte das Problem bei einem FRAM, wenn ich den µC resettet hatte
> während er was aus dem FRAM ausgelesen hat. Der FRAM war hat noch ein
> Bit auf dem Bus gelegt und dann gings nicht mehr.
>
> Ist bei dir SDA oder SCL low ?
Am Anfang oder wann? Anfangs, nach uC Reset sind beide High, dann 
versucht er Start zu senden und SDA bleibt dann low (gelb).

> Wie hast du die beiden Pins konfiguriert ? Wired_And ?
Einfach als Ausgang mehr hatte ich nicht gemacht.

> Das ist von dem FRAM auf einem xMega32e5. page_adress ist die I2C
> Adresse incl. dem R/W-Bit. Adress ist das dann die Speicherzelle.

Ich teste das gleich mal durch.

von MOBA 2. (Gast)


Lesenswert?

Ich habe jetzt nochmal bisschen getestet. ich verstehe es einfach nicht, 
dass kann doch nicht sein.


Atmel Lib:

Ich initialisiere:

PORTC = Ausgang
PORTC SDA/SCL = WiredANdPullUp (ext. Pullup ist auch vorhanden)

TWI_MasterInit(&twiMaster, &TWIC, TWI_MASTER_INTLVL_HI_gc, 
TWI_BAUD(F_CPU, 100000));

sei();

TWI_MasterWrite(&twiMaster, 0x2F, &data[0], 1);

while (1)
{
}


Er macht den Start (klar, weil ja ADDR beschrieben wird, dann war es 
das.
Er geht nichtmal in die ISR(TWIC_TWIM_vect) rein.?!

von Bastian W. (jackfrost)


Lesenswert?

In PMIC.CTRL hast du den Highlvl Interupt aktiviert ? Es ist in deinem 
Code nicht ersichtlich ob das erledigt ist oder nicht.

Gruß JackFrost

von MOBA 2. (Gast)


Lesenswert?

Bastian W. schrieb:
> In PMIC.CTRL hast du den Highlvl Interupt aktiviert ? Es ist in deinem
> Code nicht ersichtlich ob das erledigt ist oder nicht.
>
> Gruß JackFrost

PMIC brauche ich das? Es reicht doch, dass alle Interrupts beim TWI 
aktiv sind, oder?

Ich habe das jetzt glaube soweit verstanden, aber noch nicht was das 
Problem ist.

Status IDLE
Schreibe ADDR
Status OWNER (aber nur Start gesendet), rufe dann WriteHandler auf 
(Interrupt kann nicht kommen, da ja kein Byte gesendet wurde)

Macht nichts, Status aber immer noch OWNER

Wenn ich wieder von vorne gehe (schreibe ADDR)

habe ich Status 17 (IDLE + RXACK), dann 18 (OWNER + RXACK) dann 144 
(Read Intterupt Bit?!)


Ich habe nochmal in das Errata geguckt, steht aber nichts dazu, ich 
verstehe das nicht warum der nichts rausschickt und nach Start 
abbricht?!?!


EDIT:

Ja klar im PMIC habe ich das gemacht, ich war gerade auf einer anderen 
Schiene (PINCTRL)... Sorry.

von MOBA 2. (Gast)


Lesenswert?

Ich habe den Chip (MCP) jetzt sogar mal rausgelötet, liegt nicht an dem.
Interrupt sei jetzt auch erstmal dahingestellt.

Das Problem ist: Warum sendet der START und dann nichts mehr??? Warum 
kommt die Addresse nicht???

Ich habe nachdem ADDR beschrieben wurde und das fehlschlug Bit 3-5 im 
Statusregister aktiv + Owner (=114).

Ich habe das Gefühl, das ist irgendwie ARBLOST, aber warum nur? Er hat 
doch nichtmal irgendwas gesendet oder überschneiden sich SDA/SCL das der 
aus dem Tritt kommt?

von MOBA 2. (Gast)


Lesenswert?

Jetzt gehts.

Ich weiß nicht warum.

Ich habe einfach mal in der Init die Baudratesetting an 2. Stelle 
gesetzt und nach CTRLA noch eine Line eingefügt in der ich CNTRC = 0 
setze.

?!

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.