电子说
(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 )
{
}
}
全部0条评论
快来发表一下你的评论吧 !