最新动态

工业物联网通讯专家!
认真做好每一件事,设计简单、可靠、价格合理的产品!

STM32的I2C 模拟IIC 读写EEPROM 铁电存储器

转发:

这个模拟I2C的代码也是在本站下载的,原来是访问EEPROM的。
我使用STM32来访问I2C接口的铁电存储器,FM24CL16,2K字节,比访问EEPROM要方便一点,所以简单修改了一下,比原来少很多。 感谢ground网友提供的原始代码! FM24CL16的手册由于文件服务器问题,暂时传不上来。等阿莫弄好了再传吧。
代码就不打包了,直接贴上来了
=================================

/* Configure I2C1 pins: SCL and SDA */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
=================================
/*******************************************************************************
* File Name : i2c_fram.h
* Author : MCD Application Team
* Version : V2.0.1
* Date : 06/13/2008
* Description : Header for i2c_ee.c module
*******************************************************************************/
/* Define to prevent recursive inclusion ------------------------------------ */
#ifndef __I2C_FRAM_H
#define __I2C_FRAM_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_lib.h"

/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/


/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */


bool I2C_FRAM_BufferWrite(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite);
bool I2C_FRAM_BufferRead(u8* pBuffer, u16 ReadAddr, u16 NumByteToRead);

#endif /* __I2C_FRAM_H */

=================================
/*******************************************************************************
* File Name : i2c_fram.c
* Author : Appcat
* Version : V0.0.1
* Date : 07/11/2009
* Description : This file provides a set of functions needed to manage the
* communication between I2C peripheral and I2C FM24CL16 FRAM.
*******************************************************************************/

/* Includes ------------------------------------------------------------------*/
#include "i2c_fram.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define I2C_Speed 100000
#define I2C1_SLAVE_ADDRESS7 0xA0
#define I2C_PageSize 256

#define SCL_H GPIOB->BSRR = GPIO_Pin_6
#define SCL_L GPIOB->BRR = GPIO_Pin_6 

#define SDA_H GPIOB->BSRR = GPIO_Pin_7
#define SDA_L GPIOB->BRR = GPIO_Pin_7

#define SCL_read GPIOB->IDR & GPIO_Pin_6
#define SDA_read GPIOB->IDR & GPIO_Pin_7


/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
vu8 FRAM_ADDRESS;

/* Private function prototypes -----------------------------------------------*/

/**/
void I2C_delay(void)
{
u8 i=150; //这里可以优化速度 ,经测试最低到5还能写入
while(i) 
{ 
i--; 
} 
}

bool I2C_Start(void)
{
SDA_H;
SCL_H;
I2C_delay();
if(!SDA_read)return FALSE; //SDA线为低电平则总线忙,退出
SDA_L;
I2C_delay();
if(SDA_read) return FALSE; //SDA线为高电平则总线出错,退出
SDA_L;
I2C_delay();
return TRUE;
}

void I2C_Stop(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SDA_H;
I2C_delay();
}

void I2C_Ack(void)
{
SCL_L;
I2C_delay();
SDA_L;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}

void I2C_NoAck(void)
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
SCL_L;
I2C_delay();
}

bool I2C_WaitAck(void) //返回为:=1有ACK,=0无ACK
{
SCL_L;
I2C_delay();
SDA_H;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
SCL_L;
return FALSE;
}
SCL_L;
return TRUE;
}

void I2C_SendByte(u8 SendByte) //数据从高位到低位//
{
u8 i=8;
while(i--)
{
SCL_L;
I2C_delay();
if(SendByte&0x80)
SDA_H; 
else 
SDA_L; 
SendByte<<=1;
I2C_delay();
SCL_H;
I2C_delay();
}
SCL_L;
}

u8 I2C_ReceiveByte(void) //数据从高位到低位//
{ 
u8 i=8;
u8 ReceiveByte=0;

SDA_H;
while(i--)
{
ReceiveByte<<=1; 
SCL_L;
I2C_delay();
SCL_H;
I2C_delay();
if(SDA_read)
{
ReceiveByte|=0x01;
}
}
SCL_L;
return ReceiveByte;
}

bool I2C_FRAM_BufferWrite(u8* pBuffer, u16 WriteAddr, u16 NumByteToWrite)
{
u8 Addr = 0, count = 0;

Addr = WriteAddr / I2C_PageSize;

count = WriteAddr % I2C_PageSize;

Addr = Addr << 1;

Addr = Addr & 0x0F; 

FRAM_ADDRESS = I2C1_SLAVE_ADDRESS7 | Addr;

if (!I2C_Start()) return FALSE;
I2C_SendByte(FRAM_ADDRESS);//设置器件地址+段地址 
if (!I2C_WaitAck())
{
I2C_Stop(); 
return FALSE;
}
I2C_SendByte(count); //设置段内地址 
I2C_WaitAck();

while(NumByteToWrite--)
{
I2C_SendByte(* pBuffer);
I2C_WaitAck();
pBuffer++;
}
I2C_Stop();
//注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms)
//Systick_Delay_1ms(10);
return TRUE;
}


//读出1串数据 
bool I2C_FRAM_BufferRead(u8* pBuffer, u16 WriteAddr, u16 NumByteToRead)
{
u8 Addr = 0, count = 0;

Addr = WriteAddr / I2C_PageSize;

count = WriteAddr % I2C_PageSize;

Addr = Addr << 1;

Addr = Addr & 0x0F; 

FRAM_ADDRESS = I2C1_SLAVE_ADDRESS7 | Addr;

if (!I2C_Start()) return FALSE;

I2C_SendByte(FRAM_ADDRESS);//设置器件地址+段地址 

if (!I2C_WaitAck()) 
{
I2C_Stop(); 
return FALSE;
}

I2C_SendByte(count); //设置低起始地址 
I2C_WaitAck();
I2C_Start();
I2C_SendByte(FRAM_ADDRESS | 0x01);
I2C_WaitAck();
while(NumByteToRead)
{
*pBuffer = I2C_ReceiveByte();
if(NumByteToRead == 1)I2C_NoAck();
else I2C_Ack(); 
pBuffer++;
NumByteToRead--;
}
I2C_Stop();
return TRUE;
}

=================================



上一篇: RS232标准接口定义 9针 25针 互转连接 自测试接法等
下一篇: JS获取当前时间戳的方法-JavaScript 获取当前时间戳

发表评论