STM32入门学习笔记之EEPROM存储实验5

电子说

1.2w人已加入

描述

(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 )
  {

  }
}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分