Yep, probably the best tutorial on I2C on STM32 devices, and it removes some of the mystery of HAL functions that scare the bejesus out of most of us. Thanks, Matej.
I believe when using HAL functions MEM read and write (or maybe transmit/receive) there is no need to OR the LSB (the read/write bit). The function does this for you. I recently created a program using 3 I2C devices using Hal library and all of them worked without ORing the LSB (=1). Otherwise great video.
4 года назад
Great observation. Thank you for that. I found that when HAL read/write memory functions send device address by "OR-ing" address with 1 and for writing "AND-ing" a zero for LSB. Luckily due to the nature of operations, manually doing this before function call still works. I think it is still important to show it because HAL "hiding" this fact does not teach you of the operation. Funny how you still have to left shift the 7-bit address yourself; probably because some manufacturers list device adress already left shifted, as I showed in the video.
Matej Blagšič I never tried it but it’s interesting that it works with or without doing it. And yes it is ironic that you still have to shift the 7bit address. They really chose when to help you and when to make you work lol! Great effort. Keep up the good work.
4 года назад
Yeah, this is the funny part of "standards" as people tend to bend the definitions a bit just so you can curse at the screen. The reason why it still works if you manualy set device address LSB to 1 when reading is because OR will set 0 to 1 and leave 1 as 1, therefore HAL read function will do the OR on LSB that is already at 1, so no harm. When you init a write, LSB should be 0, but in case you forget and still write a 1 for the LSB, then HAL write will do: ... &= ~(0x01); Which takes 0x01 and flips it 0xfe and AND-it to device address, where AND keeps all address bits with 1 at 1 and forces LSB to 0 (hence 0xfe has only LSB on 0). I think you already know this but it might help someone else. Thanks for the comment.
Excellent demonstration of how to use I2C with HAL. Following your general procedure I was able to setup AS5048B 14-bit rotary position sensor from AMS. Which was much faster than doing it manually through register manipulation. Have you considered going over CMSIS for communication protocols, or using register manipulation? Your through style of explanation is appreciated, Thanks. Keep up the good work.
4 года назад
Thank you for your comment. I'm happy to hear you were able to apply knowledge to your project. I will do a series on LL drivers, which are similar to standard library for F-series from past. Standard or now the LL library is very bare bones and can be inspected and used for learning on how devices work on register level. I will explain those things, but working on register level for everything is not convenient and makes code harder to read and develop.
dont say for any device i have been working for months on nucleo f446re to read fron i2c eeprom using address 0x78 with HAL or LL tried arduino ide softwrie on all pins but 0x78 reserved for 10 bit addressing mode and RTC bkp register 10 can you help me
Hi how much is the time between interrupt(falling or rising edge) and function in normal case and how we can decrease this time ? (Doing the function immediately after interrupt without any delay)
Greetings! This is indeed one of the most helpful videos on the web regarding I2C, thank you Matej! However, is it possible to generate a repeated start with the HAL functions? It appears that a stop condition is generated after each function, which is inconvenient given that a lot of IC require a repeated start before sending the requested bytes back to the master. (It is visible in your datasheet as well) After hooking up a logic analyser to the scl and sda I saw that no matter which function was used, a stop condition was always generated. Your help would be of great use since I am doing my internship project and have been stuck on this problem for a while...
Год назад
Hey, thanks for the kind words. Yes, what you said in your first sentance makes sense. Every "packet" has a start and a stop. It starts with address and function and followed by bytes going either to master or to slave. The number of those is predetermined by the implementation datasheet. So if you want to read data from your sensors by polling or responding to a interrupt pin from the sensor, the master must once again start the communication with start, and then poll for the N amount of bytes from the sensor. If you read multiple registers, you must then send multiple read requests and packet transmissions. Do correct me if I'm misunderstanding your problem. Regards
Thank u for the best I2C video! I tried to do it like you in the video and I use the AT30TS750A temperature sensor. I set the A0, A1 and A2 to ground. So I get the 48 hex address and I shifted it. For the Config Address I got 0x00 like on page 18 in the data sheet (default). The rest I dis the same as you in the video. (Expect the conversion of the temperature). But if I debug the code I get at the first if-case the HAL_Error. Do you know what I did wrong? With the oscilloscope, I also get no signal on the bus while debugging. Thanks in advance!
Hello, first I really like this tutorial and it really helps me, it is probably the most complete and clear one I have seen on this subject on cube. However I watched the video many times but I don't understand the difference between Mem_Read/write or receive/transmit, can you try to write it down so I can figure it out ?
3 года назад
Thank you for kind words. The difference is in abstraction. Receive and Transmit are used the same as with SPI, they just transmit/receive a set amount of bytes to/from device. This is basic and by reading device datasheet you will see, that first byte should be R/W address of the device, second should be the register that you want to write/read to and third is one or a series of rx/tx bytes to or from that device register address. Because this happens often and its prone to errors (you have to toggle LSB in address to signal read/write, remember the sequence which is the same for all i2c devices), HAL is providing you functions (mem_read, mem_write), that do all of the above for you. You just plug in your device address (7bit left shifted, functions will toggle R/W bit for you), device memory address you wish to affect and data to read/write. It is very handy and it's a shame SPI library doesn't have it implemented; probaby becase some SPI devices require more than just CS toggle, like some displays have reset, data mode etc. Hope this clears it out :)
Do you know of any caveats if STM's HAL library has any I2c issues? For example, when to use hal_i2c_master_transmit () vs HAL_I2C_Mem_Read/Write()? I understand the former sends the register address first (start, address, stop), while the latter, send start bit, slave I2C address, slave internal mem address, repeat start, data, stop.. i.e no stop in the middle. I'm using stm32h7 and seeing issues with a temp sensor.. not sure if I should try a third-party/opensource driver (ex. adastra-soft).
Год назад
I haven't had issues with i2c interfaces so far, but it's also true that I haven't worked with i2c devices recently. You already pointed out the differences in the way it works which is correct. I'm looking into the implementation of both on f3xx library from sometime last year and I can see they are a bit different, not just one using the other. HAL_I2C_Master_Transmit does not check the inputs. Only if the I2C peripheral is available. It will only return an error if a timeout during the transmission is detected (or if the I2C is busy before starting). HAL_I2C_Mem_Write in addition to previous checks also checks the input data pointer and size. If pData equals NULL or Size equals to zero, it returns an error. If you have invalid arguments to the functions, let's say zero data, first one just returns OK (finished already), but I haven't tested this. The second one will return you error, providing that the check for free I2C peripheral is OK.
Great video. What about using interrupt to read I2C?
Год назад
Thank you. I haven't used interrupts for I2C as most stuff has just been configuration and reading parameters while waiting for response. I was however using rtc to trigger regular interrupts, where I was reading data from spi - again just polling. But I would figure this could work the same. You could configure sampling on some sensors, that have a "data ready" output pin with which you could trigger an interrupt and read from the sensor. The way I2C is used is that master initiates the communication and slave responds.
Hello, can you explain in other video this pointers, the use of them in functions
2 года назад
I belive there are plenty of videos on youtube explaining pointers in all levels of detail, so I don't think I need to make another. Then again, If I had one, I could point you or any future viewer to it. I'll keep it in mind!
const unit8_t max30205_config = 0x44; sir please tell me value 0x44 how come , i dont see this value in data sheet please reply if possible
2 года назад
The configuration register for MAX30205 is described on datasheet page 12/15, table 5. If you convert 0x44 to binary you get 01000100. This means, that bits 2 and 6 have value 1, others value 0. In this case bit 2 represents OS polariy, therefore it is high if needed along with external pull up resistor. More important is bit 6 which represents |TIMEOUT and if this bit is high, timeout is disabled.
How the 100 bits/s and 100 kHz can be thought as equal(2:50), can someone explain? I am a newbie :-)
3 года назад
I misspoke. It should be 100kbits/s, but not all of that is usefull information (ack, address byte, r/w bit etc). Since data lines have only two states, 1 clock signal transmits one symbol with 1bit of information per period, hence 100kbit/s for 100kHz clock :)
I agree. It works on a similar way as uart which is very simple and therefore reliable. Nowdays, SPI is still faster than i2c but uses more wires ... I still like it
Hi, I have stm32f411 and want to connect it with 24LC64 ... I am using arduino IDE. Ive written a program that has TFT, Rotary encoder, Analog...many things. I only have 48 hours to get some form of non volatile memory for the project. a 24LC64 i have used before with arduino nano...no problem... but now for the M4 processor.... eeeek! it seems not easy. i have just downloaded STM32CUBE MX.... however the learning curve is okay...BUT the output will give about 30 files!! for just EEPROM i2c. I dont hve keel or other IDE and no time to transfer my program. i simply need a header file to add to the arduino IDE to program the stmf411(Black pill module board). I only want to store about 6 BYTES! as 6 variables. I have the 3 address pins of the 24LC64 to ground, so the chip address is DEC 80 or HEX 50. and the DATA Pin to PB7 and the CLK pin to PB6. please HELP!! :o)
3 года назад
If you're using arduino ide, then you can just use wire library that works with appropriate i2c interface. You can write eeprom pages and read them by checking out the datasheet. That would be fast. You can also check id anyone has written arduino library for it. Then I don't understand why were you mentioning cubemx if your're using arduinoIde. If you IC or board is supported for arduino, then there should be no problem.
@ hi, thanks for the reply.... ive so far looked at 30 examples and its driving me nuts! i didnt know cube mx... had a look.... eeek! it looks like it will give me 30 files as an output for stm32f411 and i2c to drive an 24lc64 eeprom. its more for a full ide for c programming...rather than the simpler arduino. the main problem seems to be the stm32f411 has different pinout than the arduino. and opperates at a different speed. i havew found softWire.h library which seems to let me asign different pins ... but i still cant write to or read from the eeprom. any ideas? the 24lc64 is wired correctly. PB7 for data and PB6 for clk... all address lines to ground for HEX50 address of the chip.
3 года назад
So do you want to program your f411 with cube and create your project there or in arduino? That's what confused me. As far as pinout goes, there are different pinouts depending on microcontroller. Arduino has some defaults for i2c, spi and uart, but you might have seen that there are a couple pins that can do the same thing. In arduino you can choose which pins it uses, but in cube you can do anything. If you want to build the project in cube and cube only, so porting your project there, you will need a debugger for downloading code or if you're using usb on the board with update bootloader, that you can use ST's tool for that, where you just have to navigate to the .bin file inside your Project/Debug/ folder For i2c communication, you can use my video for reference.
@ hi... thanks for helping, i want to still do the project in arduino IDE. I have used softWire.h where you can define different default i2c pins as they are PB7 and PB6 on the stm32f411. however still not getting the 24lc64 to read or write. I wonder if it might be the defualt frequency as my chip is 100mhtz,
3 года назад
Ok. As far as I can see, softWire is software i2c library that only requires gpio pin and no dedicated i2c preipheral. Therefore it should work regardless of your microcontroller, as long as it's supported by arduino. Therefore you should check the settings for i2c and if it's running at 400kHz or less (as supported by the IC, where 100kHz is norm and should work with all i2c devices. I would prefer to use internal i2c peripheral of f411, so maybe you can find a way to use that with arduino Wire library.
very good thanks. I want to learn about working APDS9960 but i have not done it for now. Can you(aynbodies) help me for APDS9960 with stm32 cubemx or cubeide?
Год назад
I would suggest you read up on existing documentation from brodcom and some other libraries (adafruit comes to mind). Then it is just about reading the datasheet and implementing what you need above i2c.
Great tutorial! On STMf103c8t6, the scl clock is pulled low after the first transfer, and it will be stuck in HAL_BUSY error state forever.. this is very weird, have you ever seen such deadlock?
3 года назад
I haven't had a problem with i2c, but I did have similar ones with uart and timer interrupts ... it is a bug in hal that I went around by using underlying functions that hal calls. Hope this gives you an idea or two.
@ I've issued a reset when it said HAL_Busy and it started working. Also had to stabilize the voltage.
3 года назад
Chech that pull up resistors are between 2k and 10k and that you have some decoupling capacitors on each device. If it's just a hal bug then it's great you found a solution.
Matej, how have you solved read block, I wanted to implement that instead of specifying how many bytes should be read, that it should take Size send from the slave.. I need it for smbus.
Man can you please shate your dark theme settings file? I've waster hours in that forsaken preference window trying to color each element, but poor UI design and lack of proper information makes it very difficult. Unnapreciative fucks those developers of CubeIDE.