1. 使用STM32CubeMX生成I2C初始化代码
hi2c1.Instance = I2C1;
hi2c1.Init.Timing = 0x20404768;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK) {
Error_Handler();
}
if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) {
Error_Handler();
}
if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) {
Error_Handler();
}
2. CAT24C128.h
/*
* CAT24C128.h
*
* Created on: Feb 27, 2024
* Author: atom
*/
#ifndef SRC_MODULE_CAT24C128_H_
#define SRC_MODULE_CAT24C128_H_
#include <stdint.h>
/******************************************************************************/
/* Macro Definitions */
/* 宏定义 */
/*****************************************************************************/
#define CAT24C128_PAGE_NUM 256
#define CAT24C128_PAGE_SIZE 64
#define CAT24C128_A0 0 << 1
#define CAT24C128_A1 0 << 2
#define CAT24C128_A2 0 << 3
#define CAT24C128_ADDRESS_HEADER (0b1010 << 4)
#define CAT24C128_WRITE_ADDRESS (uint8_t)(CAT24C128_ADDRESS_HEADER | CAT24C128_A2 | CAT24C128_A1 | CAT24C128_A0 | 0)
#define CAT24C128_READ_ADDRESS (uint8_t)(CAT24C128_ADDRESS_HEADER | CAT24C128_A2 | CAT24C128_A1 | CAT24C128_A0 | 1)
#define CAT24C128_DATA_ADDRESS(page, index) ((uint16_t)((((uint16_t)(page)) << 6) | ((uint16_t)(index & 0x3F))))
/******************************************************************************/
/* Functions Prototypes */
/* 函数声明 */
/*****************************************************************************/
uint8_t CAT24C128_ReadBytes(uint8_t *_pReadBuf, uint16_t address, uint16_t size);
uint8_t CAT24C128_WriteBytes(uint8_t *_pWriteBuf, uint16_t address, uint16_t size);
uint16_t CAT24C128_Calculate_Page_Num(uint16_t address, uint16_t size);
uint16_t* CAT24C128_Calculate_Page_Space(uint16_t address, uint16_t size);
#endif /* SRC_MODULE_CAT24C128_H_ */
3. CAT24C128.c
/*
* CAT24C128.c
*
* Created on: Feb 27, 2024
* Author: atom
*/
#include "CAT24C128.h"
#include "bsp_i2c.h"
#include <stdlib.h>
#include <string.h>
/******************************************************************************/
/* Functions Prototypes */
/* 函数实现 */
/*****************************************************************************/
uint8_t CAT24C128_ReadBytes(uint8_t *_pReadBuf, uint16_t address, uint16_t size) {
uint8_t recv;
if ((recv = HAL_I2C_Mem_Read(&hi2c1, CAT24C128_READ_ADDRESS, address, I2C_MEMADD_SIZE_16BIT, _pReadBuf, size, 100)) == HAL_OK) {
return 1;
}
return 0;
}
uint8_t CAT24C128_WriteBytes(uint8_t *_pWriteBuf, uint16_t address, uint16_t size) {
uint16_t pageNum = CAT24C128_Calculate_Page_Num(address, size);
if (pageNum > CAT24C128_PAGE_NUM) return 0;
uint16_t startByte = address & (CAT24C128_PAGE_SIZE - 1);
uint16_t *byteCounts = CAT24C128_Calculate_Page_Space(address, size);
uint16_t alreadySend = 0;
uint16_t p, n = 0;
uint16_t page = address >> 6;
for (p = 0; p < pageNum; p++) {
uint16_t byteCount = byteCounts[p];
uint8_t data[byteCount];
startByte = p == 0 ? startByte : 0;
uint16_t pAddr = CAT24C128_DATA_ADDRESS(page, startByte);
for (n = 0; n < byteCount; n++) {
data[n] = _pWriteBuf[n + alreadySend];
}
HAL_StatusTypeDef recv;
if (!((recv = HAL_I2C_Mem_Write(&hi2c1, CAT24C128_WRITE_ADDRESS, pAddr, I2C_MEMADD_SIZE_16BIT, data, byteCount, 100)) == HAL_OK)) {
return 0;
}
HAL_Delay(5);
alreadySend += byteCount;
page++;
}
return 1;
}
uint16_t CAT24C128_Calculate_Page_Num(uint16_t address, uint16_t size) {
uint16_t usize = size;
uint16_t num = 0;
uint16_t freeSpace = CAT24C128_PAGE_SIZE - (address & (CAT24C128_PAGE_SIZE - 1));
if (usize <= freeSpace) {
return 1;
}
usize -= freeSpace;
num = usize / CAT24C128_PAGE_SIZE;
num += (usize % CAT24C128_PAGE_SIZE != 0) + 1;
return num;
}
uint16_t* CAT24C128_Calculate_Page_Space(uint16_t address, uint16_t size) {
uint16_t usize = size;
uint16_t index = 0;
uint16_t freeSpace = CAT24C128_PAGE_SIZE - (address & (CAT24C128_PAGE_SIZE - 1));
uint16_t *spaceList = (uint16_t*) malloc(CAT24C128_PAGE_NUM * sizeof(uint16_t));
memset(spaceList, 0, CAT24C128_PAGE_NUM * sizeof(uint16_t));
while (usize > 0) {
if (usize > freeSpace) {
usize -= freeSpace;
spaceList[index] = freeSpace;
freeSpace = CAT24C128_PAGE_SIZE;
index++;
}
if (usize <= freeSpace) {
spaceList[index] = usize;
return spaceList;
}
}
return spaceList;
}
使用示例:
// 从地址0 上读取连续六个字符 储存到result_code
uint8_t result_code[6] = { 0 };
uint8_t result_eeprom = CAT24C128_ReadBytes(result_code, 0, 6);
// 将eeprom_checkCode数组写入到地址0
const uint8_t eeprom_checkCode[6] = { 5, 9, 6, 2, 4, 8 };
CAT24C128_WriteBytes(eeprom_checkCode, 0, 6);
注意CAT24C128_WriteBytes这个函数里使用了HAL_Delay(5)
如果在中断中使用可能会导致主机卡死, 可以换成自己实现的delay
附STM32自定义延时:
#include "delay.h"
void delay_us(uint32_t nus) {
uint32_t ticks;
uint32_t told, tnow, reload, tcnt = 0;
reload = SysTick->LOAD; // 获取重装载寄存器值
ticks = nus * (SystemCoreClock / 1000000); // 计数时间值
told = SysTick->VAL; // 获取当前数值寄存器值(开始时数值)
while (1) {
tnow = SysTick->VAL; // 获取当前数值寄存器值
if (tnow != told) // 当前值不等于开始值说明已在计数
{
if (tnow < told) { // 当前值小于开始数值,说明未计到0
tcnt += told - tnow; // 计数值=开始值-当前值
} else { // 当前值大于开始数值,说明已计到0并重新计数
tcnt += reload - tnow + told; // 计数值=重装载值-当前值+开始值 (已从开始值计到0)
}
told = tnow; // 更新开始值
if (tcnt >= ticks) {
break; // 时间超过/等于要延迟的时间,则退出.
}
}
}
}
void delay_ms(uint16_t ms) {
while (ms-- != 0) {
delay_us(1000);
}
}
void delay_s(uint16_t s) {
while (s-- != 0) {
delay_ms(1000);
}
}