STM32 HAL库硬件IIC实现CAT24C128通讯

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);
	}
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值