CPU作爲老闆,發錢需要自己轉帳,收錢需要自己看信息,是一種悲哀。
上一篇《STM32 使用IO口模擬I2C時序》,我們講述了“論老闆如何自己發錢和收錢”。
這一篇《STM32 使用硬件I2C接口讀寫EEPROM》,我們來講述“論老闆如何僱傭員工幫忙發錢和收錢”。
我們先來招聘一個職位:
崗位職責:
1、自動產生I2C時序,向其他芯片發送(發錢)或者接收(收錢)數據。
任職要求:
1、CPU只需發指令便行,無須關心時序。(老闆只要告訴發多少錢就行了,不需要知道怎麼發)。
經過層層篩選,I2C bus interface 剛好符合這個要求,他的簡歷在 RM0033文檔 553頁,記得多讀讀喔。
它還能與搬磚小能手DMA配合,把錢當磚頭搬,相當強大。
這就是業內人稱:硬件I2C,它會自動產生SCL/SDA的時序,不需要通過CPU對IO口拉高拉低。
接下來,寫代碼了,Stm32Cube這一塊,就不再多敘述,簡單說一下就行了。
對EEPROM操作,速度,選擇100K就夠了,如果要選擇更牛逼的速度,要把Speed Mode變成Fast Mode。
這裏值得一提的是,爲什麼有個Slave Features呢?
因爲Stm32的I2C也可以做從設備,讓另一個MCU做主設備,對它進行操作。在這裏,我們是對EEPROM操作,是做主設備,這個Slave,就不用管它。
另外,不建議Mcu間的通信用I2C,一般用RS232/RS485,簡單通用。
還有,Stm32 I2C同樣是支持DMA方式的,我們這裏,就不用DMA了。
生成代碼,看看都生成了些啥?
i2c.c/i2c.h 文件,還有在main裏面調用 MX_I2C1_Init() 配置I2C
我們把它添加到上一篇的工程裏,同樣用@cmd命令測試它。
PS: stm32cube生成代碼時,自已添加修改的代碼,會被覆蓋。這讓人很惱火。解決方法有4個:
1. 在項目初期,規劃好所有用到的外設,一次性配置好;
2. 將自己的代碼添加在 /* USER CODE BEGIN */和/* USER CODE END*/之間(這讓人更惱火,還讓不讓人自由自在地寫代碼了?程序員追求自由自在的心靈,叔可忍,嬸不可忍!);
3. 自己調用HAL庫配置(要stm32cube幹嘛?總得做點事吧?);
4. 用stm32cube配置好,生成代碼後,把相關的代碼拷到對應的項目上(我就是這麼做的。)。
對了,記得務必要把i2c.c加進編譯裏面,加在User裏面。
對了,記得務必要把stm32_hal_i2c.c也加進編譯裏面,加在 Drivers裏面。
對了,還要把 stm32f2xx_hal_conf.h裏面的 #define HAL_I2C_MODULE_ENABLED 打開。
對了,還要記得io口__HAL_RCC_GPIOB_CLK_ENABLE()。
接下來,
在main裏面,#include "i2c.h"
在初始化代碼裏增加 MX_I2C1_Init();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_UART4_Init();
MX_TIM1_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
USR_UartInit();
// IOI2C_GpioInit(); // 上一節的IO口,要去掉啊。
MX_I2C1_Init(); // 看這裏,看這裏!
接下來,調用這兩個函數,一個是寫,一個是讀。
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);
上一節的工程基礎上,在at24c02.c/at24c02.h 裏,把 I2C 讀寫的接口改一下:
static uint8_t I2C_READBUF(uint8_t *pAddr, uint8_t *pData, uint16_t len)
{
// return IOI2C_ReadBlock(AT24C02_DEVICE, pAddr, 1, pData, len);
uint16_t addr = *pAddr;
if(HAL_I2C_Mem_Read(&hi2c1, AT24C02_DEVICE|I2C_RD, addr, I2C_MEMADD_SIZE_8BIT, pData, len, 500) != HAL_OK)
return IOI2C_BUSY;
return IOI2C_OK;
}
static uint8_t I2C_WRITEBUF(uint8_t *pAddr, uint8_t *pData, uint16_t len)
{
// return IOI2C_WriteBlock(AT24C02_DEVICE, pAddr, 1, pData, len);
uint16_t addr = *pAddr;
if(HAL_I2C_Mem_Write(&hi2c1, AT24C02_DEVICE|I2C_WR, addr, I2C_MEMADD_SIZE_8BIT, pData, len, 500) != HAL_OK)
return IOI2C_BUSY;
return IOI2C_OK;
}
編譯、燒錄、運行、測試:
寫字節:
@cmd 0x1 2 0 0x13
@cmd 0x1 2 1 0x14
@cmd 0x1 2 2 0x34
讀字節:
@cmd 0x1 0 0
@cmd 0x1 0 1
@cmd 0x1 0 2
3. 寫一串,就往0x3存儲單元寫14個字節吧。
@cmd 0x1 3 0x3 14
4、讀一串,就從0x0讀18個字節吧。
@cmd 0x1 1 0x0 18
0x13、0x14、0x34,是寫字節時寫進去的;
0x3~0x10,是寫一串的時候寫進去的,剛好14個字節。
整個工程及代碼呢,請上百度網盤上下載:
鏈接:https://pan.baidu.com/s/19usUcgZPX8cCRTKt_NPcfg
密碼:07on
文件夾:\Stm32CubeMx\Code\I2c.rar
上一篇:《STM32 使用IO口模擬I2C時序》
下一篇:《》
回目錄:《目錄》