STM32CubeMx入門教程(7):I2C的讀寫應用

2023-07-12 12:03:19 來源:嵌入式開發(fā)始站

導語“本次 教程使用CubeMx配置I2C進行I2C總線設(shè)備的數(shù)據(jù)讀寫操作,使用EEPROM作為實驗對象”


(資料圖片)

01第一節(jié) 系統(tǒng)要求

?硬件

野火指南者開發(fā)板

?軟件

CubeMx & MDK & 串口調(diào)試助手

?原理圖

我們可以從原理圖中得到使用的I2C1,AT24C02的設(shè)備地址的第三位是000,容量是256個字節(jié)。設(shè)備地址從下圖得到:

不帶讀寫方向的使用左移得到的地址為0b10100000->0xA0, 讀地址為:0xA1,寫地址為0xA0;

注意:(1) 操作ATC02的時候,多字節(jié)寫入的時候沒寫入一個字節(jié),延時最小5ms, 多字節(jié)讀的時候沒有要求,頁寫入的時候每8個字節(jié)為一頁,共32頁。

02第二節(jié) CubeMx的配置

我們依然使用之前的USART的項目,在此基礎(chǔ)上進行I2C的配置,串口的使用是進行EEPROM讀寫數(shù)據(jù)顯示在控制臺上,使用CubeMx進行I2C的配置:

I2C的配置很簡單,完成上述配置后生成代碼。

03第三節(jié)MDK的代碼編寫

使用MDK打開CubeMx生成的代碼進行應用代碼編寫。

(1)在main.c 中進行AT24C02的相關(guān)宏定義和變量定義:

#define ADDR_AT24C_Write0xA0#define ADDR_AT24C_Read  0xA1#define DEV_ADDR_ATC02   0xA0 //0x50 左移得到的。#define ATC02_BufferSize 256   // 256#define I2C_TIMEOUT                0xFF#define AT_I2C              hi2c1uint8_t AT24_WriteBuffer[ATC02_BufferSize],AT24_ReadBuffer[ATC02_BufferSize];

( 2 ) 應用函數(shù)申明:

HAL_StatusTypeDef I2C_Write_Buffer(I2C_HandleTypeDef *hi2c,uint16_t DevAddress, uint16_t MemAddress,uint16_t MemAddSize, uint8_t *pData, uint16_t Size,uint32_t Timeout);HAL_StatusTypeDef I2C_Read_Buffer(I2C_HandleTypeDef *hi2c,uint16_t DevAddress, uint16_t MemAddress,uint16_t MemAddSize, uint8_t *pData, uint16_t Size,uint32_t Timeout);

I2CWriteBuffer()是自定義的任意字節(jié)寫入I2C-AT24C02的函數(shù),I2CReadBuffer()是任意字節(jié)讀寫函數(shù)。這兩個函數(shù)的實現(xiàn)采用HAL庫的這兩個函數(shù):

1)HALStatusTypeDef HALI2CMemWrite(I2CHandleTypeDef *hi2c, uint16t DevAddress, uint16t MemAddress, uint16t MemAddSize, uint8t *pData, uint16t Size, uint32_t Timeout);

參數(shù)依次是:(I2C句柄,AT24C02的設(shè)備地址,設(shè)備中數(shù)據(jù)地址,數(shù)據(jù)地址的大小,寫的數(shù)據(jù),數(shù)據(jù)大小,超時時間)

2)HALStatusTypeDef HALI2CMemRead(I2CHandleTypeDef *hi2c, uint16t DevAddress, uint16t MemAddress, uint16t MemAddSize, uint8t *pData, uint16t Size, uint32_t Timeout);

參數(shù)依次是:(I2C句柄,AT24C02的設(shè)備地址,設(shè)備中數(shù)據(jù)地址,數(shù)據(jù)地址的大小,讀出數(shù)據(jù),數(shù)據(jù)大小,超時時間)

為什么不直接使用庫函數(shù)呢?是因為在測試中AT24C02讀寫不正常,查看AT24C02的手冊發(fā)現(xiàn),單個字節(jié)寫入沒問題,多字節(jié)的寫入需要每個字節(jié)延時5ms, 其實多字節(jié)的讀沒有問題,這個從新實現(xiàn)了下。可以連續(xù)8個字節(jié)的頁寫入,這個不需要延時。

(3)多字節(jié)的讀寫函數(shù):

/*這里自己實現(xiàn)多字節(jié)的ATC02的寫操作*/HAL_StatusTypeDef I2C_Write_Buffer(I2C_HandleTypeDef *hi2c,uint16_t DevAddress, uint16_t MemAddress,uint16_t MemAddSize, uint8_t *pData, uint16_t Size,uint32_t Timeout){       uint16_t count=0;       for(count=0;count       {              if(HAL_I2C_Mem_Write(hi2c,DevAddress,MemAddress, MemAddSize,pData,1,Timeout)==HAL_OK)              {                     MemAddress ++;                     pData ++;                     HAL_Delay(5);              }              else              {                     printf("i2c write is error tn");                     return HAL_ERROR;              }       }       return HAL_OK;}/*這里自己實現(xiàn)多字節(jié)的ATC02的讀操作*/HAL_StatusTypeDef I2C_Read_Buffer(I2C_HandleTypeDef *hi2c,uint16_t DevAddress, uint16_t MemAddress,uint16_t MemAddSize, uint8_t *pData, uint16_t Size,uint32_t Timeout){       uint16_t count=0;       for(count=0;count< Size;count ++)       {              if(HAL_I2C_Mem_Read(hi2c,DevAddress,MemAddress, MemAddSize,pData,1,Timeout)==HAL_OK)              {                     MemAddress ++;                     pData ++;                     //HAL_Delay(5);              }              else              {                     printf("i2c read is error n");                     return HAL_ERROR;              }       }       return HAL_OK;}

(4)在main函數(shù)中添加測試代碼:

uint16_t num_atc=0;       printf("this is test for I2C device read and write in ATC02rn");       printf("/**--------------------開始I2C-------------------------**/rn");       for( num_atc=0;num_atc       {              AT24_WriteBuffer[num_atc]=num_atc;              printf("0x%xt",AT24_WriteBuffer[num_atc]);              }       if(I2C_Write_Buffer(&AT_I2C,DEV_ADDR_ATC02, 0, I2C_MEMADD_SIZE_8BIT,AT24_WriteBuffer,ATC02_BufferSize, I2C_TIMEOUT) == HAL_OK)       {              printf("write i2c lots bytes is oktn");       }       if(HAL_I2C_Mem_Read(&AT_I2C,DEV_ADDR_ATC02, 0, I2C_MEMADD_SIZE_8BIT,AT24_ReadBuffer,ATC02_BufferSize,I2C_TIMEOUT)== HAL_OK)       {              printf("rn EEPROM 24C02 read data Test OK rn");       }       else       {              printf("rn EEPROM 24C02 read data Test False rn");       }/*這里使用自定義多字節(jié)讀函數(shù)也是正常的*//*       if(I2C_Read_Buffer(&AT_I2C,DEV_ADDR_ATC02, 0,               I2C_MEMADD_SIZE_8BIT,AT24_ReadBuffer,ATC02_BufferSize,I2C_TIMEOUT)== HAL_OK)       {              printf("i2c read lots is oktn");       }*/       for(num_atc=0; num_atc< ATC02_BufferSize; num_atc++)       {              printf("0x%xt",AT24_ReadBuffer[num_atc]);       }       if(memcmp(AT24_WriteBuffer,AT24_ReadBuffer,ATC02_BufferSize) == 0 ) /* check date */       {              printf("rn EEPROM 24C02 Read and write Test OKrn");       }       else       {    printf("rn EEPROM 24C02 Read and write Test Falsern");       }              printf("/**--------------------結(jié)束I2C-------------------------**/rn");

編譯上述程序后下載

04第四節(jié)效果演示

使用串口觀察寫入的數(shù)據(jù)和讀出的數(shù)據(jù)是否一致?

可以看到I2C操作EEPROM進行讀寫都是正常的。

標簽:

上一篇:ASIC設(shè)計約束與SDC命令介紹
下一篇:最后一頁