Forum: Mikrocontroller und Digitale Elektronik STM32F103RB I2C HAL Probleme initialisierung


von Kai G. (dr_evil)


Lesenswert?

Hallo zusammen,

wie schon vor einiger Zeit mal angesprochen möchte ich im Endziel einen 
Infineon TLV493 3 D Sensor via i2C ansteuern.

Ich versuche jetzt gerade meine I2C Schnittstelle so zu konfigurieren, 
dass irgendwas auf dem Bus passiert.

Ich nutze Eclipse und Arbeite mit HAL

Die Verbindung zum Board steht und die Übertragung dorthin klappt.

Ich habe folgenden Code:


void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{

     GPIO_InitTypeDef GPIO_InitStruct;

     //Enable the GPIO-clock
     __HAL_RCC_GPIOB_CLK_ENABLE() ;

       /* Peripheral clock enable */
     __HAL_RCC_I2C1_CLK_ENABLE();

                 GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
                 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
                 GPIO_InitStruct.Pull = GPIO_PULLUP;
                 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
           //      GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
                 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

.
.
.

Ich hab das ganze mit dem Oszi gemessen und meine Clock gibt (mit 
angeschlossenem Sensor) für 0,2 Sek. einen unveränderlichen Takt raus 
gleich zu beginn.


danach sind sowohl SCL und SDA auf Low... (Pull upps sind drin)

kann mir jemand helfen, und sieht, was ich ggf. vergessen habe zu 
initialisieren?

Danke

von pegel (Gast)


Lesenswert?

N'Abend

Irgend etwas passiert ja schon.
Jetzt musst du auch Daten senden, so das der Sensor etwas tun kann.
Hast du ein Speicheroszi?

von Kai G. (dr_evil)


Lesenswert?

Ich habe in der main ein kurzes programm was eine Adresse an den Sensor 
senden soll.

Aber es passiert nichts.

Habe einen logic analyser

: Bearbeitet durch User
von pegel (Gast)


Lesenswert?

Hast du im User Manual nachgesehen was der Sensor auf den Leitungen 
erwartet?

von Kai G. (dr_evil)


Lesenswert?

Ja habe ich.
Habe den programmcode auf einem anderen stm board ausprobiert mit einem 
anderen controller und dort sendet das board auch etwas. Mit dem f103rb 
allerdings nicht.
Ich musste rcc befehle für die clock löschen, da diese hier nicht 
verfügbar sind.
Hier wird garnicht erst etwas gesendet, geschweige denn die Clock 
aktiviert so wie sie soll. Ich vermute den fehler bei der 
initialisierung der Clock.

von pegel (Gast)


Lesenswert?

Oh, wenn er am anderen Board funktioniert, bleibt eigentlich nur das 
Timing zu prüfen.
Da bin ich jetzt aber überfragt. :(

von Kai G. (dr_evil)


Lesenswert?

Also der sendor hat nicht funktioniert. Er hat nicht geantwortet.
Aber mein nucleoboard hat wenigstens was über den Bus geschickt.
Das tut dieses jetzige mit dem f103rb aber nicht. Unabhängig vom Sensor

von pegel (Gast)


Lesenswert?

Hast du in deinem Code irgendwo ein

__HAL_RCC_AFIO_CLK_ENABLE();

und

__HAL_AFIO_REMAP_I2C1_ENABLE();

von pegel (Gast)


Lesenswert?

Zum Test kannst du auch erst mal das originale I2C1 an PB6 und PB7 
versuchen.

von Kai G. (dr_evil)


Lesenswert?

Also um hier weiter zu kommen..
soweit ich das auf dem Layout erkennen kann, ist der PIN B7 garnicht 
nach außen geführt. auf dem Nucleoboard ist dafür PB8&9 vorgesehen.

und die beiden Zeilen
__HAL_RCC_AFIO_CLK_ENABLE();

und

__HAL_AFIO_REMAP_I2C1_ENABLE();

habe ich in dem code nicht. ich Poste hier nochmal den kompletten code:

#include "stm32f1xx.h"
#include "stm32f1xx_nucleo.h"
#include <string.h>
#include <stm32f1xx_hal.h>



#define SENSOR_ADDR               0xBC

/*
 * Überschreibe _weak MspInit um die GPIO's zu konfigurieren
 */
void HAL_I2C_MspInit(I2C_HandleTypeDef* hi2c)
{

     GPIO_InitTypeDef GPIO_InitStruct;

     //Enable the GPIO-clock
     __HAL_RCC_GPIOB_CLK_ENABLE() ;

       /* Peripheral clock enable */
     __HAL_RCC_I2C1_CLK_ENABLE();

                 GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9;
                 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
                 GPIO_InitStruct.Pull = GPIO_PULLUP;
                 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
           //      GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
                 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void i2c_init(I2C_HandleTypeDef* hi2c)
{
                hi2c->Instance = I2C1;
                hi2c->Init.ClockSpeed = 500000;
                hi2c->Init.OwnAddress1 = 0xA1;
                hi2c->Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
                hi2c->Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
                hi2c->Init.OwnAddress2 = 0xA1;
                hi2c->Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
                hi2c->Init.NoStretchMode = I2C_NOSTRETCH_ENABLE;
                hi2c->State = HAL_I2C_STATE_RESET;
                if (HAL_I2C_Init(hi2c) != HAL_OK) {
                               //If not HAL_OK then activate LED3
                               BSP_LED_On(LED2);
                }
}


int main(void)
{
                I2C_HandleTypeDef i2c;
                uint8_t arr[5];

                memcpy(arr, "ABCDE", 5);

                HAL_Init();


                BSP_LED_Init(LED2);


                //Init I2C Bus using HAL functions
                i2c_init(&i2c);


                for(;;)
                {
                          if (HAL_I2C_Master_Transmit(&i2c, SENSOR_ADDR, 
arr, 5, 1 ) == HAL_TIMEOUT) {
                                              //If not HAL_OK then 
activate LED3
                                               BSP_LED_On(LED2);
                               }

                               HAL_Delay(1000);
                               BSP_LED_Off(LED2);
                               HAL_Delay(1000);
                }
}


Vielleicht hilft dies weiter.

von pegel (Gast)


Lesenswert?

Kai G. schrieb:
> habe ich in dem code nicht

Dann setz die doch mal ein.

__HAL_RCC_AFIO_CLK_ENABLE();
schaltet AFIO ein

__HAL_AFIO_REMAP_I2C1_ENABLE();
Remap von PB6/7 auf PB8/9

von pegel (Gast)


Lesenswert?

OwnAddress ist übrigens nur interessant, wenn der STM32 den Slave 
spielt.

von Kai G. (dr_evil)


Lesenswert?

Hey super.:)
Der Bus tut etwas. Der Sensor noch nicht so wie er soll, aber es 
passiert etwas.

Vielen Dank bis dahin

von nico_2010 (Gast)


Lesenswert?

Hi,
Your premises are wrong. The sensor address is 0x5E not 0xBC.
I2C HAL use this function:

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, 
uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

to send something on bus.
But DevAddress is only 7 bits wide, so to make room for R/W bit you must 
write in the above command as follows:

if (HAL_I2C_Master_Transmit (& i2c, SENSOR_ADDR<<1,
arr, 5, 1) == HAL_TIMEOUT)

and everything will be fine.

von Andre (Gast)


Lesenswert?

Hey Nico

Kai is passing sensor address 0xBC to transmit function without 
shifting.

If you use 7 bit address notation of 0x5e and pass it to transmit 
function shiftet by 1 (multiplied by two), it will result in the same 
(0xBC). Or do I get something wrong here?

BR

von Cristi P. (nico_2010)


Lesenswert?

Andre schrieb:
> Hey Nico
>
> Kai is passing sensor address 0xBC to transmit function without
> shifting.
>
> If you use 7 bit address notation of 0x5e and pass it to transmit
> function shiftet by 1 (multiplied by two), it will result in the same
> (0xBC). Or do I get something wrong here?
>
> BR

Hello,
yes, you miss something: HAL libs do not i2c_address << 1. You have to 
do this as I mentioned above.
Beat regards

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.