hal library i2c sorunu

Başlatan esdevhk, 21 Haziran 2018, 10:13:03

esdevhk

iyi günler arkadaşlar,

i2c hal lib içerisine baktığımda 4 adet fonksiyon gözüme çarptı.

*HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

*HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

*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_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)


Sizlere sorum şu arkadaşlar:
*bu 4 fonksiyon birbirine göre farklilikları nelerdir?

Örneğin şuan L3GD20H'dan gyro verisi okumaya çalışıyorum.

TxBuffer[0] = 0x20;
 TxBuffer[1] = 0x0F;
 HAL_I2C_Master_Transmit(&hi2c1,gyro_Adrr,TxBuffer,2,10);

/* Burada amacım CTRL1(20h) register bitlerini 0x0F olarak adreslemek. Bunu sağlıyor mu bu kod parçacığı? */

  uint8_t gyro_Adrr=0x6B; (Data sheetden okuduğum 7bit slave adress. 8.biti fonk kendi koyuyor diye okudum.)
  // X_OUT_L = 0x28
  // X_OUT_H = 0x29
	TxBuffer[2] = 0x28; 
	HAL_I2C_Master_Transmit(&hi2c1,gyro_Adrr,&TxBuffer[2],1,10);
	HAL_Delay(1);
        RxBuffer[2] = 0x28; /* Bu satıra gerek var mı? */ 
	HAL_I2C_Master_Receive(&hi2c1,gyro_Adrr,&RxBuffer[0],1,10);

	TxBuffer[3] = 0x29;
	HAL_I2C_Master_Transmit(&hi2c1,gyro_Adrr,&TxBuffer[3],1,10);
	HAL_Delay(1);
	RxBuffer[1] = 0x29; /* Bu satıra gerek var mı? */ 
	HAL_I2C_Master_Receive(&hi2c1,gyro_Adrr,&RxBuffer[1],1,10);

/* Buradaki amacım da X_OUT_L ve X_OUT_H registerlarından veri çekmek. Doğru veriyi yukarıdaki kodlarla çekebilmem mümkün mü?*/

Yukarıdaki kod parçacıklarında yaptığım işlemlerde bir yanlışlık varsa nelerdir? I2C protokolünün mantığını az çok oturttum fakat HAL_I2C_Master_Transmit() ve HAL_I2C_Master_Receive() fonk tam olarak işlevini oturtmuş değilim bunu daha iyi açıklar mısınız? Ayrıca bu iki fonk'nun Mem_Write() ve Mem_Read() fonk'larından farkı nedir? Artısı eksisi nedir? Yukarıdaki kodlarım yanlış ise doğrusunu açıklarsanız çok mutlu olurum.

Teşekkürler

e-zeki

HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Bu iki foksiyon 2 I2C aygıt arasında "DevAddress"adresinde bulunan aygıttan veri alır veya gönderir.

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_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

bu iki fonksiyonsa "DevAddress" adresinde bulunan aygıtın "MemAddress" memory adresine istenilen datayı yazar veya o adresteki datayı okur.
L3GD20H register değerlerini setlemek ya da okumak için alttaki iki fonksiyonu kullanmanız gerek.


esdevhk

Alıntı yapılan: e-zeki - 27 Haziran 2018, 11:04:54
HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)
Bu iki foksiyon 2 I2C aygıt arasında "DevAddress"adresinde bulunan aygıttan veri alır veya gönderir.

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_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

bu iki fonksiyonsa "DevAddress" adresinde bulunan aygıtın "MemAddress" memory adresine istenilen datayı yazar veya o adresteki datayı okur.
L3GD20H register değerlerini setlemek ya da okumak için alttaki iki fonksiyonu kullanmanız gerek.



Yani hocam şunu diyebilir miyiz, eğer ki kullandığım sensörün birden fazla registeri varsa Mem_Read and Mem_Write fonklarını kullanmam gerekir. Fakat direkt registerı olmadan sensörden data okuyacaksam Transmit ve Receive fonkları.

MC_Skywalker

Sensör ile haberleşirken;
//
HAL_I2C_Master_Transmit(&hi2c1,0x40<<1,buffer,1,100);
HAL_I2C_Master_Receive(&hi2c1,0x40<<1,buffer,2,100);


LCD ile haberleşirken;
// I2C address 
#define SSD1306_I2C_ADDR        0x78
static void ssd1306_WriteCommand(uint8_t command)
{
	HAL_I2C_Mem_Write(&hi2c1,SSD1306_I2C_ADDR,0x00,1,&command,1,10);
}

kullanıyorum.

esdevhk

Alıntı yapılan: MC_Skywalker - 27 Haziran 2018, 16:47:30Sensör ile haberleşirken;
//
HAL_I2C_Master_Transmit(&hi2c1,0x40<<1,buffer,1,100);
HAL_I2C_Master_Receive(&hi2c1,0x40<<1,buffer,2,100);


LCD ile haberleşirken;
// I2C address 
#define SSD1306_I2C_ADDR        0x78
static void ssd1306_WriteCommand(uint8_t command)
{
	HAL_I2C_Mem_Write(&hi2c1,SSD1306_I2C_ADDR,0x00,1,&command,1,10);
}

kullanıyorum.


Hocam doğrudur fakat farkı şu sanırsam araştırmalarım sonucu şunu anladım. Örneğin Mem_Write fonknun aldığı parametreler DevAdress,MemAdress,*pData yani bir sensörün ilgili register ına yazmak istediğim değeri Mem _Write ile yazabiliyoruz. Fakat transmit ve receive fonk da ise ilgili register ve register a gönderilmek istenen değeri HAL_UART_Transmit(&hi2c,DevAdress,*pData,2) olarak 2 paket halinde gönderiyoruz sanırsam. Aynı işi farklı yollardan görüyor herhalde. Ama Mem_Write ve Mem_Read daha kullanışlı geldi bana.

e-zeki

Alıntı yapılan: huseyink - 27 Haziran 2018, 16:30:02Yani hocam şunu diyebilir miyiz, eğer ki kullandığım sensörün birden fazla registeri varsa Mem_Read and Mem_Write fonklarını kullanmam gerekir. Fakat direkt registerı olmadan sensörden data okuyacaksam Transmit ve Receive fonkları.

Hayır. herhangi bir sensörün zaten her zaman birçok register'ı olacaktır. Bu iki fonksiyon arasında neredeyse hiç fark yok ikisini de kullanabilirsin. stm32fxxxhal_i2c.c dosyasını açarsan bu fonksiyonlar ve interrupt fonksiyonlarının açıklamalarını görebilirsin. 2 fonksiyonu karşılaştırırsan aralarında neredeyse hiç fark olmadığını görebilirsin. Sanıyorum Mem_W/R versiyonları direkt memory access'e sahip oldukları için biraz daha öncelikli fonksiyonlar. Ben hep Mem versiyonlarını kullandım bugüne kadar.

Alıntı YapHocam doğrudur fakat farkı şu sanırsam araştırmalarım sonucu şunu anladım. Örneğin Mem_Write fonknun aldığı parametreler DevAdress,MemAdress,*pData yani bir sensörün ilgili register ına yazmak istediğim değeri Mem _Write ile yazabiliyoruz. Fakat transmit ve receive fonk da ise ilgili register ve register a gönderilmek istenen değeri HAL_UART_Transmit(&hi2c,DevAdress,*pData,2) olarak 2 paket halinde gönderiyoruz sanırsam. Aynı işi farklı yollardan görüyor herhalde. Ama Mem_Write ve Mem_Read daha kullanışlı geldi bana.

Evet öyle sayılır fakat Mem foknsiyonlarında da Size parametresi olduğu için istediğin uzunlukta datayı registerlara yazabilirsin. size 1 den farklı olursa MemAdress den başlar ve 1 arttırarak o adreslere yazarak/ okuyarak gider.
 
Hal kütüphaneleri için ST nin toplu dökümanını inceleyebilirsin "UM1786" "Description of STM32F3 HAL and low-layer drivers" diye geçiyor.