STM32F4单片机读取AT24c02
STM32F4是由ST(意法半导体)开发的一种高性能微控制器系列。其采用了90nm的NVM工艺和ART技术(自适应实时存储加速器,Adaptive Real-Time MemoryAccelerator™)
AT24C02是Atmel公司出品的一个2K位串行CMOS E2PROM, 内部含有256个8位字节,CATALYST公司的先进CMOS技术实质上减少了器件的功耗。AT24C02有一个16字节页写缓冲器。该器件通过IIC总线接口进行操作,有一个专门的写保护功能。
而本例用到的开发平台是keil uvision5。
目录
一、先介绍几个概念
1、E2PROM
2、FLASH
3、I²C
4、E2PROM和FLASH两者的区别
(1)FLASH是内部存储器
(2)AT24C02是外部存储器
二、原理图
三、代码
1、main.c
2、24cxx.c
3、IIC
一、先介绍几个概念
1、E2PROM
E2PROM,也就是EEPROM (Electrically Erasable Programmable Read-Only Memory),中文名叫电可擦可编程只读存储器,是一种掉电后数据不丢失的存储芯片。AT24C02就似乎E2PROM的一种型号。
2、FLASH
flash是存储芯片的一种,通过特定的程序可以修改里面的数据。FLASH在电子以及半导体领域内往往表示Flash Memory的意思,即平时所说的“闪存”,全名叫Flash EEPROM Memory。
flash存储器又称闪存,它结合了ROM和RAM的长处,不仅具备电子可擦除可编程(EEPROM)的性能,还可以快速读取数据(NVRAM的优势),使数据不会因为断电而丢失。
3、I²C
I²C(Inter-Integrated Circuit)是内部整合电路的称呼,是一种串行通讯总线,使用多主从架构,由飞利浦公司在1980年代为了让主板、嵌入式系统或手机用以连接低速周边装置而发展。I²C(读作"I-squared-C" ),还有可选的拼写方式是I2C(读作I-two-C)以及IIC(读作I-I-C),在中国则多以"I方C"称之。I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。
4、E2PROM和FLASH两者的区别
(1)FLASH是内部存储器
stm32f4系列单片机内部集成了FLASH,FLASH是用于存储程序代码的,有些场合也可能用它来保存数据,当然前提是该单片机的FLASH工艺是可以自写的(运行中可擦写),但要注意FLASH的擦写次数通常小于一万次,而且通常FLASH只能按块擦除。FLSAH则必须先擦除成BLANK,然后再写入,而一般没有单字节擦除的功能,至少一个扇区擦除。
(2)AT24C02是外部存储器
AT24C02是单独的一个芯片,用于存放擦除次数较多的数据读写。AT24C02支持I2C总线数据传送协议。AT24C02这种EEPROM不能用来存程序,通常单片机的指令寻址不能到这个区域。EEPROM的擦写次数应有百万次,而且可以按字节擦写。EEPROM在一个PAGE内是可以任意写的,可以按字节擦除。所以,如果有频繁的擦除需求,比如要记录某个实时变化的数据,那么就需要把数据存到EEPROM中。
二、原理图
SCL接stm32f407的PB8,SDA接PB9。
三、代码
1、main.c
本例程代码包含4部分:at24c02的初始化、检测、写数据和读数据。
int main(void)
{char At24c02_status=1;int i;
int read_num;//初始化
AT24CXX_Init();NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168); //初始化延时函数
uart_init(115200);//初始化串口波特率为115200//检测at24c02是否正常
At24c02_status=AT24CXX_Check(save_num);//如果at24c02正常,则进行读写
if(At24c02_status){//写入数据for(i=0;i<8;i++){AT24CXX_WriteOneByte(i,i);}//读取数据for(i=0;i<8;i++){read_num=AT24CXX_ReadOneByte(i);printf("%d\r\n",read_num);}
}
else
{printf("at24c02 error!");//报错信息
}}
2、24cxx.c
#include "24cxx.h"
#include "delay.h"/*******************************************************************************
* 函 数 名 : AT24CXX_Init
* 函数功能 : AT24CXX初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void AT24CXX_Init(void)
{IIC_Init();//IIC初始化
}/*******************************************************************************
* 函 数 名 : AT24CXX_ReadOneByte
* 函数功能 : 在AT24CXX指定地址读出一个数据
* 输 入 : ReadAddr:开始读数的地址
* 输 出 : 读到的数据
*******************************************************************************/
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{ u8 temp=0; IIC_Start(); if(EE_TYPE>AT24C16){IIC_Send_Byte(0XA0); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(ReadAddr>>8);//发送高地址 }else {IIC_Send_Byte(0XA0+((ReadAddr/256)<<1)); //发送器件地址0XA0,写数据} IIC_Wait_Ack(); IIC_Send_Byte(ReadAddr%256); //发送低地址IIC_Wait_Ack(); IIC_Start(); IIC_Send_Byte(0XA1); //进入接收模式 IIC_Wait_Ack(); temp=IIC_Read_Byte(0); IIC_Stop();//产生一个停止条件 return temp;
}/*******************************************************************************
* 函 数 名 : AT24CXX_WriteOneByte
* 函数功能 : 在AT24CXX指定地址写入一个数据
* 输 入 : WriteAddr :写入数据的目的地址 DataToWrite:要写入的数据
* 输 出 : 无
*******************************************************************************/
void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
{ IIC_Start(); if(EE_TYPE>AT24C16){IIC_Send_Byte(0XA0); //发送写命令IIC_Wait_Ack();IIC_Send_Byte(WriteAddr>>8);//发送高地址 }else {IIC_Send_Byte(0XA0+((WriteAddr/256)<<1)); //发送器件地址0XA0,写数据} IIC_Wait_Ack(); IIC_Send_Byte(WriteAddr%256); //发送低地址IIC_Wait_Ack(); IIC_Send_Byte(DataToWrite); //发送字节 IIC_Wait_Ack(); IIC_Stop();//产生一个停止条件 delay_ms(10);
}/*******************************************************************************
* 函 数 名 : AT24CXX_WriteLenByte
* 函数功能 : 在AT24CXX里面的指定地址开始写入长度为Len的数据用于写入16bit或者32bit的数据
* 输 入 : WriteAddr :写入数据的目的地址 DataToWrite:要写入的数据Len :要写入数据的长度2,4
* 输 出 : 无
*******************************************************************************/
void AT24CXX_WriteLenByte(u16 WriteAddr,u32 DataToWrite,u8 Len)
{ u8 t;for(t=0;t<Len;t++){AT24CXX_WriteOneByte(WriteAddr+t,(DataToWrite>>(8*t))&0xff);}
}/*******************************************************************************
* 函 数 名 : AT24CXX_ReadLenByte
* 函数功能 : 在AT24CXX里面的指定地址开始读出长度为Len的数据用于读出16bit或者32bit的数据
* 输 入 : ReadAddr :开始读出的地址 Len :要读出数据的长度2,4
* 输 出 : 读取的数据
*******************************************************************************/
u32 AT24CXX_ReadLenByte(u16 ReadAddr,u8 Len)
{ u8 t;u32 temp=0;for(t=0;t<Len;t++){temp<<=8;temp+=AT24CXX_ReadOneByte(ReadAddr+Len-t-1); }return temp;
}/*******************************************************************************
* 函 数 名 : AT24CXX_Check
* 函数功能 : 检查AT24CXX是否正常
* 输 入 : 无
* 输 出 : 1:检测成功,0:检测失败
*******************************************************************************/
u8 AT24CXX_Check(u8 savenum)
{u8 temp;u8 save_num=0x48;temp=AT24CXX_ReadOneByte(255);//避免每次开机都写AT24CXX if(temp==savenum)return 1; else//排除第一次初始化的情况{AT24CXX_WriteOneByte(255,savenum);temp=AT24CXX_ReadOneByte(255); if(temp==savenum)return 1;}return 0;
}/*******************************************************************************
* 函 数 名 : AT24CXX_Read
* 函数功能 : 在AT24CXX里面的指定地址开始读出指定个数的数据
* 输 入 : ReadAddr :开始读出的地址 对24c02为0~255pBuffer :数据数组首地址NumToRead:要读出数据的个数
* 输 出 : 无
*******************************************************************************/
void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
{while(NumToRead){*pBuffer++=AT24CXX_ReadOneByte(ReadAddr++); NumToRead--;}
} /*******************************************************************************
* 函 数 名 : AT24CXX_Write
* 函数功能 : 在AT24CXX里面的指定地址开始写入指定个数的数据
* 输 入 : WriteAddr :开始写入的地址 对24c02为0~255pBuffer :数据数组首地址NumToRead:要读出数据的个数
* 输 出 : 无
*******************************************************************************/
void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
{while(NumToWrite--){AT24CXX_WriteOneByte(WriteAddr,*pBuffer);WriteAddr++;pBuffer++;}
}
3、IIC
#include "iic.h"
#include "SysTick.h"/*******************************************************************************
* 函 数 名 : IIC_Init
* 函数功能 : IIC初始化
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Init(void)
{GPIO_InitTypeDef GPIO_InitStructure;RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能 GPIOB 时钟//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);//使能 GPIOB 时钟//GPIOB8,B9初始化设置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化//GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化IIC_SCL=1;IIC_SDA=1;
}/*******************************************************************************
* 函 数 名 : SDA_OUT
* 函数功能 : SDA输出配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void SDA_OUT(void)
{GPIO_InitTypeDef GPIO_InitStructure;//GPIOB9初始化设置GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
}/*******************************************************************************
* 函 数 名 : SDA_IN
* 函数功能 : SDA输入配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void SDA_IN(void)
{GPIO_InitTypeDef GPIO_InitStructure;//GPIOB9初始化设置GPIO_InitStructure.GPIO_Pin =GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//输入模式GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化
}/*******************************************************************************
* 函 数 名 : IIC_Start
* 函数功能 : 产生IIC起始信号
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Start(void)
{SDA_OUT(); //sda线输出IIC_SDA=1; IIC_SCL=1;delay_us(5);IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(6);IIC_SCL=0;//钳住I2C总线,准备发送或接收数据
} /*******************************************************************************
* 函 数 名 : IIC_Stop
* 函数功能 : 产生IIC停止信号
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Stop(void)
{SDA_OUT();//sda线输出IIC_SCL=0;IIC_SDA=0;//STOP:when CLK is high DATA change form low to highIIC_SCL=1; delay_us(6); IIC_SDA=1;//发送I2C总线结束信号delay_us(6);
}/*******************************************************************************
* 函 数 名 : IIC_Wait_Ack
* 函数功能 : 等待应答信号到来
* 输 入 : 无
* 输 出 : 1,接收应答失败0,接收应答成功
*******************************************************************************/
u8 IIC_Wait_Ack(void)
{u8 tempTime=0;SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA){tempTime++;if(tempTime>250){IIC_Stop();return 1;}}IIC_SCL=0;//时钟输出0 return 0;
} /*******************************************************************************
* 函 数 名 : IIC_Ack
* 函数功能 : 产生ACK应答
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_Ack(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=0;delay_us(2);IIC_SCL=1;delay_us(5);IIC_SCL=0;
}/*******************************************************************************
* 函 数 名 : IIC_NAck
* 函数功能 : 产生NACK非应答
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void IIC_NAck(void)
{IIC_SCL=0;SDA_OUT();IIC_SDA=1;delay_us(2);IIC_SCL=1;delay_us(5);IIC_SCL=0;
} /*******************************************************************************
* 函 数 名 : IIC_Send_Byte
* 函数功能 : IIC发送一个字节
* 输 入 : txd:发送一个字节
* 输 出 : 无
*******************************************************************************/
void IIC_Send_Byte(u8 txd)
{ u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输for(t=0;t<8;t++){ if((txd&0x80)>0) //0x80 1000 0000IIC_SDA=1;elseIIC_SDA=0;txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的IIC_SCL=1;delay_us(2); IIC_SCL=0; delay_us(2);}
} /*******************************************************************************
* 函 数 名 : IIC_Read_Byte
* 函数功能 : IIC读一个字节
* 输 入 : ack=1时,发送ACK,ack=0,发送nACK
* 输 出 : 应答或非应答
*******************************************************************************/
u8 IIC_Read_Byte(u8 ack)
{u8 i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){IIC_SCL=0; delay_us(2);IIC_SCL=1;receive<<=1;if(READ_SDA)receive++; delay_us(1); } if (!ack)IIC_NAck();//发送nACKelseIIC_Ack(); //发送ACK return receive;
}
注意:本例只给出了核心的函数,其中调用的一些stm32f4xx的基本函数库和头文件没有贴上来,需要把相关库函数和头文件都包含进去才可以调试成功。
(全文结束)
STM32F4单片机读取AT24c02相关推荐
- STM32F4单片机读取光电编码器的小理解
STM32F4单片机读取光电编码器的小理解 大家好! 我是木兔同学,这是我第一次发CSDN的博客,本人接触的单片机主要是STM32f407,今天谈一谈STM32F4单片机读取光电编码器的小理解,希望大 ...
- 基于STM32F4单片机对步进电机的控制(有代码)
步进电机简介 步进电机是将电脉冲控制信号转变为角位移或线位移的一种常用的数字控制执行元件,又称为脉冲电机.在驱动电源的作用下,步进电机受到脉冲的控制,其转子的角位移量和速度严格地与输入脉冲的数量和脉冲 ...
- I2C总线原理和应用实例(51单片机和AT24C02的I2C通讯)
1. I2C简介 I2C(Inter-Integrated Circuit:内部集成电路)总线是由Philips公司开发的一种简单.双向二线制同步串行总线.(来源于百度百科) 总结其主要特点如下: 只 ...
- STM32F407单片机读取USR-WIFI232-B2模块的MAC地址
最近工程项目需要单片机读取USR-WIFI232-B2(WIFI)模块的MAC地址,研究了一下,并成功获取了MAC地址.步骤如下: 1.单片机上电.USR-WIFI232-B2(WIFI)模块先延时1 ...
- 【51单片机】AT24C02存储器(I²C总线)/DS18B20温度传感器(单总线)
目录 一.AT24C02存储器 1.AT24C02存储器介绍 2.存储器简化模型 3.AT24C02存储器原理图 二.I²C总线 1.I²C总线的介绍 2.I²C电路 3.I²C时序图 3.1I²C开 ...
- 【STM32】HAL库 STM32CubeMX教程十二---IIC(读取AT24C02 )
前言: 本系列教程将HAL库与STM32CubeMX结合在一起讲解,使您可以更快速的学会各个模块的使用 在之前的标准库中,STM32的硬件IIC非常复杂,更重要的是它并不稳定,所以都不推荐使用. 但是 ...
- STC单片机对AT24C02进行数据读写操作
STC单片机对AT24C02进行数据读写操作
- c语言AT源码,51单片机读写AT24C02源代码(详细注释)
在P1口上接八个led灯,结果就显示在这八个灯上面.AT24C02的接线方式见程序的顶部的定义.以下是源代码: #include //包含头文件 typedef unsigned char uchar ...
- 三、单片机读取ID卡(EM4100的数据格式)
目录 一.单片机读取ID卡(工作原理及电路) 二.单片机读取ID卡(产生载波) 三.单片机读取ID卡(EM41000的数据格式) 四.单片机读取ID卡(硬件调试及读码) (一)EM4100的数据格式 ...
最新文章
- MongoDB在windows服务器安装部署及远程连接MongoDB
- 第四百一十六天 how can I 坚持
- PendingIntent与Intent区别
- 深度解读 MongoDB 4.4 新特性
- [Kubernetes] 如何关联PVC到特定的PV
- 【华为云技术分享】基于自动机器学习的心脏病预测模型(1)
- mongodb日志分析工具mtools之mplotqueries
- mod_signalwire.c:371 Curl Result 1, Error: Protocol https not supported
- 刷机-升级到4.01M33-2的方法
- matlab的实时编辑器介绍以及应用示例
- JavaScript九宫格数独生成算法
- oracle 19c jdbc之Reactive Streams Ingestion (RSI) Library
- 【调剂】2020年西安建筑科技大学考研调剂信息(含接收专业)
- TVS (瞬态二极管)
- 笔记本玩游戏画面间歇卡顿的终极解决方案 ThrottleStop使用教程
- win10快速删除文件cmd命令
- QPainter 绘制圆角矩形 drawRoundRect详解
- Exchange 2010 升级到Exchange 2016 之 Exchange 2016安装
- 伺服CAN总线设计(电工Demo)
- hy3208中文参数_HY-MOSFET-产品目录表