Zur Übersicht - INFO - Neueste 50 Beiträge - Neuer Beitrag - Suchen - Zum C-Control-I-Forum - Zum C-Control-II-Forum

Re: I2C Probleme Kategorie: Programmierung C (von Tobias - 22.07.2017 14:32)
Als Antwort auf I2C Probleme von FelixM - 21.07.2017 10:48

Hallo Felix,

aus meiner Erfahrung her kannst Du die "64" nicht in den Header des I2C_Write setzen.
Du musst Control und Data-Bytes in ein Array geben und alles als Daten rüberschicken.
Also eher h2 = I2C_Write(144,0,0,h3,2);, wobei h3 zwei Speicherstellen hat (h3[2])
und h3[0]=64 und h3[1]=128.

Ich habe leider den Baustein nicht, ich denke aber so könnte es funktionieren. Anbei mein
Programm für eine DA-Baustein AD5625R. Vielleicht kannst Du da nützliche Informationen
entnehmen.

VG, Tobias


#define dac1 0x20        //DAC1 = Adresse 0x20
#define dac2 0x3E        //DAC2 = Adresse 0x3E

#define port1_Umax 5000  //Port hat Uout 0-5000mV
#define port2_Umax 5000  //Port hat Uout 0-1100mV
#define port3_Umax 5000
#define port4_Umax 5000

#define port5_Umax 5000
#define port6_Umax 5000
#define port7_Umax 5000
#define port8_Umax 5000

#define DA1 1
#define DA2 2
#define DA3 3
#define DA4 4
#define DA5 5
#define DA6 6
#define DA7 7
#define DA8 8

//Bsp. für Ansprechen von set_voltage: set_voltage(da_laser,dac1,5000);
//1Bit=1,221mV bei 5Vmax
//spg_out in mV übergeben! Hier dann Umrechnung in Bit!
//Port-Nr. von 1-8 ACHTUNG!!! Eigentlich Port_Nr. von 0-3
void set_voltage (byte port, float spg_out)
{
    byte msb, lsb, rw, cmd, port_merker;
    byte settings[3]; // für die neue I2C-Funktion (AVR132) nötig
    //float data_float;
    word data;
    byte addr;

     switch (port)
        {
         case 1: //Umrechnung Kanal 1
         data=spg_out*(5000/port1_Umax)/1.221;
         //data=spg_out/1.221;
         break;

         case 2: //Umrechnung Kanal 2
         data=spg_out*(5000/port2_Umax)/1.221;
         break;

         case 3: //Umrechnung Kanal 3
         data=spg_out*(5000/port3_Umax)/1.221;
         break;

         case 4: //Umrechnung Kanal 4
         data=spg_out*(5000/port4_Umax)/1.221;
         break;

         case 5: //Umrechnung Kanal 5
         data=spg_out*(5000/port5_Umax)/1.221;
         break;

         case 6: //Umrechnung Kanal 6
         data=spg_out*(5000/port6_Umax)/1.221;
         break;

         case 7: //Umrechnung Kanal 7
         data=spg_out*(5000/port7_Umax)/1.221;
         break;

         case 8: //Umrechnung Kanal 8
         data=spg_out*(5000/port8_Umax)/1.221;
         break;
        };

    // Zuweisung Baustein-Adresse, abhängig vom Port
    if(port>=1 && port <=4)
    {
     addr=dac1;
     port_merker=port-1;
    }
    if(port>=5 && port <=8)
    {
     addr=dac2;
     port_merker=port-5;
    }

    rw=0; //rw=read(1)/write(0)
    cmd=0b011000+(port_merker);

    //data=data_float;
    data=data<<4;  //Ersten vier Bit werden nicht genutzt, Daten von Bit 5-16
    lsb=data; //Da lsb(byte) nur 8-Bit hat, werden Bit 9-16 von "data" abgeschnitten
    msb= data >> 8; //Bit 9-16 von Data in msb "schieben"
    //addr=(addr << 1) + rw; //Bit 1 im Adressbit mit RW belegen, Adresse in Bit 2-8


    settings[0]=cmd;
    settings[1]=msb;
    settings[2]=lsb;
    Thread_Lock(1);
    I2C_Write(addr,0,0,settings,3);
    Thread_Lock(0);
    /* alt (Meag128)
    Thread_Lock(1); //Threadwechsel unterbinden
    I2C_Start();
    I2C_Write(addr);
    I2C_Write(cmd);
    I2C_Write(msb);
    I2C_Write(lsb);
    I2C_Stop();
    Thread_Lock(0);
    */





> Hallo zusammen,
>
> Ich versuche grad über die Funktionen der I2C Bibliothek des AVR32 den analogen Ausgang des PCF8591
> anzusprechen.
>
> seine Adresseneingänge habe ich auf Masse gelegt, sodass er eine Adresse von 0x90 für W und 0x91 für R
> haben muss und I2C_Probe gibt mir auch zurück, dass er da ist (also eine 1)
>
> I2C_Write hingegen gibt mir bei gleicher Adresse(0x90) immer eine 1 zurück und ich habe keine Ahnung
> woran es liegt.
> Die Ausgabe erfolgt übrigens über eine der USART Schnittstellen.
> Das Programm sieht bei mir folgendermaßen aus:
>
> void Rs232Initbeide(void)
> {
>   Serial_Init(2,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD9600);
>   Serial_Init(1,SR_8BIT|SR_1STOP|SR_NO_PAR,SR_BD9600);
>   pause(20);
> }
>
> void main(void)
> {
>      byte h1,h2,h3[1],h4[1];
>      char t1[100];
>      h3[0] = 128;
>      I2C_SetSpeed(I2C_100kHz);
>      Rs232Initbeide();
>
>      while(1)
>   {
>    
>    h2 = I2C_Write(144,64,1,h3,1);                       //I2C Schaltkreis beschreiben über I2C Bibo
>    Str_WriteInt(h2,t1,0);                               //Ausgabe 0 -> erfolgreich | -1 -> Übertragungsfehler
>    Serial_WriteText(1,t1);                              //konfigurierte Adresse: W 144 R 145
>
>
>     //Newline rs232
>     Serial_Write(1,LF);
>     Serial_Write(1,CR);
>     Pause(20);
>    }
> }
>
>
> der Parameter 64 bei I2C_Write ist das control byte des PCF8591,
>  welches den analogen Output aktiviert.
>
> Hoffe mal hier kann mir jemand helfen :D
> Vielen Dank im Voraus
>
> Felix


    Antwort schreiben


Antworten: