I2C - základné použitie pre STM32

Z Kiwiki
Skočit na navigaci Skočit na vyhledávání

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

Aktivácia rozhrania I2C


V pravej časti sa zobrazia piny MCU, ktoré majú priradenú funkciu liniek SDA a SCL.

Konfigurácia I2C rozhrania

Parametre rozhrania I2C

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
  • HAL_I2C_Master_Transmit()
  • HAL_I2C_Master_Receive()
  • HAL_I2C_Slave_Transmit()
  • HAL_I2C_Slave_Receive()
  • HAL_I2C_Mem_Write()
  • HAL_I2C_Mem_Read()
  • HAL_I2C_IsDeviceReady()
  • HAL_I2C_Master_Transmit_IT()
  • HAL_I2C_Master_Receive_IT()
  • HAL_I2C_Slave_Transmit_IT()
  • HAL_I2C_Slave_Receive_IT()
  • HAL_I2C_Mem_Write_IT()
  • HAL_I2C_Mem_Read_IT()
  • HAL_I2C_Master_Seq_Transmit_IT()
  • HAL_I2C_Master_Seq_Receive_IT()
  • HAL_I2C_Slave_Seq_Transmit_IT()
  • HAL_I2C_Slave_Seq_Receive_IT()
  • HAL_I2C_EnableListen_IT()
  • HAL_I2C_DisableListen_IT()
  • HAL_I2C_Master_Abort_IT()
  • HAL_I2C_Master_Transmit_DMA()
  • HAL_I2C_Master_Receive_DMA()
  • HAL_I2C_Slave_Transmit_DMA()
  • HAL_I2C_Slave_Receive_DMA()
  • HAL_I2C_Mem_Write_DMA()
  • HAL_I2C_Mem_Read_DMA()
  • HAL_I2C_Master_Seq_Transmit_DMA()
  • HAL_I2C_Master_Seq_Receive_DMA()
  • HAL_I2C_Slave_Seq_Transmit_DMA()
  • HAL_I2C_Slave_Seq_Receive_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.


Zdroje a odkazy