stm32cubeMX学习八、驱动AT24C02(基于STM32F103ZET6)

本程序编写基于秉火霸道STM32F103ZET6运行环境。
在这里插入图片描述

1、看硬件原理图关于AT24C02的部分

在这里插入图片描述
关于I2C协议,在以往的博客中讲得很详细,这里就不在多说。
https://blog.csdn.net/morixinguan/article/details/78509764
从该原理图,结合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:%d\n",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 */
}

运行结果:在这里插入图片描述
测试例程下载:
https://download.csdn.net/download/morixinguan/11572496
在这里插入图片描述

发布了597 篇原创文章 · 获赞 1061 · 访问量 182万+

猜你喜欢

转载自blog.csdn.net/morixinguan/article/details/99687237