Wie Sie initialisiert die I2C-Schnittstelle auf STM32F0?

Vor kurzem ich habe versucht, den I2C-bus arbeiten auf der STM32F030F4P6 MCU, aber mit wenig Glück.

Ich bin mit einem STM32F0-Modul und gefunden haben, ausreichende Ressourcen für die STM32F1-Modul I2C Initialisierung, aber nichts spezifisches über die STM32F0-Initialisierung/transfer-Prozess.

Hier ist mein code für die Initialisierung:

void i2c_init(uint8_t ownAddress)
{
GPIO_InitTypeDef  GPIO_InitStructure;
I2C_InitTypeDef  I2C_InitStructure;

//Enable GPIOA clocks

RCC_APB2PeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

//Configure I2C1 clock and GPIO

GPIO_StructInit(&GPIO_InitStructure);


/* I2C1 clock enable */

RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

/* I2C1 SDA and SCL configuration */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);

/* I2C1 Reset */

RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);


/* Configure I2C1                */

I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_StructInit(&I2C_InitStructure);
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
//I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
//I2C_InitStructure.I2C_ClockSpeed = ClockSpeed;


I2C_Init(I2C1, &I2C_InitStructure);
I2C_Cmd(I2C1, ENABLE); 

}

Um zu testen, um zu sehen, ob meine Einstellung richtig war, entwarf ich einige I2C-übertragung code, der die übertragung von Daten in einem nie endenden Schleife. Hier ist der code für:

while(1)
{
I2C_SlaveAddressConfig(I2C1, RegName);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_NumberOfBytesConfig(I2C1, 8);
I2C_SendData(I2C1,0b00000000);
I2C_GenerateSTOP(I2C1, ENABLE);
}

Wo:

RegName = 0x75

SDA = GPIO_PIN_10 auf GPIOA

SCL = GPIO_PIN_9 auf GPIOA

I2C = I2C1

ownAdrress = 0x68

Wenn ich den Umfang der I2C-Leitungen nach beginne ich diesen code bekomme ich eine schwebende Spannung um 160mV. Wenn ich den code schrittweise Durchlaufen jedes der I2C-Funktionsaufrufe geschehen und abgeschlossen, so dass ist, warum ich dachte, es hatte etwas mehr damit zu tun, mit meiner Initialisierung des pins selbst.

Mein problem ist sehr ähnlich zu diesem thread, aber wurde nie beantwortet:

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=https%3a%2f%2fmy%2est%2ecom%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fSTM32F0%20I2C%20code%20doesn%27t%20work&FolderCTID=0x01200200770978C69A1141439FE559eb459d7580009c4e14902c3cde46a77f0ffd06506f5b&currentviews=1342

Edit 1: Hier ist meine aktuelle code, funktioniert immer noch nicht (Edit 2: Aktualisiert, was ich derzeit habe; bewegte Dinge mehr in die richtige Position):

void i2c_init(uint8_t ownAddress)
{

    /* TypeDefs for GPIOA and I2C1 */

    GPIO_InitTypeDef  GPIO_InitStructure;
    I2C_InitTypeDef  I2C_InitStructure;

    /* Enable GPIOA clocks and I2C1 clock enable */

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

    /* Configure I2C1 clock and GPIO */

    GPIO_StructInit(&GPIO_InitStructure);

    /* I2C1 SDA and SCL configuration */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; //UP
    GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;

    /* GPIO AF Configuration -> GPIO_AF_1: USART2, CEC, Tim3, USART1, USART2,EVENTOUT, I2C1, I2C2, TIM15 */

    GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);

    GPIO_Init(GPIOA, &GPIO_InitStructure);

    /* I2C1 Reset */

    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, ENABLE);
    RCC_APB1PeriphResetCmd(RCC_APB1Periph_I2C1, DISABLE);


    //I2C_DeInit(I2C1);

    /* Configure I2C1 */

    I2C_StructInit(&I2C_InitStructure);

    I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_OwnAddress1 = ownAddress;
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;

    I2C_Init(I2C1, &I2C_InitStructure);
    I2C_Cmd(I2C1, ENABLE);
    //I2C_AcknowledgeConfig(I2C1, ENABLE);

}

Wie Sie sehen können habe ich noch die zwei Zeilen GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1); und GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); wo ich fand, dass GPIO_AF_1 hatte die Alternative Funktion der I2C1 von die STM32F0 Standard-Peripherie-bibliotheek.

Irgendwelche anderen Ideen? Ich habe das Spiel mit den Uhren zu sehen, ob das etwas geändert und wurden snippets hinzufügen, anderer Leute code, nur um zu sehen, ob das hat keine Auswirkungen auf die Ausgabe von meinem Gerät.

Edit 3: ich habe versucht, ziehen sowohl die SDA-und SCL-Linien bis VCC mit einem 1kohm-Widerstand entsprechend der Anweisungen dieser Anleitung: https://electronics.stackexchange.com/questions/57121/i2c-pullup-resistor-calculations

->(3.3 V-0,4)/3mA ~= 1kohm

Edit 4: Nachdem er durch meinen code-Zeilen habe ich versucht die Ausgabe der verschiedenen flag bit Register. Genau diese registriert: isr = I2C1->ISR;, cr1 = I2C1->CR1;, und cr2 = I2C1->CR2;

Die Flagge, ich bekomme nach der Einleitung der I2C übertragung Umgang mit I2C_TransferHandling(I2C1, 0x02, 1, I2C_AutoEnd_Mode, I2C_Generate_Start_Write); war 0x8001 die entziffert werden kann und die zwei Fehler:

#define I2C_ISR_BUSY ((uint32_t)0x00008000) /*!< Bus busy */

und

#define I2C_ISR_TXE ((uint32_t)0x00000001) /*!< Transmit data register empty */

Ich habe festgestellt, dass einige Problemumgehungen Arbeit unter diesem link hier (entfernen Sie die Leerzeichen nach https: gehen Sie zu dem link -> stack-überlauf wird nicht lassen Sie mich nach mehr als 1 link aus irgendeinem Grund): https: //my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FSTM32L151RB%20I2C%20Busy%20flag%20always%20set&FolderCTID=0x01200200770978C69A1141439FE559eb459d7580009c4e14902c3cde46a77f0ffd06506f5b&currentviews= 690, ich bin auf der Suche zu implementieren und werde berichten, sobald ich Sie ausprobieren.

Möglicherweise eine dumme Frage. Hast du pullups an SDA und SDL? Sind Sie hoch, bevor Sie diesen code ausführen?
Hey es DoxyLover, versucht und hat nicht funktioniert. Glaube nicht, dass Sie hoch angesetzt, bevor ich den code ausführt.
Was hast du genau angeschlossen, die I2C Leitungen? Was ist das slave-Gerät? Sind Sie sich bewusst, dass Sie, müssen pull-up-widerstände angeschlossen, die zwischen jeder I2C-Leitung und Vcc?
So jetzt habe ich nicht angeschlossen, alle anderen Geräte überhaupt; es ist einfach ein Meister mit einem separaten Zug für die jeweils von der SCL und SDA Leitung. Und ja, ich bin mir bewusst, dass ich irgendwann benötigen einen pullup für jedes Gerät habe ich es angeschlossen. Jetzt habe ich nicht einmal ein signal ausgehen (ich sollte in der Lage sein zu sehen, die raw-Daten ist mit meinem aktuellen code oder zumindest das start-signal).
Sie fehlt GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_Pin_9); GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_Pin_10);. Ich bin mir nicht sicher, ob es zählt, aber Sie müssen möglicherweise tun Sie es vor aufrufen GPIO_Init.

InformationsquelleAutor Stroodlemuffin | 2014-11-04

Schreibe einen Kommentar