【晒FRAM铁电存储器样片】+MB85RC64芯片读写测试(IO模拟IIC总线—STM32平台)
- UID
- 797015
- 性别
- 男
|
|
|
|
|
|
- UID
- 797015
- 性别
- 男
|
A 底层驱动代码实现
底层驱动主要是用IO端口模拟出IIC总线的通信时序,这个比较简单,从51时代就开始模拟IC总线,这个没有什么难度,代码如下:
#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include <stdio.h>
#include <string.h>
#include "stm32f10x_conf.h"
#include "system_stm32f10x.h"
#include "I2C_103VCT6.H"
/* 类型定义 typedef-----------------------------------------------------------*/
/* 预定义字符 ------------------------------------------------------------*/
/* 宏定义 -------------------------------------------------------------*/
// 对I2C数据总线进行操作。
//===========================================================
// PC7--SCL
// PC6--SDA
#define I2C_PRORT GPIOC
#define I2C_PORT_CLK RCC_APB2Periph_GPIOC
#define I2C_SDA_PIN GPIO_Pin_6
#define I2C_SCL_PIN GPIO_Pin_7
#define I2C_SDA_H GPIO_SetBits(I2C_PRORT, I2C_SDA_PIN)
#define I2C_SDA_L GPIO_ResetBits(I2C_PRORT, I2C_SDA_PIN)
#define I2C_SDA_VAL GPIO_ReadInputDataBit(I2C_PRORT,I2C_SDA_PIN)
#define I2C_SCL_H GPIO_SetBits(I2C_PRORT, I2C_SCL_PIN )
#define I2C_SCL_L GPIO_ResetBits(I2C_PRORT, I2C_SCL_PIN
/* 变量定义 ---------------------------------------------------------*/
extern void Delay_Us(__IO uint32_t nCount);
/*******************************************************************************
* 函数名称: I2C_Gpio_Config();
* 功能描述: 设置I2C引脚,用软件模拟的方法实现I2C功能
* 输入参数: void
* 返回参数: 无
********************************************************************************/
void I2C_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure ;
RCC_APB2PeriphClockCmd(I2C_PORT_CLK ,ENABLE);
//配置I2C_SCL/I2C_SDA引脚
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN |I2C_SCL_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_PRORT, &GPIO_InitStructure);
GPIO_SetBits(I2C_PRORT, I2C_SDA_PIN |I2C_SCL_PIN );
}
/*******************************************************************************
* 函数名称: I2C_SDA_OUT();
* 功能描述: 设置SDA端口为输出模式
* 输入参数: void
* 返回参数: 无
********************************************************************************/
void I2C_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_PRORT, &GPIO_InitStructure);
}
/*******************************************************************************
* 函数名称: I2C_SDA_IN();
* 功能描述: 设置SDA端口为输入模式
* 输入参数: void
* 返回参数: 无
********************************************************************************/
void I2C_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_SDA_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(I2C_PRORT, &GPIO_InitStructure);
}
/*******************************************************************************
* 函数名称: I2C_Start();
* 功能描述: 开始条件
* 输入参数: void
* 返回参数: 无
********************************************************************************/
void I2C_Start(void)
{
I2C_SDA_OUT();
I2C_SDA_H ;
I2C_SCL_H ;
Delay_Us(4);
I2C_SDA_L; //START:when CLK is high,DATA change form high to low
Delay_Us(4);
I2C_SCL_L ;//钳住I2C总线,准备发送或接收数据
Delay_Us(4);
}
/*******************************************************************************
* 函数名称: I2C_Stop();
* 功能描述: 停止条件
* 输入参数: void
* 返回参数: 无
********************************************************************************/
void I2C_Stop(void)
{
I2C_SDA_OUT();
//I2C_SCL_L ;
I2C_SDA_L; //STOP:when CLK is high DATA change form low to high
Delay_Us(4);
I2C_SCL_H ;
Delay_Us(4);
I2C_SDA_H ; //发送I2C总线结束信号
Delay_Us(4);
}
/*******************************************************************************
* 函数名称: I2C_Wait_Ack();
* 功能描述: 检查从机的应答操作
* 输入参数: 无
* 返回参数: 从机是否有应答:1--失败,0--成功
********************************************************************************/
unsigned char I2C_Wait_Ack(void)
{
unsigned char utemp ;
I2C_SDA_H ;
Delay_Us(2);
I2C_SCL_H ;
Delay_Us(2);
I2C_SDA_IN(); //SDA设置为输入
utemp = I2C_SDA_VAL;
Delay_Us(2);
I2C_SCL_L ;
Delay_Us(2);
I2C_SDA_OUT();
if( utemp) return 1 ;
else return 0 ;
}
/*******************************************************************************
* 函数名称: I2C_Ack();
* 功能描述: 产生I2C的主机应答操作
* 输入参数: 无
* 返回参数: 无
********************************************************************************/
void I2C_Ack(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_L;
Delay_Us(2);
I2C_SCL_H ;
Delay_Us(2);
I2C_SCL_L;
//I2C_SDA_H;
}
/*******************************************************************************
* 函数名称: I2C_NAck();
* 功能描述: 不产生I2C的主机应答操作
* 输入参数: 无
* 返回参数: 无
********************************************************************************/
void I2C_NAck(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_H;
Delay_Us(2);
I2C_SCL_H ;
Delay_Us(2);
I2C_SCL_L;
}
/*******************************************************************************
* 函数名称: I2C_Write_1();
* 功能描述: 向IIC总线发送一个1
* 输入参数: 无
* 返回参数: 无
********************************************************************************/
void I2C_Write_1(void)
{
I2C_SDA_H;
Delay_Us(2);
I2C_SCL_H ;
Delay_Us(2);
I2C_SCL_L;
Delay_Us(2);
}
/*******************************************************************************
* 函数名称: I2C_Write_0();
* 功能描述: 向IIC总线发送一个0
* 输入参数: 无
* 返回参数: 无
********************************************************************************/
void I2C_Write_0(void)
{
I2C_SDA_L;
Delay_Us(2);
I2C_SCL_H ;
Delay_Us(2);
I2C_SCL_L;
Delay_Us(2);
} |
|
|
|
|
|
- UID
- 797015
- 性别
- 男
|
/*******************************************************************************
* 函数名称: I2C_Send_Byte();
* 功能描述: 向IIC总线发送一个字节的数据
* 输入参数: ucData--发送的数据
* 返回参数: 无
********************************************************************************/
void I2C_Send_Byte(unsigned char ucData)
{
unsigned char i;
//I2C_SDA_OUT();
//I2C_SCL_L;
for(i = 8;i > 0;i--)
{
if( ucData & 0x80) I2C_Write_1();
else I2C_Write_0();
Delay_Us(2);
ucData <<= 1;
}
I2C_SDA_H;
Delay_Us(2);
}
/*******************************************************************************
* 函数名称: I2C_Send_Byte();
* 功能描述: 向IIC总线发送N个字节的数据
* 输入参数: pbuffer--指向发送数据存放首地址
n--数据的个数
* 返回参数: 发送是否成功的标志:0--成功,1--失败
********************************************************************************/
unsigned char I2C_Send_NByte(unsigned char * pbuffer, unsigned char n)
{
unsigned char i;
for(i = 0;i < n;i++)
{
I2C_Send_Byte(* pbuffer);
if(I2C_Wait_Ack()==0)
{
pbuffer++;
}
else
{
I2C_Stop();
return 1;
}
}
I2C_Stop();
return 0;
}
/*******************************************************************************
* 函数名称: I2C_Read_Byte();
* 功能描述: 从IIC总线读取一个字节
* 输入参数: 无
* 返回参数: 读取的数据
********************************************************************************/
unsigned char I2C_Read_Byte(void)
{
unsigned char uData =0x00;
unsigned char utemp,i;
for(i = 8;i > 0;i--)
{
I2C_SDA_H;
Delay_Us(2);
I2C_SCL_H ;
Delay_Us(2);
I2C_SDA_IN(); //SDA设置为输入
Delay_Us(2);
utemp = I2C_SDA_VAL;
uData <<= 1;
if(utemp) uData |= 0x01;
Delay_Us(2);
I2C_SCL_L;
Delay_Us(2);
I2C_SDA_OUT();
}
I2C_SDA_H;
Delay_Us(2);
return( uData );
}
/*******************************************************************************
* 函数名称: I2C_Read_NByte();
* 功能描述: 从IIC总线读取N个字节的数据
* 输入参数: pbuffer--指向发送数据存放首地址
n--数据的个数
* 返回参数: 读取的数据
********************************************************************************/
void I2C_Read_NByte(unsigned char * pbuffer, unsigned char n)
{
unsigned char i;
for(i = 0;i < n;i++)
{
pbuffer[i] = I2C_Read_Byte();
if( i < (n-1)) I2C_Ack(); //应答
else I2C_NAck(); //无应答
}
I2C_Stop();
}
/********************************************************************************
函数名称:Delay()
功 能:延时函数
参 数:无
返 回 值:无
*********************************************************************************/
void Delay(__IO uint32_t nCount)
{
/* Decrement nCount value */
while (nCount != 0)
{
nCount--;
}
}
/********************************************************************************
函数名称:Delay_Us()
功 能:软件延时微秒级函数
参 数:无
返 回 值:无
*********************************************************************************/
void Delay_Us(__IO uint32_t nCount)
{
/* 10uS延迟=>10.8uS,100uS延迟=>104uS*/
while (nCount != 0)
{
nCount--;
Delay(350);
}
}
/********************************************************************************
函数名称:Delay_Ms()
功 能:软件延时豪秒级函数
参 数:无
返 回 值:无
*********************************************************************************/
void Delay_Ms(__IO uint32_t nCount)
{
/* 10uS延迟=>10.8uS,100uS延迟=>104uS*/
while (nCount != 0)
{
nCount--;
Delay(35000);
}
} |
|
|
|
|
|
- UID
- 797015
- 性别
- 男
|
B 应用层驱动代码实现
这个代码可以不经修改,直接应用到任何硬件平台中,主要实现FRAM器件的读写函数。为了兼容EERPOM器件,这里函数名称沿用原来的,没有重新命名和优化,因为MB85RC64兼容AT24C64EERPOM的。
extern void Delay_Ms(__IO uint32_t nCount);
extern void Delay_Us(__IO uint32_t nCount);
#define Device_Address 0xA0 //24CXX的设备地址
/*******************************************************************************
* 函数名称: EEPROM_Read_Byte()
* 功能描述: 从24CXX的指定地址读取1个字节的数据
* 输入参数: dataaddress--数据读取的地址
* 返回参数: 读取的数据
********************************************************************************/
unsigned char EEPROM_Read_Byte(unsigned char dataaddress)
{
unsigned char temp;
I2C_Start(); // 起始条件
I2C_Send_Byte(Device_Address); // 向从器件发送设备地址
if(I2C_Wait_Ack()==0) // 如果有从器件应答
I2C_Send_Byte(dataaddress); // 发送数据地址
else
return 0;
if(I2C_Wait_Ack()==0)
{
I2C_Start(); // 起始条件
I2C_Send_Byte((Device_Address|0x01));
}
else
return 0;
if(I2C_Wait_Ack()==0)
temp = I2C_Read_Byte();
else
return 0;
I2C_NAck();
I2C_Stop();
return temp;
}
/*******************************************************************************
* 函数名称: EEPROM_Read_NByte()
* 功能描述: 从24CXX的指定地址读取N个字节的数据
* 输入参数: pbuffer--指向保存数据地址的指针
n--读取数据的个数
dataaddress--数据读取的首地址
* 返回参数: 读取结果:0--成功,1--失败
********************************************************************************/
unsigned char EEPROM_Read_NByte( unsigned char *pbuffer, unsigned char n, unsigned char dataaddress )
{
I2C_Start(); // 起始条件
I2C_Send_Byte(Device_Address); // 向从器件发送设备地址
if(I2C_Wait_Ack()==0) // 如果有从器件应答
I2C_Send_Byte(dataaddress); // 发送数据地址
else
return 1;
if(I2C_Wait_Ack()==0)
{
I2C_Start(); // 起始条件
I2C_Send_Byte((Device_Address|0x01));
}
else
return 1;
if(I2C_Wait_Ack()==0)
I2C_Read_NByte(pbuffer, n);
else
return 1;
return 0;
}
/*******************************************************************************
* 函数名称: EEPROM_Write_Byte();
* 功能描述: 向24CXX的指定地址中写入1个字节的数据
* 输入参数: wdata--写入的数据
dataaddress--数据读取的首地址
* 返回参数: 写入结果:0--成功,1--失败
********************************************************************************/
unsigned char EEPROM_Write_Byte( unsigned char dataaddress, unsigned char wdata )
{
I2C_Start(); // 起始条件
I2C_Send_Byte(Device_Address); // 向从器件发送设备地址
if(I2C_Wait_Ack()==0) // 如果有从器件应答
I2C_Send_Byte(dataaddress); // 发送数据地址
else
return 1;
if(I2C_Wait_Ack()==0) // 如果从器件应答
I2C_Send_Byte(wdata); // 发送要写入的数据
else
return 1 ;
if(I2C_Wait_Ack()==0) // 如果从器件应答
I2C_Stop(); // 如果从器件应答 ,发送停止条件
else
return 1;
Delay_Ms(10); //等待EEPROM完成内部写入
return 0 ;
}
/*******************************************************************************
* 函数名称: EEPROM_Write_NByte();
* 功能描述: 向24CXX的指定地址中写入1个字节的数据
* 输入参数: dataaddress--数据读取的地址
* 返回参数: 写入结果:0--成功,1--失败
********************************************************************************/
unsigned char EEPROM_Write_NByte( unsigned char *pbuffer, unsigned char n, unsigned char dataaddress )
{
unsigned char temp;
I2C_Start(); // 起始条件
I2C_Send_Byte(Device_Address); // 向从器件发送设备地址
if(I2C_Wait_Ack()==0) // 如果有从器件应答
I2C_Send_Byte(dataaddress); // 发送数据地址
else
return 1;
if(I2C_Wait_Ack()==0) // 如果从器件应答
temp = I2C_Send_NByte(pbuffer, n);
else
return 1;
Delay_Ms(10); //等待EEPROM完成内部写入
if(temp==0) return 0;
else return 1;
}
这应用层的四个函数可以满足大部分应用需求,在测试环节会用到。
|
|
|
|
|
|
- UID
- 797015
- 性别
- 男
|
|
|
|
|
|
- UID
- 797015
- 性别
- 男
|
|
|
|
|
|
- UID
- 797015
- 性别
- 男
|
发帖子上去,现在看不到图片了,不知道如何解决这个问题! |
|
|
|
|
|
- UID
- 797015
- 性别
- 男
|
|
|
|
|
|