Forum: Mikrocontroller und Digitale Elektronik stm32 und pcf8574T


von peter m. (bastler788)


Lesenswert?

Hallo,

ich programmiere einen STM 32 f100, welcher über I2C mit dem 
Portexpander PCF8574t verbunden ist. nun möchte ich gerne seine eingänge 
abfragen. was leider nicht klappt.

I2C Konfigurier ich wie folgt:

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, 
ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  I2C_DeInit(I2C1);

  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = 
I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_ClockSpeed = 100000;
  I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_OwnAddress1 = 0;
  I2C_Init(I2C1, &I2C_InitStructure);

  I2C_ITConfig(I2C1, I2C_IT_EVT, ENABLE);
  I2C_ITConfig(I2C1, I2C_IT_BUF, ENABLE);
  I2C_ITConfig(I2C1, I2C_IT_ERR, ENABLE);

  I2C_Cmd(I2C1, ENABLE);


Die abfrage des Portexpander sieht dan wie folgt aus:
  I2C_GenerateSTART(I2C1,ENABLE);
 I2C_Send7bitAddress(I2C1, 0x40, I2C_Direction_Transmitter);
IO_Gruppe1 = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);


Kann mir jemand helfen?

von Mike R. (thesealion)


Lesenswert?

peter müller schrieb:
> I2C_Send7bitAddress(I2C1, 0x40, I2C_Direction_Transmitter);
> IO_Gruppe1 = I2C_ReceiveData(I2C1);

Irgendwie widerspricht sich deine Einstellung Transmitter und 
ReceiveData.
Ansonsten ist I2C bei den STMs echt kompliziert. Dafür gibt es aber ein 
paar ganz gutte AppNotes, die solltest du dir mal ansehen.

von peter m. (bastler788)


Lesenswert?

Mike S. schrieb:
> peter müller schrieb:
>> I2C_Send7bitAddress(I2C1, 0x40, I2C_Direction_Transmitter);
>> IO_Gruppe1 = I2C_ReceiveData(I2C1);
>
> Irgendwie widerspricht sich deine Einstellung Transmitter und
> ReceiveData.
> Ansonsten ist I2C bei den STMs echt kompliziert. Dafür gibt es aber ein
> paar ganz gutte AppNotes, die solltest du dir mal ansehen.

habs geändert aber klappt immer noch nicht. es wird quasi die adresse wo 
ich raus schicke eingelesen

von Mike R. (thesealion)


Lesenswert?

Dann sieh dir jetzt noch einmal die angesprochenden AppNotes von ST an.
Das Kommando "I2C_Send7bitAddress" tut nämlich nichts anderes als die
Adresse um das Read/Write Bit zu erweitern und in das DataRegister zu 
schreiben.

Du musst jetzt noch warten, bis das ganze gesendet wurde, der Slave 
seine Adresse bestätigt hat und dann kannst du lesen.

von Mike R. (thesealion)


Lesenswert?

Um die Suche zu vereinfachen, hier einmal Link (aus dem STM32 Wiki hier 
auf der Seite) 
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00209826.pdf

von peter m. (bastler788)


Lesenswert?

leider kam ich noch ncht weiter =( nach dem senden der adresse habe ich 
nun wartezeiten eingefügt aber weis nicht ob die richtig sind:

I2C_GenerateSTART(I2C1, ENABLE);
I2C_Send7bitAddress(I2C1, 0x40, I2C_Direction_Receiver);

while(I2C_GetFlagStatus(I2C1,I2C_FLAG_ADDR)){}
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BTF)){}
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_RXNE)){}

IO_Gruppe1 = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);


ich mag i2C nicht

von peter m. (bastler788)


Lesenswert?

hab folgendes beispiel gefunden:

I2C_AcknowledgeConfig(I2C1, ENABLE);
/* Test on BUSY Flag */
while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on start flag */
while (!I2C_GetFlagStatus(I2C1,I2C_FLAG_SB));
/* Send address for read */
I2C_Send7bitAddress(I2C1, 0x40, I2C_Direction_Receiver);
/* Test Receive mode Flag */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
/* load in all 4 registers */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
IO_Gruppe1 = I2C_ReceiveData(I2C1);

/*enable NACK bit */
I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current);
I2C_AcknowledgeConfig(I2C1, DISABLE);

/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));





Das Programm bleibt bei der ersten While hängen. weis jemand warum?

von vampire (Gast)


Angehängte Dateien:

Lesenswert?

-wenn Du lesen willst, musst Du 0x41 senden.
Die A0--A2 auf Masse!

von peter m. (bastler788)


Lesenswert?

vampire schrieb:
> -wenn Du lesen willst, musst Du 0x41 senden.
> Die A0--A2 auf Masse!

die funktion
I2C_Send7bitAddress(I2C1, 0x40, I2C_Direction_Receiver);

macht ja aus der Adresse 0x40 die 0x41

von vampire (Gast)


Lesenswert?

-frag nur "busy" ab in der "while".
Haste A0,A1,A2 auf Masse?

von peter m. (bastler788)


Lesenswert?

vampire schrieb:
> -frag nur "busy" ab in der "while".
> Haste A0,A1,A2 auf Masse?

ja die sind auf masse und busy ist gesetzt wenn ich des im debuggmodus 
beobachte

von vampire (Gast)


Angehängte Dateien:

Lesenswert?

-ich habe mich nie lange mit I2C aufgehalten. Nur bestehenden Code 
"angepasst".
Hier mal das I2C aus einem Bsp.(24C02) von mir;

Im main dann einfach:
I2C_Configuration();
  WriteBuffer[0]=0x96;
  I2C_Write(Open_I2C,ADDR_PCF8574a,0,WriteBuffer,1);
  WriteBuffer[0]=0x69;
  I2C_Write(Open_I2C,ADDR_PCF8574b,0,WriteBuffer,1);


(für Ausgabe);
aus: 
http://www.mikrocontroller.net/attachment/157827/F4D_ETH_cam.V02.zip

von peter m. (bastler788)


Lesenswert?

vampire schrieb:
> -ich habe mich nie lange mit I2C aufgehalten. Nur bestehenden Code
> "angepasst".
> Hier mal das I2C aus einem Bsp.(24C02) von mir;
>
> Im main dann einfach:
> I2C_Configuration();
>   WriteBuffer[0]=0x96;
>   I2C_Write(Open_I2C,ADDR_PCF8574a,0,WriteBuffer,1);
>   WriteBuffer[0]=0x69;
>   I2C_Write(Open_I2C,ADDR_PCF8574b,0,WriteBuffer,1);
>
>
> (für Ausgabe);
> aus:
> http://www.mikrocontroller.net/attachment/157827/F4D_ETH_cam.V02.zip



was ist das für ne Datei im anhang?

von vampire (Gast)


Lesenswert?

-das ist 24C02.c und 24C02.h , mit 7z gepackt.
Da ist I2C_Configuration(void), I2C_Read, I2C_WriteOneByte usw. drin
(für stm32f4xx);

von peter m. (bastler788)


Lesenswert?

vampire schrieb:
> -das ist 24C02.c und 24C02.h , mit 7z gepackt.
> Da ist I2C_Configuration(void), I2C_Read, I2C_WriteOneByte usw. drin
> (für stm32f4xx);

7z kenn ich nicht, aber habs aufbekommen, aber bin leider nocht nicht 
weiter gekommen

von peter m. (bastler788)


Lesenswert?

es tut!!!!!!!!!!!!!

bei der Konfiguration war das
  GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);
der Fehler, hab ein beispiel kopiert wo dies drin war, was ich 
allerdings nicht brauche da ich die default bins verwende.

die funktion zum einlesen über i2c sieht dann wie folgt aus:
I2C_AcknowledgeConfig(I2C1, ENABLE);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));
/* Test on BUSY Flag */
while (I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));
I2C_GenerateSTART(I2C1, ENABLE);
/* Test on start flag */
while (!I2C_GetFlagStatus(I2C1,I2C_FLAG_SB));
/* Send address for read */
I2C_Send7bitAddress(I2C1,  bAdresse, I2C_Direction_Receiver);

/* load in all 4 registers */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
bReceiveData = I2C_ReceiveData(I2C1);
/*enable NACK bit */
I2C_NACKPositionConfig(I2C1, I2C_NACKPosition_Current);
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF));

return(bReceiveData);

von vampire (Gast)


Lesenswert?

-äh, nur mal so!
die
"ich programmiere einen STM 32 f100"//Kopie
STD-PERIPH_DRIVER(CMSIS) mit stm32f1xx-i2c.c/ .h hast Du 
selbstverständlich eingebunden in dein Programm?!

von vampire (Gast)


Lesenswert?

- upps, hat sich ja schon erledigt !!!

von peter m. (bastler788)


Lesenswert?

vampire schrieb:
> - upps, hat sich ja schon erledigt !!!

ja, vielen dank für eure hilfe

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.