(2)创建at24cxx.c文件并输入以下代码。
/*********************************************************************************************************
EEPROM 驱 动 程 序
*********************************************************************************************************/
#include "at24cxx.h"
#include "delay.h"
/***************************************************
Name :IIC_Write_Data
Function :写入1个数据
Paramater :
Address:地址
Byte:读取的字节
Return :None
***************************************************/
void IIC_Write_Data( u8 Address, u8 Byte )
{
u16 Time, tmpreg ;
tmpreg = tmpreg ;
//等待BUSY标志置0
Time = 0 ;
while( ( ( I2C1->SR2&0x02 )==0x02 )&&( Time<65535 ) )
Time ++ ;
I2C1->CR1 &= ~( 1<<11 ) ; //禁用Pos
I2C1->CR1 |= 1<<8 ; //开始信号
//等待SB标志置1
Time = 0 ;
while( ( ( I2C1->SR1&0x01 )==0 )&&( Time<65535 ) )
Time ++ ;
I2C1->DR = 0xA0 ; //发送从机地址
//等待地址发送结束
Time = 0 ;
while( ( ( I2C1->SR1&0x02 )==0 )&&( Time<65535 ) )
{
Time ++ ;
if( ( I2C1->SR1&0x400 )==0x400 )
{
I2C1->SR1 &= ~( 1<<10 ) ; //清除AF标志
I2C1->CR1 |= 1<<9 ; //结束信号
break ;
}
}
tmpreg = I2C1->SR1 ; //清除地址标志
tmpreg = I2C1->SR2 ;
//等待TXE标志置0
Time = 0 ;
while( ( ( I2C1->SR2&0x04)==0 )&&( Time<65535 ) )
{
Time ++ ;
//检查是否检测到NACK
if( ( I2C1->SR1&0x400 )==0x400 )
{
I2C1->SR1 &= ~( 1<<10 ) ;
I2C1->CR1 |= 1<<9 ; //结束信号
break ;
}
}
I2C1->DR = Address ; //发送寄存器地址
//等待TXE标志置1
Time = 0 ;
while( ( ( I2C1->SR1&0x80 )==0 )&&( Time<65535 ) )
{
Time ++ ;
//检查是否检测到NACK
if( ( I2C1->SR1&0x400 )==0x400 )
{
I2C1->SR1 &= ~( 1<<18 ) ; //清除NACKF标志
I2C1->CR1 |= 1<<9 ; //结束信号
break ;
}
}
I2C1->DR = Byte ; //发送数据
//等待BTF标志被置1
Time = 0 ;
while( ( ( I2C1->SR1&0x04 )==0 )&&( Time<65535 ) )
{
Time ++ ;
//检查是否检测到NACK
if( ( I2C1->SR1&0x400 )==0x400 )
{
I2C1->SR1 &= ~( 1<<10 ) ; //清除NACKF标志
I2C1->CR1 |= 1<<9 ; //结束信号
break ;
}
}
I2C1->CR1 |= 1<<9 ; //结束信号
delay_ms( 10 ) ;
}
/***************************************************
Name :IIC_Read_Data
Function :读取1个数据
Paramater :
Address:地址
Return :读取的数据
***************************************************/
void IIC_Read_Data( u8 Address, u8 *Data )
{
u16 tmpreg, Time;
tmpreg = tmpreg ;
//等待BUSY标志置0
Time = 0 ;
while( ( ( I2C1->SR1&0x02 )==0x02 )&&( Time<65535 ) )
Time ++ ;
I2C1->CR1 &= ~( 1<<11 ) ; //禁用Pos
//发送从机地址
I2C1->CR1 |= 1<<8 ; //开始信号
Time = 0 ;
//等待SB标志置1
while( ( ( I2C1->SR1&0x01 )==0 )&&( Time<65535 ) )
Time ++ ;
I2C1->DR = 0xA0 ; //发送从机地址
//等待地址发送结束
while( ( ( I2C1->SR1&0x02 )==0 )&&( Time<65535 ) )
{
if( ( I2C1->SR1&0x400 )==0x400 )
{
I2C1->SR1 &= ~( 1<<10 ) ; //清除AF标志
I2C1->CR1 |= 1<<9 ; //停止信号
break ;
}
}
tmpreg = I2C1->SR1; //清除ADDR标志
tmpreg = I2C1->SR2;
//等待TXE标志置1
while( ( ( I2C1->SR1&0x80 )==0 )&&( Time<65535 ) )
{
//检查是否检测到NACK
if( ( I2C1->SR1&0x400)==0x400 )
{
I2C1->SR1 &= ~( 1<<10 ) ; //清除NACKF标志
I2C1->CR1 |= 1<<9 ; //通用结束
break ;
}
}
I2C1->DR = Address ; //写入数据
//等待BTF标志置1
while( ( ( I2C1->SR1&0x04 )==0 )&&( Time<65535 ) )
{
//检查是否检测到NACK
if( ( I2C1->SR1&0x400)==0x400 )
{
I2C1->SR1 &= ~( 1<<10 ) ; //清除NACKF标志
I2C1->CR1 |= 1<<9 ; //通用结束
break ;
}
}
I2C1->CR1 |= 1<<9 ; //通用结束
//等待忙标志退出
Time = 0 ;
while( ( ( I2C1->SR1&0x02 )==0x02 )&&( Time<65535 ) )
Time ++ ;
I2C1->CR1 &= ~( 1<<11 ) ; //禁用Pos
//发送从机地址
I2C1->CR1 |= 1<<10 ; //开启应答信号
I2C1->CR1 |= 1<<8 ; //开始信号
//等待SB标志置1
Time = 0 ;
while( ( ( I2C1->SR1&0x01 )==0 )&&( Time<65535 ) )
Time ++ ;
I2C1->DR = 0xA1 ; //发送从机地址
//等待地址标志置1
while( ( ( I2C1->SR1&0x02 )==0 )&&( Time<65535 ) )
{
Time ++ ;
//检查是否检测到STOPF
if( ( I2C1->SR1&0x10 )==0x10 )
{
I2C1->SR1 &= ~( 1<<4 ) ; //清除停止标志
break ;
}
}
I2C1->CR1 &= ~( 1<<10 ) ; //禁止应答
tmpreg = I2C1->SR1; //清除ADDR标志
tmpreg = I2C1->SR2;
I2C1->CR1 |= 1<<9 ; //通用应答
//等待直到RXNE标志置1
Time = 0 ;
while( ( ( I2C1->SR1&0x40 )==0 )&&( Time<65535 ) )
{
Time ++ ;
//检查是否检测到STOPF
if( ( I2C1->SR1&0x10 )==0x10 )
{
I2C1->SR1 &= ~( 1<<4 ) ; //清除停止标志
break ;
}
}
*Data = I2C1->DR ; //从DR读取数据
}
/***************************************************
Name :AT24Cxx_Write_nData
Function :写入n个数据
Paramater :
Address:地址
*Buffer:数据缓存
Len:数据长度
Return :None
***************************************************/
void AT24Cxx_Write_nData( u16 Address, u8 *Buffer, u16 Len )
{
u16 i ;
for( i=0; i/***************************************************
Name :AT24Cxx_Read_nData
Function :读取n个数据
Paramater :
Address:地址
*Buffer:数据缓存
Len:数据长度
Return :None
***************************************************/
void AT24Cxx_Read_nData( u16 Address, u8 *Buffer, u16 Len )
{
u16 i ;
for( i=0; i/***************************************************
Name :AT24Cxx_Check
Function :检查AT24C是否正常
Paramater :None
Return :
0:成功
1:失败
***************************************************/
u8 AT24Cxx_Check()
{
u8 Data ;
IIC_Read_Data( 255, &Data ) ;
if( Data!=0x55 )
{
IIC_Write_Data( 255, 0x55 ) ;
IIC_Read_Data( 255, &Data ) ;
if( Data!=0x55 )
return 0 ;
}
return 1 ;
}
/***************************************************
Name :AT24Cxx_Init
Function :AT24C初始化
Paramater :None
Return :None
***************************************************/
void AT24Cxx_Init()
{
RCC->APB2ENR |= 1<<3 ; //先使能外设GPIOB时钟
GPIOB->CRL &= 0x00FFFFFF ; //PB6和PB7推挽输出
GPIOB->CRL |= 0xFF000000 ;
RCC->APB1ENR |= 1<<21 ;
I2C1->CR1 |= 1<<15 ;
I2C1->CR1 &= ~( 1<<15 ) ;
I2C1->CR1 &= 1<<0 ; //关闭I2C模块
I2C1->CR2 &= ~( 3<<0 ) ;
I2C1->CR2 |= 16<<0 ; //I2C频率范围
I2C1->TRISE &= ~( 3<<0 ) ;
I2C1->TRISE |= 17<<0 ; //I2C上升时间
I2C1->CCR &= ~( 1<<15 ) ;
I2C1->CCR &= ~( 1<<14 ) ;
I2C1->CCR &= ~( 0xFFF<<0 ) ;
I2C1->CCR |= 80<<0 ; //I2C速度
I2C1->CR1 &= ~( 1<<6 ) ;
I2C1->CR1 &= ~( 1<<7 ) ; //通用应答模式
//主机地址1+地址模式
I2C1->OAR1 &= ~( 1<<15 ) ;
I2C1->OAR1 &= ~( 3<<8 ) ;
I2C1->OAR1 &= ~( 0xFE<<1 ) ;
I2C1->OAR1 &= ~( 1<<0 ) ;
I2C1->OAR1 |= 1<<14 ; //地址模式
//双模式+主机地址2
I2C1->OAR2 &= ~( 1<<0 ) ;
I2C1->OAR2 &= ~( 0x7F<<1 ) ;
I2C1->CR1 |= 1<<0 ; //开启I2C模块
while( AT24Cxx_Check()==0 ) ;
}
(3)创建1.c文件并输入以下代码。
#include "sys.h"
#include "delay.h"
#include "usart1.h"
#include "at24cxx.h"
u8 TEXT_Buffer[] = "STM32F103 IIC Test" ;
int main()
{
u8 datatemp[ 17 ] ;
STM32_Clock_Init( 9 ) ; //STM32时钟初始化
SysTick_Init( 72 ) ; //SysTick初始化
USART1_Init( 72, 115200 ) ; //初始化串口1波特率115200
AT24Cxx_Init() ; //AT24C初始化
AT24Cxx_Write_nData( 0, TEXT_Buffer, 18 ) ; //从第0个地址处开始写入
AT24Cxx_Read_nData( 0, datatemp, 18 ) ; //从第0个地址处开始读出
while( 1 )
{
}
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
存储器
+关注
关注
38文章
7484浏览量
163774 -
EEPROM
+关注
关注
9文章
1019浏览量
81564 -
存储芯片
+关注
关注
11文章
896浏览量
43136
发布评论请先 登录
相关推荐
小白高手都适用,STM32学习教程(入门合集、自学笔记和例程)
、安全特性等方面对STM32进行全面的剖析;第4章主要介绍开发工具;第5章则引导读者针对STM32的外设进行一系列的基础实验设计;第6章通过10篇高级应用文章介绍
发表于 04-10 14:56
CubeMX入门STM32 HAL库的学习笔记
STM32CubeMX是ST官方开发的一款很好用的软件,主要用于STM32系列单片机的硬件驱动层的配置。网上也有一些关于STM32CubeMX的相关教程,对它的相关操作进行说明。从今天起,小柯希望能将自己从CubeMX
发表于 08-17 06:55
STM32各模块学习笔记
STM32个模块学习笔记 目录 STM32笔记之一 中断优先级.......................................
发表于 11-30 03:32
•3158次阅读
STM32学习之I2C协议(读写EEPROM)
关于STM32学习分享第七章 I2C协议(读写EEPROM)文章目录关于STM32学习分享前言二、代码1.i2c.c2.i2c.h3.mai
发表于 11-30 15:21
•32次下载
STM32入门学习笔记之EEPROM存储实验1
EEPROM(Electrically Erasable Programmable read only memory),称为带电可擦除可编程只读存储器,是一种可以断电保存数据的存储芯片,EEP
STM32入门学习笔记之EEPROM存储实验2
EEPROM(Electrically Erasable Programmable read only memory),称为带电可擦除可编程只读存储器,是一种可以断电保存数据的存储芯片,EEP
STM32入门学习笔记之EEPROM存储实验3
EEPROM(Electrically Erasable Programmable read only memory),称为带电可擦除可编程只读存储器,是一种可以断电保存数据的存储芯片,EEP
STM32入门学习笔记之EEPROM存储实验4
EEPROM(Electrically Erasable Programmable read only memory),称为带电可擦除可编程只读存储器,是一种可以断电保存数据的存储芯片,EEP
EEPROM存储实验
可以在电脑上或专用设备上擦除已有信息,重新编程,一般用在即插即用设备中,这种存储芯片可以通过高于普通电压的作用来擦除或重写,EEPROM芯片一般用在需要频繁存储数据,但是数据量不大的场合,本实
评论