STM32 Tutorial 04 - I2C Module (Pca9685) Using HAL (And FreeRTOS)
STM32 Tutorial 04 - I2C Module (Pca9685) Using HAL (And FreeRTOS)
You can use the STM32CubeMX tool to create the necessary config. files to enable the I2C-Drivers.
The HAL library provides the necessary functions to communicate to with the I2C protocol.
I’m going to show you how to output I2C with the HAL library using a PCA-9685 16-channel 12-Bit LED
driver.
STM32CubeMX
Generating the config. files from STM32CubeMX.
Nothing special here. Just note, that you have the option to change the addressing mode to
I2C_ADDRESSING_MODE_10BIT.
I2C Basics
Note ! This info is essential when working with I2C protocol. Possible
sources of error are marked with red blocks.
The I2C always needs to be terminated with a pull-up resistor on each SDA and SCL. Typical values can
range from 4k7 to 22k.
error Bus not terminated. This is the case, when SDA and SCL are in a low
state (GND) instead of pulled high.
The bus is activated with a start condition. (SCL pulled low after SDA was pulled low)
Followed by the slave address.
Slave address:
- Bits 7 – 4 are a unique address, each family of chips has a unique combination
- Bits 3 – 1 determines the id of a chip. They are usually set with pull-up / pull-down resistors
- Bit 0 determines if a read or a write access is being performed on the slave
error The slave does not ACK the reception. This case occurs, if the
address was incorrect. Check your datasheets to find the correct
address.
The end of transmission is then marked with the stop condition. (SDA is pulled high after SCL was
pulled high)
Note ! If more than one byte of data is being outputted, and the slave does
not acknowledge the first byte, the timeout comes in handy.
It prevents the function from unsuccessfully waiting for an
acknowledgement (infinite loop).
To send multiple bytes of data, you can create an array as a buffer and give it to the HAL function.
Also change the size argument to the number of bytes you want to read.
1 void pca9685_pwm(I2C_HandleTypeDef *hi2c, uint8_t address, uint8_t num, uint16_t on, uint16_t off)
2 {
3
4 uint8_t outputBuffer[5] = {0x06 + 4*num, on, (on >> 8), off, (off >> 8)};
5 HAL_I2C_Master_Transmit(&hi2c1, address, outputBuffer, 5, 1);
6
7 }
8
Note:
You might also want to look at the following functions when working with I2C peripherals.
HAL_I2C_Mem_Read()
HAL_I2C_Mem_Write()
They provide a cleaner and more direct way to access the registers on a peripheral chip.
This tutorial is very basic and might not show the best way to use the STM32 environment.
It still might help you get into the whole HAL philosophy of STM if you are coming from another
platform. This document is free of copyright under the Creative Commons Zero attribution.
Simon Burkhardt
electronical engineering
simonmartin.ch
History:
V1.0 tested the code, created this document
V1.0.1 added contact info and cc0 notice