14-I2C_LoLevel-Library (STM32F429)

diese Library dient zum benutzen der I2C-Schnittstelle im Master-Mode

die I2C-Pins die benutzt werden sollen, müssen im C-File eingetragen werden
(im H-File kann die I2C-Clock-Frq eingestellt werden)

auf der Hardware dürfen die zwei externen Pull-Up Widerstände (je 4k7) an SCL und SDA nicht vergessen werden, sonst funktioniert das ganze nicht.

die Library kann als LoLevel-Funktion die Schnittstelle initialisieren und Daten zu einem Slave senden und von einem Slave empfangen.

es gibt Funktionen um ein einzelnes Datenbyte zu senden/empfangen und Funktionen um mehrere Bytes zu senden/empfangen. In dem Fall müßen die Daten vor dem senden in einem Array stehen bzw. stehen nach dem empfangen in einem Array.

Die Funktion “UB_I2C1_WriteCMD” sendet nur ein einzelnes Byte an den Slave.

es gibt auch noch eine “Pausenfunktion” was einfach nur ein Zähler auf 0 ist um z.B. für langsame I2C-Devives eine Wartefunktion einfügen zu können.

es gibt 3 identische Librarys, getrennt für I2C1, I2C2 und I2C3

im Beispiel wurde I2C3 benutzt mit dieser Pinbelegung :

1
2
SCL an PA8
SDA an PC9

Funktionen (für I2C1) :

1
2
3
4
5
6
7
8
9
void UB_I2C1_Init(void);                                                     // zum initialisieren der I2C-Schnittstelle
int16_t UB_I2C1_ReadByte(uint8_t slave_adr, uint8_t adr);                    // um ein Byte zu lesen
int16_t UB_I2C1_WriteByte(uint8_t slave_adr, uint8_t adr, uint8_t wert);     // zum ein Byte zu schreiben
int16_t UB_I2C1_ReadMultiByte(uint8_t slave_adr, uint8_t adr, uint8_t cnt);  // um mehrere Bytes zu lesen
int16_t UB_I2C1_WriteMultiByte(uint8_t slave_adr, uint8_t adr, uint8_t cnt); // um mehrere Bytes zu schreiben
int16_t UB_I2C1_WriteCMD(uint8_t slave_adr, uint8_t cmd);                    // ein einzelnes Byte senden
int16_t UB_I2C1_ReadByte16(uint8_t slave_adr, uint16_t adr);                 // 16bit adresse auslesen
int16_t UB_I2C1_WriteByte16(uint8_t slave_adr, uint16_t adr, uint8_t wert);  // 16bit adresse beschreiben
void UB_I2C1_Delay(volatile uint32_t nCount);                                // Pausenfunktion

Beispiel :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//--------------------------------------------------------------
// File     : main.c
// Datum    : 03.11.2013
// Version  : 1.0
// Autor    : UB
// EMail    : mc-4u(@)t-online.de
// Web      : www.mikrocontroller-4u.de
// CPU      : STM32F429
// IDE      : CooCox CoIDE 1.7.4
// GCC      : 4.7 2012q4
// Module   : CMSIS_BOOT, M4_CMSIS_CORE
// Funktion : Demo der I2C-LoLevel-Library
// Hinweis  : Diese zwei Files muessen auf 8MHz stehen
//              "cmsis_boot/stm32f4xx.h"
//              "cmsis_boot/system_stm32f4xx.c"
// In Configuration diese Define hinzufügen :
// "STM32F429_439xx" , "__ASSEMBLY__" , "USE_STDPERIPH_DRIVER"
//--------------------------------------------------------------
 
#include "main.h"
#include "stm32_ub_i2c3.h"
 
int main(void)
{
  int16_t wert;
 
  SystemInit(); // Quarz Einstellungen aktivieren
 
  // Init der I2C1-Schnittstelle
  UB_I2C3_Init();
 
  // ein Byte vom I2C-Slave mit Adr 0xA0
  // aus Register-Adr 0x01 auslesen
  wert=UB_I2C3_ReadByte(0xA0,0x01);
  if(wert<0) {
    // Fehler
  }
 
  // den Wert 0x12 zum I2C-Slave mit Adr 0xC0
  // in Register-Adr 0x02 speichern
  wert=UB_I2C3_WriteByte(0xC0,0x02,0x12);
  if(wert<0) {
    // Fehler
  }
 
  UB_I2C3_Delay(400); // kleine Pause nach dem schreiben
 
  while(1)
  {
 
  }
}

Hier die Library zum Download :

i2c_master_f429_v103

Hier der komplette CooCox-Projektordner zum Download :

Demo_F429_14


19 Antworten auf 14-I2C_LoLevel-Library (STM32F429)

  1. kostas sagt:

    Sir, im having problem using the I2C1 on stm32f429
    Not just with your library but with ST too.
    I dont know what mistake im doing but i think i get no data from I2C.
    Im using a lux sensor BH1750, its working ok using arduino.
    I uploaded the source file here
    https://github.com/papadkostas/STM32F429/blob/master/main.c
    The arduino code looks like this
    uint16_t level;
    Wire.beginTransmission(0×23);
    Wire.requestFrom(0×23, 2);
    level = Wire.read();
    level <<= 8;
    level |= Wire.read();
    Wire.endTransmission();
    Also im using the pull up 4K7 resistors for both SDA/SCL.
    Im thinking the communication never occurs because after debuging the code found that @UB_I2C3_WriteByte.c Line 200 stays there until timeout occurs.
    Thought you might see what im doing wrong here
    Thanks in advance.
    Kostas.

    • admin_ub sagt:

      oh thats easy, my SlaveAdress is a 8bit Adress and the Arduino one is 7bit. So just shift 0×23 one bit to the left and you have the right adress 0×46 for my code (and for the st too)

  2. kostas sagt:

    Oh!! i didnt knew this information, you’re right!!
    Still on the screen i get the failed message.
    Scope needed here :/

    • kostas sagt:

      I think using screen and touch sensor blocking the pins for i2c operation.
      Right?
      I have uploaded the whole project here
      https://github.com/papadkostas/BH1750_UB

      • admin_ub sagt:

        i2c is a multi slave bus. So you can use both devices at the same time (touch and BH1750). The pull Up resistors for I2C3 are already on the disco board, so don’t connect external pull ups for this channel. Use a scope to check the signals PA8 = Clock, PC9 = DATA. And keep the wires as short as possible. Perhaps you need a delay after “UB_I2C3_WriteByte(0×23<<1,0×00,0×10);” and whats the return code of this function ?

        • kostas sagt:

          Well, it returns -2 not matter what im doing
          even with or without the sensor connected to the bus.
          Cables are about 10cm, is the same i’ve used with arduino.
          I updated the code to print init errors too.
          Its really a big mystery on whats going on here.
          I think its something wrong with the address on slave.
          UB_I2C3_WriteByte(0×23<<1,0×00,0×10);
          With arduino im not sending any address.
          First i only request transmision to slave, and then sending the data for register.
          Am i thinking wrong?
          Thanks for your time!!

          • Joerg B. sagt:

            Hello Kostas,
            Did You use a stm32f4 discoveryboard?

            Did You use the breakout board for Your BH1750?

            Be sure there are only ONE Pull Up on SCL and SDA Line. Refer Schematics of all Boards You use.

            Use the Adress acording the ADD Pin of the bh1750. Refer Datasheet.

            Have a look to the Arduino Code and than be sure Your code does the same as arduino code.

            Good luck !

            Joerg

          • Joerg B. sagt:

            Ok You use the board so You have to remove the Pull Ups on Your breakout Board.

        • Joerg B. sagt:

          Why did u shift 1 left the adress???

          “statusinit = UB_I2C3_WriteByte(0×23<<1,0×00,0×10);“

          • kostas sagt:

            Admin said that this i2c interface
            using 8 bit addressing
            and the arduino i2c interface
            use 7bit i2c addressing.
            So i had to shift it 1bit to left.
            The LSB is R/W operation?
            Yes i removed the external pull up resistors
            http://www.dfrobot.com/image/data/SEN0097/BH1750FVI.pdf
            If you see here, page 7 example 1.
            To start continuously measurement
            you have to do the following:
            1)Issue START condition
            2)Send slave address with write operation bit
            3)Wait to Receive ACK
            4)Send 1 Byte
            5)Wait to Receive ACK
            6)Issue STOP condition
            I think what the code do is this:
            1)Issue START condition
            2)Send slave address with write option bit
            5)Wait to Receive ACK
            5)Send 1 Byte(0×00)
            6)Wait to Receive ACK
            7)Send 1 Byte(0×10)
            8)Wait to Receive ACK
            9)Issue STOP condition

  3. kostas sagt:

    Now im getting -5 return from statusinit = UB_I2C3_WriteByte(0×23<<1,0×00,0×10);
    Im searching now what it means.
    Looks like its getting closer.

    • Joerg B. sagt:

      • kostas sagt:

        here is what scope showed to me today
        http://oi62.tinypic.com/xo1wjo.jpg
        i think that is something wrong on the code
        because address is transmitted ack too and 2 bytes come from slave

        • admin_ub sagt:

          no thats not what you see.
          You see the Slave Adress 0×46
          then the Register-Adress 0×00
          then the value 0×10
          you have a bad result because your sensor “BH1750″ dont want a register Adress and so you don’t have to send this adress
          you must change my code and delete the part (in read and write) who send the register adress

          1
          2
          3
          4
          5
          6
          7
          
            // Adresse senden
            I2C_SendData(I2C3, adr);
           
            timeout=I2C3_TIMEOUT;
            while (!I2C_GetFlagStatus(I2C3, I2C_FLAG_TXE)) {
              if(timeout!=0) timeout--; else return(P_I2C3_timeout(-4));
            }

          delete these 6 lines in both functions and it should work.

          • kostas sagt:

            Yeah thats what i said code is doing here
            5)Send 1 Byte(0×00)
            6)Wait to Receive ACK
            Those two were useless.
            Anyway , im going to try it.
            Thank you for the guidance finding out whats wrong :D !
            I’ll report back if everything is fine.
            Have a good day!

          • kostas sagt:

            Everything is fine now, you were right!!
            I changed the function, added a flag to tell if i want to send the data to a specific address on the slave or not because its usefull sometimes.
            Thank you once again!

  4. Joerg B. sagt:

    Hey Kostas,
    please share Your running code. I have ordered some of the chips from china ;)

    Joerg

    • kostas sagt:

      Sure, its here https://github.com/papadkostas/BH1750_UB
      Download as zip and go :D

      • Joerg B sagt:

        Thanks, but I have tom wait for the Chinese post :/


Wie hat Dir dieser Artikel gefallen?

1 Stern2 Sterne3 Sterne4 Sterne5 Sterne (Noch keine Bewertungen)
Loading...

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert