I2C - základné použitie pre STM32
Obsah
Rozhranie I2C obsahuje každý mikrokontrolér rodiny STM32. Zvyčajne sú k dispozícii minimálne 2 nezávislá rozhrania.
Základná konfigurácia rozhrania I2C
Po vytvorení projektu v STM32CubeMX alebo STM32IDE je potrebné si aktivovať rozranie: v časti "Pinout & Configuration" si v vyberieme rozhranie I2C. V konfiguračnej časti sa zobrazí voľba pre výber typu zbernice; vyberieme "I2C"
Aktivácia rozhrania I2C
V pravej časti sa zobrazia piny MCU, ktoré majú priradenú funkciu liniek SDA a SCL.
Konfigurácia I2C rozhrania
Nastavenie parametrov I2C rozhrania
Význam jednotlivých nastavení:
- Custom timing
- Dovoľuje nastaviť si vlastné parametre generovania časového signálu. Odporúča sa ponechať prednastavenú hodnotu Disabled. Default: Disabled
- I2C Speed Mode
- Voľba režimu časovania. V zozname sú len tie režimy, ktoré vybratý MCU podporuje.
- Standard Mode
- Fast Mode
- Fast Mode Plus
- I2C Speed Frequency
- hodnota taktovacej frekvencie pre vybraný režim. Táto hodnota sa automaticky nastaví na maximálnu povolenú hodnotu pre vybraný režim.
- Rise Time / Fall Time
- manuálna modifikácia parametrov pre CLK. Detaily o výpočte týchto časov sú tu.
- Analog Filter
- Ak sú na zbernici I2C nežiaduce rušenia signálu (pochádzajúce zo zlého návrhu dosky plošného spoje, aplikácie na riadenie motora, ...), môžete použiť digitálne a analógové filtre šumu, ktoré sú k dispozícii medzi logikou GPIO a registrami I2C. Analógový filter je implementovaný v súlade so špecifikáciou I2C, ktorá vyžaduje potlačenie špičiek so šírkou impulzu do 50 ns. Digitálny filter umožňuje potlačiť špičky s programovateľnou dĺžkou 1 až 15 periód I2CCLK. Podrobnosti o nízkoúrovňovom nastavení časovania je v dokumete AN4235[1]
Vlastnosti v režime slave zbernice I2C:
- Clock No Stretch Mode
- vypne možnosť pozdržania hodinového signálu. Default: Disabled
- Po rozpoznaní zodpovedajúcej adresy I2C s požiadavkou na čítanie MCU okamžite odošle obsah registra I2C_TXDR (dátový register I2C).
- Softvér na MCU musí zabezpečiť, aby vysielací register (I2C_TXDR) vždy obsahoval platné údaje.
- Subsystém I2C bude automaticky potvrdzovať všetky udalosti čítania a zápisu z nadradenej jednotky[2].
- General Call Address Detection
- V režime Slave je rozhranie schopné rozpoznať svoje vlastné adresy (7 alebo 10-bitové) a všeobecnú adresu volania. Rozpoznávanie adresy všeobecného volania je možné zapnúť alebo vypnúť touto voľbou.
- Primary Address Length Selection
- Dĺžka adresy usla slave. Default: 7bit
- Dual Address Acknowledgement
- Režim, kedy má uzol slave 2 adresy. Default: Disabled
- Primary Slave Address
- Adresa uzla slave (režim slave)
Nastavenie NVIC
- I2Cx event interrupt
- I2Cx error interrupt
Nastavenie DMA
Dovoľuje pridať 2 požiadavky na DMA prenos:
- I2Cx_RX - z periférie do pamäte
- I2Cx_TX - z pamäte do periférie
Práca s rozhraním I2C v programovom kóde
Základná kostra vygenerovaného programu v prostredí STM32CubeMX/STM32IDE:
1 #include "main.h"
2
3 /* Private variables ---------------------------------------------------------*/
4 I2C_HandleTypeDef hi2c1;
5
6 /* Private function prototypes -----------------------------------------------*/
7 void SystemClock_Config(void);
8 static void MX_GPIO_Init(void);
9 static void MX_I2C1_Init(void);
10
11 int main(void)
12 {
13 HAL_Init();
14 SystemClock_Config();
15
16 MX_GPIO_Init();
17 MX_I2C1_Init();
18
19 while (1)
20 {
21 }
22 }
23
24 static void MX_I2C1_Init(void)
25 {
26 hi2c1.Instance = I2C1;
27 hi2c1.Init.Timing = 0x00000E14;
28 hi2c1.Init.OwnAddress1 = 0;
29 hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
30 hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
31 hi2c1.Init.OwnAddress2 = 0;
32 hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
33 hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
34 hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
35 if (HAL_I2C_Init(&hi2c1) != HAL_OK)
36 {
37 Error_Handler();
38 }
39
40 /** Configure Analogue filter */
41 if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
42 {
43 Error_Handler();
44 }
45
46 /** Configure Digital filter */
47 if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK)
48 {
49 Error_Handler();
50 }
51 }
Vygenerovaná funkcia `MX_I2C1_Init()` sa stará o správne nastavenie parametrov podľa grafického konfigurátora v predchádzajúcom kroku. Po zbernici I2C môžeme komunikovať až po úspešnom ukončení funkcie `MX_I2C1_Init()`.
Funkcie pre I2C komunikáciu
Existujú dva spôsoby prenosu:
- Režim blokovania
- Komunikácia prebieha v režime dotazovania. Stav spracovania všetkých údajov sa vracia tou istou funkciou po ukončení prenosu.
- Režim bez blokovania
- Komunikácia sa vykonáva pomocou prerušenia alebo DMA. Tieto funkcie vracajú stav spustenia prenosu. Ukončenie spracovania údajov bude indikované prostredníctvom vyhradeného IRQ I2C pri použití režimu prerušenia alebo IRQ DMA pri použití režimu DMA.
Funkcie v blokujúcom režime | Funkcie v neblokujúcom režime s prerušením | Funkcie v neblokujúcom režime s DMA |
---|---|---|
|
|
|
Zoznam funkcií spätného volania pre neblokujúce režimy:
- HAL_I2C_MasterTxCpltCallback()
- HAL_I2C_MasterRxCpltCallback()
- HAL_I2C_SlaveTxCpltCallback()
- HAL_I2C_SlaveRxCpltCallback()
- HAL_I2C_MemTxCpltCallback()
- HAL_I2C_MemRxCpltCallback()
- HAL_I2C_AddrCallback()
- HAL_I2C_ListenCpltCallback()
- HAL_I2C_ErrorCallback()
- HAL_I2C_AbortCpltCallback()
HAL_I2C_Master_Transmit
V režime Master odošle údaje pData v blokujúcom režime
HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
- hi2c - Pointer na štruktúru I2C_HandleTypeDef - nakonfigurované rozhranie I2C
- DevAddress - adresa cieľového zariadenia slave. 7 bitová adresa slave zariadenia uvedená v datasheete musí byť posunutá o 1 bit vľavo.
- pData - Pointer na odosielané dáta
- Size - počet bajtov, ktoré sa budú odosielať.
- Timeout - časový limit pre odoslanie. Uvádza sa v milisekundách. Po uplynutí tohto času sa odosielanie ukončí a funkcia vráti chybový kód.
HAL_I2C_Master_Receive
V režime Master prijme požadovaný počet bajtov v blokujúcom režime
HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
- hi2c - Pointer na štruktúru I2C_HandleTypeDef - nakonfigurované rozhranie I2C
- DevAddress - adresa cieľového zariadenia slave. 7 bitová adresa slave zariadenia uvedená v datasheete musí byť posunutá o 1 bit vľavo.
- pData - Pointer na buffer, kde budú prijaté dáta uložené
- Size - počet bajtov, ktoré sa budú prijímať.
- Timeout - časový limit pre príjem. Uvádza sa v milisekundách. Po uplynutí tohto času sa príjem ukončí a funkcia vráti chybový kód.
HAL_I2C_Master_Transmit_IT / HAL_I2C_Master_Transmit_DMA
V režime Master odošle údaje pData v neblokujúcom režime s prerušením / s DMA
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
Význam parametrov je rovnaký ako v prípade HAL_I2C_Master_Transmit. Chýba parameter Timeout. Po ukončení odosielania sa spustí ISR I2C1_EV_IRQHandler (definovaný v súbore stm32NNxxx_it). Ten zabezpečí zavolanie funkcie spätného volania:
void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
// tento kod sa vykona po ukonceni odoslania cez I2C
}
Túto funkciu je potrebné si implemetovať v kóde aplikácie. Jej definícia sa nachádza v súbore stm32NNXXxx_hal_i2c.c
HAL_I2C_Master_Receive_IT / HAL_I2C_Master_Receive_DMA
V režime Master prijme údaje v neblokujúcom režime s prerušením / s DMA
HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)
Význam parametrov je rovnaký ako v prípade HAL_I2C_Master_Receive. Chýba parameter Timeout. Po ukončení odosielania sa spustí ISR I2C1_EV_IRQHandler (definovaný v súbore stm32NNxxx_it). Ten zabezpečí zavolanie funkcie spätného volania:
void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c)
{
// tento kod sa vykona po ukonceni odoslania cez I2C
}
Túto funkciu je potrebné si implemetovať v kóde aplikácie. Jej definícia sa nachádza v súbore stm32NNXXxx_hal_i2c.c
HAL_I2C_Mem_Write / HAL_I2C_Mem_Write
V režime Master zapíše údaje pData na požadovanú adresu v uzle slave. Komunikácia je v blokujúcom režime.
HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
- hi2c - Pointer na štruktúru I2C_HandleTypeDef - nakonfigurované rozhranie I2C
- DevAddress - adresa cieľového zariadenia slave. 7 bitová adresa slave zariadenia uvedená v datasheete musí byť posunutá o 1 bit vľavo.
- MemAddress - adresa v pamäti komunikujúcej stranu - uzla slave
- MemAddSize - počet bajtov, ktoré sa majú zapísať/prečítať.
- pData - Pointer na odosielané/prijímané dáta
- Size - počet bajtov, ktoré sa budú odosielať/prijímať.
- Timeout - časový limit pre odoslanie. Uvádza sa v milisekundách. Po uplynutí tohto času sa odosielanie ukončí a funkcia vráti chybový kód.