本程序编写基于秉火霸道STM32F103ZET6运行环境。
1、看硬件原理图关于AT24C02的部分
关于I2C协议,在以往的博客中讲得很详细,这里就不在多说。
从该原理图,结合AT24C02的数据手册如下图片:
很容易得到I2C的7位设备地址为1010 000,A2,A1,A0由硬件连接决定,如硬件原理图所示,A2、A1、A0都是接地,所以都为0。而
当要向AT24C02写数据时,R/W位为0,则写地址为1010 0000,即是十六进制数:0xA0
当要向AT24C02读数据时,R/W位为1,则读地址为1010 0001,即是十六进制数:0xA1
2、建立STM32 cube工程
2.1 首先配置i2c、调试串口、时钟
设置I2C速度为标准模式
通信速度为100000Hz
地址为7bit模式,其余的默认设置即可。
I2C对应的SCL和SDA分别为PB6和PB7。
配置串口2为调试串口。
配置时钟为64MHz
2.2、生成工程
3、编写AT24C02基本驱动代码
参考AT24C02的官方数据手册,可以编写出一个读和一个写的数据接口,提供对AT24C02的基本读写能力。
AT24C02.h
#ifndef __AT24C02_H
#define __AT24C02_H
#include “main.h”
/*
* AT24C02 2kb = 2048bit = 2048/8 B = 256 B
* 32 pages of 8 bytes each
*
* Device Address
* 1 0 1 0 A2 A1 A0 R/W
* 1 0 1 0 0 0 0 0 = 0XA0
* 1 0 1 0 0 0 0 1 = 0XA1
*/
//写地址
#define AT24C02_WRITE_ADDRESS 0xA0
//读地址
#define AT24C02_READ_ADDRESS 0xA1
//存储结构体(我们用来测试的)
typedef struct EEPROM_ST
{
uint8_t init_flag ;
uint8_t led_setting_status ;
uint8_t buzzer_setting_status ;
}EEPROM_DATA;
extern EEPROM_DATA eerom_data ;
void Default_Setting(void);
//从AT24C02读取数据
int AT24C02_Read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead);
//写数据到AT24C02
int AT24C02_Write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite);
#endif //__AT24C02_H
AT24C02.c
#include “AT24C02.h”
EEPROM_DATA eerom_data;
/*
在AT24C02里面的指定地址开始读出指定个数的数据
ReadAddr :开始读出的地址 对24c02为0~255
pBuffer :数据数组首地址
NumToRead:要读出数据的个数
*/
int AT24C02_Read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead)
{
HAL_StatusTypeDef ret = HAL_ERROR ;
ret = HAL_I2C_Mem_Read(&hi2c1, AT24C02_READ_ADDRESS, ReadAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, NumToRead, 1000);
if(HAL_ERROR == ret)
return -1 ;
return HAL_OK ;
}
/*
在AT24C02里面的指定地址开始写入指定个数的数据
WriteAddr :开始写入的地址 对24c02为0~255
pBuffer :数据数组首地址
NumToWrite:要写入数据的个数
*/
int AT24C02_Write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite)
{
uint16_t i = 0, temp = 0;
HAL_StatusTypeDef ret = HAL_ERROR ;
temp = NumToWrite / (unsigned short)0x08;
for(i = 0; i 《 temp; i++)
{
ret = HAL_I2C_Mem_Write(&hi2c1, AT24C02_WRITE_ADDRESS, WriteAddr + (i * 8), I2C_MEMADD_SIZE_8BIT, pBuffer + (i * 8), 8, 1000);
HAL_Delay(10);
}
temp = NumToWrite % (unsigned short)0x08;
if(temp)
{
HAL_Delay(10);
ret = HAL_I2C_Mem_Write(&hi2c1, AT24C02_WRITE_ADDRESS, WriteAddr + (i * 8), I2C_MEMADD_SIZE_8BIT, pBuffer + (i * 8), temp, 1000);
}
if(HAL_ERROR == ret)
return -1 ;
return HAL_OK ;
}
//默认设置参数
void Default_Setting(void)
{
eerom_data.init_flag = 1 ;
eerom_data.led_setting_status = 1 ;
eerom_data.buzzer_setting_status = 0 ;
}
真实写主程序,验证AT24C02的读写功能:
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t Status = 0 ;
EEPROM_DATA eeprom_data_copy ;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
printf(“这是一个EEPROM的实验。..n”);
//设置默认参数
Default_Setting();
//将默认参数写入EEPROM,从0地址开始写入
Status = AT24C02_Write(0, (uint8_t *)&eerom_data, sizeof(eerom_data));
if(HAL_OK != Status)
{
printf(“数据写入EEPROM失败n”);
return -1 ;
}
printf(“数据写入EEPROM成功n”);
//从EEPROM中读取设置的默认参数,从0地址开始取出
Status = AT24C02_Read(0, (uint8_t *)&eeprom_data_copy, sizeof(eeprom_data_copy));
if(HAL_OK != Status)
{
printf(“读取EEPROM失败n”);
return -1 ;
}
printf(“读取EEPROM成功n”);
printf(“init_flag:%d led_setting_status:%d buzzer_setting_status:%dn”,eeprom_data_copy.init_flag,
eeprom_data_copy.led_setting_status,eeprom_data_copy.buzzer_setting_status);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
运行结果:
本程序编写基于秉火霸道STM32F103ZET6运行环境。
1、看硬件原理图关于AT24C02的部分
关于I2C协议,在以往的博客中讲得很详细,这里就不在多说。
从该原理图,结合AT24C02的数据手册如下图片:
很容易得到I2C的7位设备地址为1010 000,A2,A1,A0由硬件连接决定,如硬件原理图所示,A2、A1、A0都是接地,所以都为0。而
当要向AT24C02写数据时,R/W位为0,则写地址为1010 0000,即是十六进制数:0xA0
当要向AT24C02读数据时,R/W位为1,则读地址为1010 0001,即是十六进制数:0xA1
2、建立STM32 cube工程
2.1 首先配置i2c、调试串口、时钟
设置I2C速度为标准模式
通信速度为100000Hz
地址为7bit模式,其余的默认设置即可。
I2C对应的SCL和SDA分别为PB6和PB7。
配置串口2为调试串口。
配置时钟为64MHz
2.2、生成工程
3、编写AT24C02基本驱动代码
参考AT24C02的官方数据手册,可以编写出一个读和一个写的数据接口,提供对AT24C02的基本读写能力。
AT24C02.h
#ifndef __AT24C02_H
#define __AT24C02_H
#include “main.h”
/*
* AT24C02 2kb = 2048bit = 2048/8 B = 256 B
* 32 pages of 8 bytes each
*
* Device Address
* 1 0 1 0 A2 A1 A0 R/W
* 1 0 1 0 0 0 0 0 = 0XA0
* 1 0 1 0 0 0 0 1 = 0XA1
*/
//写地址
#define AT24C02_WRITE_ADDRESS 0xA0
//读地址
#define AT24C02_READ_ADDRESS 0xA1
//存储结构体(我们用来测试的)
typedef struct EEPROM_ST
{
uint8_t init_flag ;
uint8_t led_setting_status ;
uint8_t buzzer_setting_status ;
}EEPROM_DATA;
extern EEPROM_DATA eerom_data ;
void Default_Setting(void);
//从AT24C02读取数据
int AT24C02_Read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead);
//写数据到AT24C02
int AT24C02_Write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite);
#endif //__AT24C02_H
AT24C02.c
#include “AT24C02.h”
EEPROM_DATA eerom_data;
/*
在AT24C02里面的指定地址开始读出指定个数的数据
ReadAddr :开始读出的地址 对24c02为0~255
pBuffer :数据数组首地址
NumToRead:要读出数据的个数
*/
int AT24C02_Read(uint16_t ReadAddr, uint8_t *pBuffer, uint16_t NumToRead)
{
HAL_StatusTypeDef ret = HAL_ERROR ;
ret = HAL_I2C_Mem_Read(&hi2c1, AT24C02_READ_ADDRESS, ReadAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, NumToRead, 1000);
if(HAL_ERROR == ret)
return -1 ;
return HAL_OK ;
}
/*
在AT24C02里面的指定地址开始写入指定个数的数据
WriteAddr :开始写入的地址 对24c02为0~255
pBuffer :数据数组首地址
NumToWrite:要写入数据的个数
*/
int AT24C02_Write(uint16_t WriteAddr, uint8_t *pBuffer, uint16_t NumToWrite)
{
uint16_t i = 0, temp = 0;
HAL_StatusTypeDef ret = HAL_ERROR ;
temp = NumToWrite / (unsigned short)0x08;
for(i = 0; i 《 temp; i++)
{
ret = HAL_I2C_Mem_Write(&hi2c1, AT24C02_WRITE_ADDRESS, WriteAddr + (i * 8), I2C_MEMADD_SIZE_8BIT, pBuffer + (i * 8), 8, 1000);
HAL_Delay(10);
}
temp = NumToWrite % (unsigned short)0x08;
if(temp)
{
HAL_Delay(10);
ret = HAL_I2C_Mem_Write(&hi2c1, AT24C02_WRITE_ADDRESS, WriteAddr + (i * 8), I2C_MEMADD_SIZE_8BIT, pBuffer + (i * 8), temp, 1000);
}
if(HAL_ERROR == ret)
return -1 ;
return HAL_OK ;
}
//默认设置参数
void Default_Setting(void)
{
eerom_data.init_flag = 1 ;
eerom_data.led_setting_status = 1 ;
eerom_data.buzzer_setting_status = 0 ;
}
真实写主程序,验证AT24C02的读写功能:
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t Status = 0 ;
EEPROM_DATA eeprom_data_copy ;
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C1_Init();
MX_USART2_UART_Init();
/* USER CODE BEGIN 2 */
printf(“这是一个EEPROM的实验。..n”);
//设置默认参数
Default_Setting();
//将默认参数写入EEPROM,从0地址开始写入
Status = AT24C02_Write(0, (uint8_t *)&eerom_data, sizeof(eerom_data));
if(HAL_OK != Status)
{
printf(“数据写入EEPROM失败n”);
return -1 ;
}
printf(“数据写入EEPROM成功n”);
//从EEPROM中读取设置的默认参数,从0地址开始取出
Status = AT24C02_Read(0, (uint8_t *)&eeprom_data_copy, sizeof(eeprom_data_copy));
if(HAL_OK != Status)
{
printf(“读取EEPROM失败n”);
return -1 ;
}
printf(“读取EEPROM成功n”);
printf(“init_flag:%d led_setting_status:%d buzzer_setting_status:%dn”,eeprom_data_copy.init_flag,
eeprom_data_copy.led_setting_status,eeprom_data_copy.buzzer_setting_status);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
运行结果:
举报