【STM32】标准库与HAL库对照学习教程十三--软件IIC控制AT24C02


STM32全部教程【STM32】标准库与HAL库对照学习系列教程大全

一、前言

本篇介绍如何使用软件IIC对AT24C02进行数据的读写操作,通过标准库与HAL库的对比,希望能让您了解使用IIC控制外设的一般步骤,希望本篇文章对您能有所帮助。

工程配置在前面已经配了很多次了,本章不会再详细讲解工程配置。
有关IIC的原理您可以看这篇文章:
【STM32】标准库与HAL库对照学习教程特别篇–IIC通信原理讲解
本篇不会再介绍IIC的通信原理。

二、准备工作

  • STM32开发板(我用的是普中的STM32F103ZE的Z200系列)
  • STM32cubemx软件、keil5(MDK)
  • 开发板原理图

三、AT24C02(EEPROM)介绍

1、AT24C02简介

AT24C02EEPROM储存器的一种,其内部可存储256个字节(0xff)的数据。

在其内部有一个8字节的页面缓存区,当对AT24C02进行写数据的操作时,会将数据先放到缓存区里,再存入存储器里,因此要注意控制写入数据的间隔时间

结构图:
在这里插入图片描述

2、引脚功能

在这里插入图片描述

3、设备地址

AT24C02器件地址为7位高4位固定为1010,低3位由 A0/A1/A2信号线的电平决定。传输地址数据时,第八位是读写位

四、硬件电路图

看自己开发板的原理图。
在这里插入图片描述
在这里插入图片描述

五、数据传输过程

1、写入数据

  • 1、MCU先发送一个起始信号启动总线
  • 2、接着,发送设备写操作地址(0xA0)。
  • 3、等待应答信号(ACK)。
  • 4、发送写入数据的存储地址。AT24C02一共有256个字节的存储空间,地址从0x00~0xFF
  • 5、每写一个字节的数据,AT24C02都会回应一个应答信号
  • 6、当AT24C02回应非应答信号或者主设备不在写入数据时,主设备发送结束信号停止总线。

2、读入数据

  • 1、MCU先发送一个开始信号启动总线
  • 2、接着,发送设备写操作地址(0xA0)。(这里的写操作是为了要先把要读的数据的存储地址先写进去,告诉AT24C02要读取哪个地址的数据。)
  • 3、发送要读取内存的地址
  • 4、重新发送开始信号
  • 5、发送设备读操作地址 (0xA1)。
  • 6、AT24C02自动向主机发送数据,主机每接收一个字节的数据都要回应一个应答信号
  • 当主设备在读数据时,发送一个非应答信号。在发送结束信号停止总线

六、标准库控制AT24C02

1、实验程序

iic.h

#ifndef IIC_H_
#define IIC_H_


#include "stm32f10x.h"

#define  DEBUG_IIC 1  //调试IIC开关

/************重定义引脚时钟等************/
#define IIC_SCL_RCC   RCC_APB2Periph_GPIOB
#define IIC_SCL_Pin   GPIO_Pin_6
#define IIC_SCL_Port  GPIOB

#define IIC_SDA_RCC   RCC_APB2Periph_GPIOB
#define IIC_SDA_Pin   GPIO_Pin_7
#define IIC_SDA_Port  GPIOB

/************位带操作************/
#define SCL       PBout(6)
#define SDA_out   PBout(7)
#define SDA_in    PBin(7)

void IIC_Init(void);         //IIC引脚初始化
void IIC_start(void);        //IIC起始信号
void IIC_end(void);          //IIC停止信号
void IIC_ACK(void);          //IIC主机发出应答信号
void IIC_NACK(void);         //IIC主机发出非应答信号
u8 IIC_Wait_ACK(void);       //主机等待应答信号 
void IIC_Write_byte(u8 bit); //IIC写一个字节函数
u8 IIC_Read_byte(u8 ACK);    //IIC读取一个字节的数据

#endif

iic.c

#include "iic.h"
#include "System.h"
#include "Delay.h"

#if DEBUG_IIC
#include "usart.h"
#include<stdio.h>
#endif

/*************************************************
*函数名:     IIC_Init
*函数功能:   IIC引脚初始化
*输入:       无
*返回值:     无
**************************************************/
void IIC_Init()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(IIC_SCL_RCC|IIC_SDA_RCC, ENABLE);  //打开对应时钟
	
	GPIO_InitStruct.GPIO_Pin = IIC_SCL_Pin;    //SCL引脚
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽式输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(IIC_SCL_Port, &GPIO_InitStruct); //引脚初始化 
	 
	GPIO_InitStruct.GPIO_Pin = IIC_SDA_Pin;    //SDA引脚
	GPIO_Init(IIC_SDA_Port,&GPIO_InitStruct);  //引脚初始化
	
	SCL = 1;
	SDA_out = 1;
}

/*************************************************
*函数名:     IIC_OUT
*函数功能:   SDA引脚转为输出模式
*输入:       无
*返回值:     无
**************************************************/
void IIC_OUT()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Pin = IIC_SDA_Pin;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出模式
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(IIC_SDA_Port,&GPIO_InitStruct);
}

/*************************************************
*函数名:     IIC_IN
*函数功能:   SDA引脚转为输入模式
*输入:       无
*返回值:     无
**************************************************/
void IIC_IN()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.GPIO_Pin = IIC_SDA_Pin;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;  //上拉输入模式
	GPIO_Init(IIC_SDA_Port,&GPIO_InitStruct);
}

/*************************************************
*函数名:     IIC_start
*函数功能:   IIC起始信号
*输入:       无
*返回值:     无
**************************************************/
void IIC_start()
{
	IIC_OUT();    //SDA变为输出状态
	SCL = 1;
	SDA_out = 1;
	Delay_us(5);
	SDA_out = 0;
	Delay_us(5);
}

/*************************************************
*函数名:     IIC_end
*函数功能:   IIC停止信号
*输入:       无
*返回值:     无 
**************************************************/
void IIC_end()
{
	IIC_OUT();    //SDA变为输出状态
	SCL = 0;
	SDA_out = 0;
	SCL = 1;
	Delay_us(5);
	SDA_out = 1;
	Delay_us(5);
}

/*************************************************
*函数名:      IIC_ACK
*函数功能:    IIC主机发出应答信号
*输入:        无
*返回值:      无
**************************************************/
void IIC_ACK()
{
	IIC_OUT();    //SDA变为输出状态
	SCL = 0;
	SDA_out = 0;
	Delay_us(2);
	SCL = 1;
	Delay_us(5);
	SCL = 0;
}

/*************************************************
*函数名:       IIC_NACK
*函数功能:     IIC主机发出非应答信号
*输入:         无
*返回值:       无
**************************************************/
void IIC_NACK()
{
	IIC_OUT();   //SDA变为输出状态
	SCL = 0;
	SDA_out = 1;
	Delay_us(2);
	SCL = 1;
	Delay_us(5);
	SCL = 0;
}

/*************************************************
*函数名:       IIC_Wait_ACK
*函数功能:     主机等待应答信号
*输入:         无
*返回值:       1:接收到应答信号,0:非应答或者未接收到应答信号
**************************************************/
u8 IIC_Wait_ACK()
{
	u8 i;
	IIC_IN();   //SDA变为输入状态
	SCL = 1;
	while(SDA_in)
	{
		i++;
		if(i > 250)
		{
			IIC_end();
			#if DEBUG_IIC
				printf("未收到应答信号,IIC有误\r\n");
			#endif
			return 0;
		}
	}
  	SCL=0;  
	return 1; 
}

/*************************************************
*函数名:       IIC_Write_byte
*函数功能:     IIC写一个字节函数
*输入:         bit:写入的数据
*返回值:       无
**************************************************/
void IIC_Write_byte(u8 byte)
{
	u8 i;
	IIC_OUT();  //SDA变为输出状态
	SCL = 0;
	for(i = 0;i < 8;i++)
	{
		if(byte & 0x80)   //判断最高位,0x80 = 1000 0000
			SDA_out = 1;
		else
			SDA_out = 0;
		byte <<= 1;
		Delay_us(2);
		SCL = 1;
		Delay_us(2);
		SCL = 0;
		Delay_us(2);
	}
}

/*************************************************
*函数名:       IIC_Read_byte
*函数功能:     IIC读取一个字节的数据
*输入:         ACK:1-接收后给应答信号,0-接收后给非应答信号
*返回值:       BIt:读取的值
**************************************************/
u8 IIC_Read_byte(u8 ACK)
{
	u8 i,Bit;
	IIC_IN();   //SCL变为输入状态
	for(i = 0;i < 8;i++)
	{
		SCL = 0;
		Delay_us(2);
		SCL = 1;
		Bit <<= 1;
		if(SDA_in)
			Bit++;
	}
	if(ACK)
		IIC_ACK();
	else
		IIC_NACK();
	return Bit;
}

AT24C02.h

#ifndef AT24C02_H_
#define AT24C02_H_


#include "stm32f10x.h"


/************设备地址************/
#define AT24C02_Address        0xA0  //EEPROM设备地址,1010 0000
#define AT24C02_Write_Address  0xA0  //EEPROM写地址,1010 0000+0000 0000
#define AT24C02_Read_Address   0xA1  //EEPROM读地址,1010 0000+0000 0001

/************内存地址是0x00~0xff************/

void AT24C02_Init(void);    //AT24C02初始化
void AT24C02_Write_Byte(u8 Address,u8 Byte);  //对AT24C02写一个字节的数据
u8 AT24C02_Read_Byte(u8 Address);   //对AT24C02读一个字节的数据
void AT24C02_Write_Continue(u8 Address,u8 *data,u8 number);  //连续写n个字节的数据
void AT24C02_Read_Continue(u8 Address,u8 *data,u8 number);  //连续读n个字节的数据
u8 AT24C02_check(void);   //AT24C02检测
void AT24C02_clear(void);  //清空AT24C02的数据

#endif

AT24C02.c

#include "AT24C02.h"
#include "iic.h"
#include "Delay.h"

/*************************************************
*函数名:    AT24C02_Init
*函数功能:  AT24C02初始化
*输入:      无
*返回值:    无
**************************************************/
void AT24C02_Init()
{
	IIC_Init();
}

/*************************************************
*函数名:   AT24C02_Write_Byte
*函数功能: 向AT24C02写一个字节的数据
*输入:     Address:AT24C02中存放数据的地址,Byte:存放的数据
*返回值:   无
**************************************************/
void AT24C02_Write_Byte(u8 Address,u8 Byte)
{
	IIC_start();
	IIC_Write_byte(AT24C02_Write_Address);
	IIC_Wait_ACK();
	IIC_Write_byte(Address%256);
	IIC_Wait_ACK();
	IIC_Write_byte(Byte);
	IIC_Wait_ACK();
	IIC_end();
	Delay_ms(10);  //等待缓存区数据存入内存
}

/*************************************************
*函数名:   AT24C02_Read_Byte
*函数功能: 读取一个字节的数据
*输入:     Address:要读取数据在AT24C02中的地址
*返回值:   Byte:读取的数据
**************************************************/
u8 AT24C02_Read_Byte(u8 Address)
{
	u8 Byte;
	IIC_start();
	IIC_Write_byte(AT24C02_Address);
	IIC_Wait_ACK();
	IIC_Write_byte(Address%256);
	IIC_Wait_ACK();
	IIC_start();
	IIC_Write_byte(AT24C02_Read_Address);
	IIC_Wait_ACK();
	Byte = IIC_Read_byte(0);
	IIC_end();
	return Byte;
}

/*************************************************
*函数名:   AT24C02_Write_Continue
*函数功能: 连续向AT24C02中写入number个字节数据
*输入:     Address:写入数据的起始地址,*data:写入数据的首地址,number:写入数据的个数
*返回值:   无
**************************************************/
void AT24C02_Write_Continue(u8 Address,u8 *data,u8 number)
{
	u8 i;
	for(i = 0;i < number;i++)
	{
		AT24C02_Write_Byte(Address+i,*(data+i));
	}
}

/*************************************************
*函数名:   AT24C02_Read_Continue
*函数功能: 连续向AT24C02中读取number个字节数据
*输入:     Address:读取数据的起始地址,*data:存放数据的首地址,number:读取数据的个数
*返回值:   无
**************************************************/
void AT24C02_Read_Continue(u8 Address,u8 *data,u8 number)
{
	u8 i;
	for(i = 0;i < number;i++)
	{
		*(data+i) = AT24C02_Read_Byte(Address+i);
	}
}

/*************************************************
*函数名:   AT24C02_check
*函数功能: 检查AT24C02是否正常
*输入:     无
*返回值:   无
**************************************************/
u8 AT24C02_check()
{
	u8 temp = AT24C02_Read_Byte(0xff);
	if(temp == 0x38) return 1;
	else
	{
		AT24C02_Write_Byte(0xff,0x38);
		temp = AT24C02_Read_Byte(0xff);
		if(temp == 0x38) return 1;
	}
	return 0;
}

/*************************************************
*函数名:   AT24C02_clear
*函数功能: 清空AT24C02内存放的数据
*输入:     无
*返回值:   无
**************************************************/
void AT24C02_clear()
{
	u8 a[256];
	u32 i;
	for(i = 0;i < 256;i++)
	{
		a[i] = 0xff;
	}
	AT24C02_Write_Continue(0,a,0xff);
}

2、实验效果

在这里插入图片描述

七、HAL库控制AT24C02

1、cubemx配置工程主要步骤


在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
④串口
在这里插入图片描述
⑤引脚
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2、实验程序

程序是根据标准库移植过来的。
iic.c

#include "iic.h"
#include "System.h"
#include "Delay.h"

#if DEBUG_IIC
#include "usart.h"
#include<stdio.h>
#endif

/*************************************************
*函数名:     IIC_Init
*函数功能:   IIC引脚初始化
*输入:       无
*返回值:     无
**************************************************/
void IIC_Init()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOB_CLK_ENABLE();

  HAL_GPIO_WritePin(GPIOB, IIC_SCL_Pin|IIC_SDA_Pin, GPIO_PIN_SET);

  GPIO_InitStruct.Pin = IIC_SCL_Pin|IIC_SDA_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
	
	SCL = 1;
	SDA_out = 1;
}

/*************************************************
*函数名:     IIC_OUT
*函数功能:   SDA引脚转为输出模式
*输入:       无
*返回值:     无
**************************************************/
void IIC_OUT()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.Pin = IIC_SDA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;  //推挽输出模式
	GPIO_InitStruct.Pull = GPIO_NOPULL;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

/*************************************************
*函数名:     IIC_IN
*函数功能:   SDA引脚转为输入模式
*输入:       无
*返回值:     无
**************************************************/
void IIC_IN()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	GPIO_InitStruct.Pin = IIC_SDA_Pin;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  //输入模式
	GPIO_InitStruct.Pull = GPIO_PULLUP;  //上拉
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

/*************************************************
*函数名:     IIC_start
*函数功能:   IIC起始信号
*输入:       无
*返回值:     无
**************************************************/
void IIC_start()
{
	IIC_OUT();    //SDA变为输出状态
	SCL = 1;
	SDA_out = 1;
	Delay_us(5);
	SDA_out = 0;
	Delay_us(5);
}

/*************************************************
*函数名:     IIC_end
*函数功能:   IIC停止信号
*输入:       无
*返回值:     无 
**************************************************/
void IIC_end()
{
	IIC_OUT();    //SDA变为输出状态
	SCL = 0;
	SDA_out = 0;
	SCL = 1;
	Delay_us(5);
	SDA_out = 1;
	Delay_us(5);
}

/*************************************************
*函数名:      IIC_ACK
*函数功能:    IIC主机发出应答信号
*输入:        无
*返回值:      无
**************************************************/
void IIC_ACK()
{
	IIC_OUT();    //SDA变为输出状态
	SCL = 0;
	SDA_out = 0;
	Delay_us(2);
	SCL = 1;
	Delay_us(5);
	SCL = 0;
}

/*************************************************
*函数名:       IIC_NACK
*函数功能:     IIC主机发出非应答信号
*输入:         无
*返回值:       无
**************************************************/
void IIC_NACK()
{
	IIC_OUT();   //SDA变为输出状态
	SCL = 0;
	SDA_out = 1;
	Delay_us(2);
	SCL = 1;
	Delay_us(5);
	SCL = 0;
}

/*************************************************
*函数名:       IIC_Wait_ACK
*函数功能:     主机等待应答信号
*输入:         无
*返回值:       1:接收到应答信号,0:非应答或者未接收到应答信号
**************************************************/
uint8_t IIC_Wait_ACK()
{
	uint8_t i;
	IIC_IN();   //SDA变为输入状态
	SCL = 1;
	while(SDA_in)
	{
		i++;
		if(i > 250)
		{
			IIC_end();
			#if DEBUG_IIC
				printf("未收到应答信号,IIC有误\r\n");
			#endif
			return 0;
		}
	}
  	SCL=0;  
	return 1; 
}

/*************************************************
*函数名:       IIC_Write_byte
*函数功能:     IIC写一个字节函数
*输入:         bit:写入的数据
*返回值:       无
**************************************************/
void IIC_Write_byte(uint8_t byte)
{
	uint8_t i;
	IIC_OUT();  //SDA变为输出状态
	SCL = 0;
	for(i = 0;i < 8;i++)
	{
		if(byte & 0x80)   //判断最高位,0x80 = 1000 0000
			SDA_out = 1;
		else
			SDA_out = 0;
		byte <<= 1;
		Delay_us(2);
		SCL = 1;
		Delay_us(2);
		SCL = 0;
		Delay_us(2);
	}
}

/*************************************************
*函数名:       IIC_Read_byte
*函数功能:     IIC读取一个字节的数据
*输入:         ACK:1-接收后给应答信号,0-接收后给非应答信号
*返回值:       BIt:读取的值
**************************************************/
uint8_t IIC_Read_byte(uint8_t ACK)
{
	uint8_t i,Bit;
	IIC_IN();   //SCL变为输入状态
	for(i = 0;i < 8;i++)
	{
		SCL = 0;
		Delay_us(2);
		SCL = 1;
		Bit <<= 1;
		if(SDA_in)
			Bit++;
	}
	if(ACK)
		IIC_ACK();
	else
		IIC_NACK();
	return Bit;
}

iic.h

#ifndef IIC_H_
#define IIC_H_


#include "main.h"

#define  DEBUG_IIC 0   //调试IIC开关


/************位带操作************/
#define SCL       PBout(6)
#define SDA_out   PBout(7)
#define SDA_in    PBin(7)

void IIC_Init(void);         //IIC引脚初始化
void IIC_start(void);        //IIC起始信号
void IIC_end(void);          //IIC停止信号
void IIC_ACK(void);          //IIC主机发出应答信号
void IIC_NACK(void);         //IIC主机发出非应答信号
uint8_t IIC_Wait_ACK(void);       //主机等待应答信号 
void IIC_Write_byte(uint8_t bit); //IIC写一个字节函数
uint8_t IIC_Read_byte(uint8_t ACK);    //IIC读取一个字节的数据

#endif

AT24C02.c

#include "AT24C02.h"
#include "iic.h"
#include "Delay.h"

/*************************************************
*函数名:    AT24C02_Init
*函数功能:  AT24C02初始化
*输入:      无
*返回值:    无
**************************************************/
void AT24C02_Init()
{
	IIC_Init();
}

/*************************************************
*函数名:   AT24C02_Write_Byte
*函数功能: 向AT24C02写一个字节的数据
*输入:     Address:AT24C02中存放数据的地址,Byte:存放的数据
*返回值:   无
**************************************************/
void AT24C02_Write_Byte(uint8_t Address,uint8_t Byte)
{
	IIC_start();
	IIC_Write_byte(AT24C02_Write_Address);
	IIC_Wait_ACK();
	IIC_Write_byte(Address%256);
	IIC_Wait_ACK();
	IIC_Write_byte(Byte);
	IIC_Wait_ACK();
	IIC_end();
	Delay_ms(10);  //等待缓存区数据存入内存
}

/*************************************************
*函数名:   AT24C02_Read_Byte
*函数功能: 读取一个字节的数据
*输入:     Address:要读取数据在AT24C02中的地址
*返回值:   Byte:读取的数据
**************************************************/
uint8_t AT24C02_Read_Byte(uint8_t Address)
{
	uint8_t Byte;
	IIC_start();
	IIC_Write_byte(AT24C02_Address);
	IIC_Wait_ACK();
	IIC_Write_byte(Address%256);
	IIC_Wait_ACK();
	IIC_start();
	IIC_Write_byte(AT24C02_Read_Address);
	IIC_Wait_ACK();
	Byte = IIC_Read_byte(0);
	IIC_end();
	return Byte;
}

/*************************************************
*函数名:   AT24C02_Write_Continue
*函数功能: 连续向AT24C02中写入number个字节数据
*输入:     Address:写入数据的起始地址,*data:写入数据的首地址,number:写入数据的个数
*返回值:   无
**************************************************/
void AT24C02_Write_Continue(uint8_t Address,uint8_t *data,uint8_t number)
{
	uint8_t i;
	for(i = 0;i < number;i++)
	{
		AT24C02_Write_Byte(Address+i,*(data+i));
	}
}

/*************************************************
*函数名:   AT24C02_Read_Continue
*函数功能: 连续向AT24C02中读取number个字节数据
*输入:     Address:读取数据的起始地址,*data:存放数据的首地址,number:读取数据的个数
*返回值:   无
**************************************************/
void AT24C02_Read_Continue(uint8_t Address,uint8_t *data,uint8_t number)
{
	uint8_t i;
	for(i = 0;i < number;i++)
	{
		*(data+i) = AT24C02_Read_Byte(Address+i);
	}
}

/*************************************************
*函数名:   AT24C02_check
*函数功能: 检查AT24C02是否正常
*输入:     无
*返回值:   无
**************************************************/
uint8_t AT24C02_check()
{
	uint8_t temp = AT24C02_Read_Byte(0xff);
	if(temp == 0x38) return 1;
	else
	{
		AT24C02_Write_Byte(0xff,0x38);
		temp = AT24C02_Read_Byte(0xff);
		if(temp == 0x38) return 1;
	}
	return 0;
}

/*************************************************
*函数名:   AT24C02_clear
*函数功能: 清空AT24C02内存放的数据
*输入:     无
*返回值:   无
**************************************************/
void AT24C02_clear()
{
	uint8_t a[256];
	uint32_t i;
	for(i = 0;i < 256;i++)
	{
		a[i] = 0xff;
	}
	AT24C02_Write_Continue(0,a,0xff);
}

AT24C02.h

#ifndef AT24C02_H_
#define AT24C02_H_


#include "stm32f1xx_hal.h"


/************设备地址************/
#define AT24C02_Address        0xA0  //EEPROM设备地址,1010 0000
#define AT24C02_Write_Address  0xA0  //EEPROM写地址,1010 0000+0000 0000
#define AT24C02_Read_Address   0xA1  //EEPROM读地址,1010 0000+0000 0001

/************内存地址是0x00~0xff************/

void AT24C02_Init(void);    //AT24C02初始化
void AT24C02_Write_Byte(uint8_t Address,uint8_t Byte);  //对AT24C02写一个字节的数据
uint8_t AT24C02_Read_Byte(uint8_t Address);   //对AT24C02读一个字节的数据
void AT24C02_Write_Continue(uint8_t Address,uint8_t *data,uint8_t number);  //连续写n个字节的数据
void AT24C02_Read_Continue(uint8_t Address,uint8_t *data,uint8_t number);  //连续读n个字节的数据
uint8_t AT24C02_check(void);   //AT24C02检测
void AT24C02_clear(void);  //清空AT24C02的数据

#endif

usart.c
在这里插入图片描述

#include<stdio.h>
/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  * 输入参数: 无
  * 返 回 值: 无
  * 说    明:无
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}

main.c
在这里插入图片描述

#include "AT24C02.h"
#include "Delay.h"
#include<stdio.h>

在这里插入图片描述

SysTick_Init(72);
AT24C02_Init();
	while(!AT24C02_check())  //检测AT24C02是否正常
	{
		printf("AT24C02检测不正常!\r\n");
		Delay_ms(500);
	}
	printf("AT24C02检测正常!\r\n");	
	AT24C02_clear();   //清空一下数据
	static uint8_t i = 0,a[5] = {7,8,3,4,5},b[5];
	AT24C02_Write_Continue(0,a,5);   //连续写入4个数据
	AT24C02_Read_Continue(0,b,5);  //读出4个数据
		for(i = 0;i < 5;i++)           //通过串口打印在电脑上
			{
				printf("读出的数据为 %d\r\n",b[i]);
			}
		break;

3、实验效果

在这里插入图片描述
到这里就结束啦!
在这里插入图片描述

  • 14
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论
在使用HAL库进行STM32IIC读写AT24C02时,你可以参考以下步骤: 1. 首先,你需要在你的工程中包含AT24CXX.c文件,并在代码中引用该文件。该文件中定义了一些常量和函数,用于初始化AT24CXX芯片、写入数据和读取数据等操作。 2. 在AT24CXX.c文件中,你可以看到定义了一些常量,如AT24C02的地址为255。这些常量可以根据你所使用的芯片型号进行修改。 3. 在AT24CXX.c文件中,还定义了一些函数,如AT24CXX_Init()用于初始化AT24CXX芯片,AT24CXX_Write()用于写入数据,AT24CXX_Read()用于读取数据,AT24CXX_Check()用于检查AT24CXX芯片是否正常工作。你可以根据需要调用这些函数来实现对AT24C02读写操作。 4. 在配置STM32的引脚时,你需要将IIC的引脚与AT24C02芯片的引脚相连接。具体的引脚配置可以参考AT24CXX.c文件中的注释。 5. 在配置串口时,你可以选择使用串口进行数据查看,以便调试和验证读写操作的结果。 6. 最后,根据你的需求选择适当的时钟频率,生成Keil工程代码。 综上所述,你可以使用HAL库的函数和AT24CXX.c文件中定义的函数来实现对AT24C02芯片的读写操作。 #### 引用[.reference_title] - *1* *3* [STM32 (基于HAL库) 硬件IIC读写任意AT24CXX芯片](https://blog.csdn.net/weixin_56565733/article/details/124401443)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32系列(HAL库)——F103C8T6通过IIC/I2C方式读写AT24C02—(EEPROM 存储模块)](https://blog.csdn.net/lwb450921/article/details/124394615)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^koosearch_v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

修成真

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值