AT24C16的地址
可以看到,16的数据地址是11位,器件地址的P2/P1/P0也是数据地址的一部分.
STM32的硬件I2C只有7/10BIT两种模式,因此本程序用7BIT实现。
函数实现
头文件
#ifndef _AT24C16_H_
#define _AT24C16_H_
#include "main.h"
#define AT24C16_DEVICE_ADDRESS 0xA0 // AT24C16的IIC地址
uint16_t AT24C16_ADDRESS_2(uint16_t page, uint16_t bit);
HAL_StatusTypeDef AT24C16_Write(uint16_t address, uint8_t *data, uint16_t size);
HAL_StatusTypeDef AT24C16_Read(uint16_t address, uint8_t *rx_buffer, uint16_t size);
HAL_StatusTypeDef AT24C16_Write_String(uint16_t address, uint8_t *data);
HAL_StatusTypeDef AT24C16_Read_String(uint16_t address, uint8_t *data, uint16_t size);
#endif
at24c16.c
#include "main.h"
#include "i2c.h"
#include "gpio.h"
#include "at24c16.h"
#include "stddef.h"
/*
* 地址转换,将十进制地址转换成二进制地址
* @page:页数
* @bit:字节位
*/
uint16_t AT24C16_ADDRESS_2(uint16_t page, uint16_t bit)
{
return ((page << 4) | bit);
}
/*
* 写函数
* @address:二进制地址
* @data:数据地址
* @size:数量
*/
HAL_StatusTypeDef AT24C16_Write(uint16_t address, uint8_t *data, uint16_t size)
{
HAL_StatusTypeDef state = HAL_OK;
uint8_t add = ((address >> 7) & 0x000e);
add = AT24C16_DEVICE_ADDRESS | add;
state = HAL_I2C_Mem_Write(&hi2c1, add, (uint8_t)address, I2C_MEMADD_SIZE_8BIT, data, size, 100);
return state;
}
/*
* 读函数
* @address:二进制地址
* @data:数据地址
* @size:数量
*/
HAL_StatusTypeDef AT24C16_Read(uint16_t address, uint8_t *rx_buffer, uint16_t size)
{
HAL_StatusTypeDef state = HAL_OK;
uint8_t add = ((address >> 7) & 0x000e);
add = AT24C16_DEVICE_ADDRESS | add;
state = HAL_I2C_Mem_Read(&hi2c1, add, (uint8_t)address, I2C_MEMADD_SIZE_8BIT, rx_buffer, size, 100);
return state;
}
/*
* 连续写函数,没有实现任意字节
* @address:地址(简单实现连续页)
* @data:数据地址
*/
HAL_StatusTypeDef AT24C16_Write_String(uint16_t address, uint8_t *data)
{
HAL_StatusTypeDef state = HAL_OK;
uint16_t i = sizeof(data) / 16;
(sizeof(data) % 16 != 0) ? i++ : 0;
uint16_t j = address >> 4;
for (int k = 0; k < i; k++)
{
state = AT24C16_Write(AT24C16_ADDRESS_2(j + k, 0), (uint8_t *)&data[i * 16], 16);
}
return state;
}
/*
* 连续读函数,没有实现任意字节
* @address:地址(简单实现连续页)
* @data:数据地址
* @size:数量
*/
HAL_StatusTypeDef AT24C16_Read_String(uint16_t address, uint8_t *data, uint16_t size)
{
HAL_StatusTypeDef state = HAL_OK;
uint16_t i = size / 16;
(size % 16 != 0) ? i++ : 0;
uint16_t j = address >> 4;
for (int k = 0; k < i; k++)
{
state = AT24C16_Read(AT24C16_ADDRESS_2(j + k, 0), (uint8_t *)&data[i * 16], 16);
}
return state;
}
调用方法
注意
连续读写函数只进行了601个字节的测试!