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

  • 一、前言
  • 二、准备工作
  • 三、AT24C02(EEPROM)介绍
    • 1、AT24C02简介
    • 2、引脚功能
    • 3、设备地址
  • 四、硬件电路图
  • 五、数据传输过程
    • 1、写入数据
    • 2、读入数据
  • 六、标准库控制AT24C02
    • 1、实验程序
    • 2、实验效果
  • 七、HAL库控制AT24C02
    • 1、cubemx配置工程主要步骤
    • 2、实验程序
    • 3、实验效果

一、前言

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

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

二、准备工作

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

三、AT24C02(EEPROM)介绍

1、AT24C02简介

AT24C02是EEPROM储存器的一种,其内部可存储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_IICprintf("未收到应答信号,IIC有误\r\n");#endifreturn 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 0000SDA_out = 1;elseSDA_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();elseIIC_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_IICprintf("未收到应答信号,IIC有误\r\n");#endifreturn 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 0000SDA_out = 1;elseSDA_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();elseIIC_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、实验效果


到这里就结束啦!

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

  1. 【STM32】STM32标准库与HAL库对照学习教程一--使用寄存器操控LED闪烁详讲

    [STM32]STM32标准库与HAL库对照学习教程一--使用寄存器操控LED闪烁详讲 前言 本教程文章是我在学习STM32标准库和HAL库后写的,想通过标准库与HAL库的对照学习加强我对STM32的 ...

  2. 【STM32】标准库与HAL库对照学习教程六--位带操作

    [STM32]标准库与HAL库对照学习教程六--位带操作 一.前言 二.准备工作 三.位带介绍 1.位带操作 2.STM32位带及位带别名区域 四.位带区与位带别名区地址转换 五.GPIO的位带操作 ...

  3. 【STM32】标准库与HAL库对照学习教程八--串口通信详解

    [STM32]标准库与HAL库对照学习教程八--串口通信详解 一.前言 二.准备工作 三.通信的基本概念 1.通信方式 2.串行通信与并行通信 (1)串行通信 (2)并行通信 3.异步通信与同步通信 ...

  4. 【STM32】标准库与HAL库对照学习教程外设篇--红外避障传感器

    [STM32]标准库与HAL库对照学习教程外设篇--红外避障传感器 一.前言 二.准备工作 三.红外避障传感器 1.传感器原理说明 2.传感器特性 四.标准库使用红外传感器 1.实验程序 2.实验效果 ...

  5. 【STM32】STM32标准库与HAL库对照学习教程特别篇--系统时钟RCC详讲

    [STM32]STM32标准库与HAL库对照学习教程特别篇--系统时钟RCC详讲 一.前言 二.时钟是什么 三.时钟树 1.时钟树图 2.时钟树讲解 左边部分 中间部分 右边部分 特殊部分 四.初始化 ...

  6. 【STM32】标准库与HAL库对照学习教程外设篇--超声波测距传感器

    [STM32]标准库与HAL库对照学习教程外设篇--超声波测距传感器 一.前言 二.准备工作 三.超声波测距传感器 1.原理说明 2.使用说明 四.标准库使用传感器 1.实验程序 2.实验效果 五.H ...

  7. 【STM32学习】(29)STM32实现595驱动三个数码管(标准库和HAL库实现)

    我选用的单片机型号为:STM32F103系列 74LS595是一个串转并行输出的芯片,它能为单片机节省很多的IO口,应用场景广泛. 现要求三个数码管动态显示,常规设计都是并行实现,需要8个IO数据口, ...

  8. 【STM32学习】(30)STM32实现18B20温度采集(标准库和HAL库实现)

    单片机型号:STM32F103 源码下载链接:(2条消息) STM32实现18B20温度采集(标准库和HAL库实现)-电信文档类资源-CSDN下载 现要求完成温度采集并在串口或液晶屏上显示.我们这里使 ...

  9. STM32标准库、HAL库特点与应用

    新手在入门STM32的时候,一般大多数都会选用标准库和HAL库,而极少部分人会通过直接配置寄存器进行开发. 对于刚入门的朋友可能没法直观了解这些不同开发发方式彼此之间的区别,本文试图以一种非常直白的方 ...

最新文章

  1. python在word中的应用_不能在worddoc中使用docx python应用表样式
  2. 19.04.27--作业 打字游戏
  3. iOS - 在UITextField外部触摸时关闭键盘
  4. Linux 开发板4G转WiFi热点 手机连接热点上网(一 思路)
  5. Solr增删改查索引
  6. 总结缓存使用过程中的几种策略以及优缺点组合分析
  7. java map null吗_Java: Map里面的键和值可以为空吗?
  8. Python爬虫大杀器之Requests快速入门
  9. sklearn查看数据
  10. SpringBoot配置RunDashboard
  11. HTML 5参考手册
  12. java成员变量覆盖_java-成员变量的属性与成员函数的覆盖
  13. Spring.NET学习笔记16——事务管理(应用篇) Level 200
  14. 单元测试、集成测试、系统测试和验收测试、冒烟测试、回归测试、随机测试、探索性测试和安全测试
  15. Linux tar压缩文件夹,排除该文件夹下的某些文件夹或文件
  16. 午夜与element-ui邂逅
  17. 2010年最新世博攻略
  18. 待定系数法求二阶常系数非齐次线性方程特解
  19. tcpdump win
  20. 逻辑思维不强的适合学java嘛_逻辑思维能力的培养很重要吗

热门文章

  1. 发送手机短信获取验证码功能
  2. 1588分析和实现总纲
  3. 人际关系-《吸引力是这样炼成的》书中的精髓:掌握7个人际交往技能,收获丰富多彩的人生。
  4. 苹果战略管理分析_苹果不懈的战略与执行
  5. 子桓说:学几招商业套路,以后用的上!
  6. 海康接口开发之访客登记(一) 获取人员信息
  7. android系统删除应用程序,手机系统自带软件怎么卸载?苹果/安卓软件卸载攻略...
  8. ​ 谁说 14 英寸没有好屏幕 — MateBook 14 评测
  9. 【MySQL】MySQL表的增删改查(进阶)
  10. Martin Fowler先生关于持续集成的一篇文章