#include "stm32f10x.h"
#include "Includes.h"
#include "Constants.h"
#include "Functions.h"
#include "Globals.h"
#define IIC_SCL_OUT GPIOB->CRL |= 0x03000000
#define IIC_SDA_IN GPIOB->CRL &= 0xCFFFFFFF
#define IIC_SDA_OUT GPIOB->CRL |= 0x30000000
#define IIC_SDA_BIT GPIOB->IDR & GPIO_Pin_7
#define IIC_SCL0 GPIOB->BRR = GPIO_Pin_6
#define IIC_SCL1 GPIOB->BSRR = GPIO_Pin_6
#define IIC_SDA0 GPIOB->BRR = GPIO_Pin_7
#define IIC_SDA1 GPIOB->BSRR = GPIO_Pin_7
#define ERRORCOUNT 3
/*************************************************************
@Fn:
@Br:
@Pa:
@Rt:
*************************************************************/
void ConfigSoftI2C1( void ){
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_StructInit( &GPIO_InitStructure ); /* 初始化变量 */
/*-- GPIO Configuration */
/* Configure PB.6/PB.7 as Open drain */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6; /* I2C引脚 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);
}
/************************************************
函 数 名: IICStart()
功 能:启动IIC总线
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void IICStart( void ){
IIC_SCL_OUT;
IIC_SDA_OUT;
IIC_SCL0;
IIC_SDA1;
IIC_SCL1;
DelayI2C();
IIC_SDA0;
DelayI2C();
IIC_SCL0;
IIC_SDA1;
}
/************************************************
函 数 名: IICStop()
功 能:停止IIC总线
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void IICStop( void ){
IIC_SCL_OUT;
IIC_SDA_OUT;
IIC_SCL0;
IIC_SDA0;
IIC_SCL1;
DelayI2C();
IIC_SDA1;
DelayI2C();
IIC_SCL0;
}
/************************************************
函 数 名: IICRecAck()
功 能:检查应答位
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:0: 有应答; 1: 无应答
************************************************/
u8 IICRecAck( void ){
u8 ack;
IIC_SCL_OUT;
IIC_SDA_OUT;
IIC_SCL0;
IIC_SDA0;
IIC_SCL1;
IIC_SDA_IN;
if( IIC_SDA_BIT )ack = 1;
else
ack = 0;
IIC_SCL0;
return( ack );
}
/************************************************
函 数 名: IICAck()
功 能:对IIC总线产生应答
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void IICAck( void ){
IIC_SCL_OUT;
IIC_SDA_OUT;
IIC_SDA0;
IIC_SCL1;
DelayI2C();
IIC_SCL0;
DelayI2C();
IIC_SDA1;
}
/************************************************
函 数 名: IICNoAck()
功 能:不对IIC总线产生应答
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void IICNoAck( void ){
IIC_SCL_OUT;
IIC_SDA_OUT;
IIC_SDA1;
IIC_SCL1;
DelayI2C();
IIC_SCL0;
}
/************************************************
函 数 名: IICSendByte()
功 能:往EEPROM写入1Byte数据
说 明:
调 用:
全局变量:
入口参数:WriteData: 写入的数据
出口参数:无
返 回 值:无
************************************************/
void IICSendByte( u8 WriteData ){
u8 i;
IIC_SCL_OUT;
IIC_SDA_OUT;
for( i = 8;i > 0;i-- )
{
IIC_SCL0;
if( WriteData & 0x80 )IIC_SDA1;
else
IIC_SDA0;
IIC_SCL1;
WriteData <<= 1;
}
IIC_SCL0;
}
/************************************************
函 数 名: IICReceiveByte()
功 能:从EEPROM读取1Byte数据
说 明:
调 用:
全局变量:
入口参数:无
出口参数:无
返 回 值:ReadData
************************************************/
u8 IICReceiveByte( void ){
u8 i, ReadData;
IIC_SCL_OUT;
IIC_SDA_OUT;
IIC_SCL0;
IIC_SDA1;
IIC_SDA_IN;
for( i = 0;i < 8; i++ )
{
IIC_SCL1;
ReadData <<= 1;
if( IIC_SDA_BIT )ReadData |= 0x01;
IIC_SCL0;
}
return( ReadData );
}
/************************************************
函 数 名: WriteReadIIC()
功 能:对EEPROM读/写数据
说 明:先写地址,后读/写数据
调 用:IICStart(),IICSendByte(),IICRecAck(),
IICNoAck(),IICAck(),IICReceiveByte(),
IICStop(),delay_nus()
全局变量:
入口参数:DataBuff: 读写数据输入/输出缓冲区的首址,
ByteQuantity: 读写数据的字节数量,
Address: EEPROM片内地址, ControlByte: EEPROM的控制字节
ControlByte具体形式: (1)(0)(1)(0)(A2)(A1)(A0)(R/W),
其中R/W = 1,表示读操作;R/W = 0为写操作;
A2,A1,A0为EEPROM的页选或片选地址
出口参数:无
返 回 值:0: 读/写操作成功; 1: 读/写操作失败
************************************************/
u8 WriteReadIIC( u8 *DataBuff, u8 ByteQuantity,
u16 Address, u8 ControlByte ){
u8 i = ERRORCOUNT, Errorflag = 1,j;
while( i-- )
{
IICStart();
IICSendByte( ControlByte & 0xFE );
if( IICRecAck() )continue;
IICSendByte(( u8 )( Address >> 8 ));
if( IICRecAck() )continue;
IICSendByte(( u8 )Address );
if( IICRecAck() )continue;
if(!( ControlByte & 0x01 ))
{
j = ByteQuantity;
Errorflag = 0; //Clr errorflag
while( j-- )
{
IICSendByte( *DataBuff++ );
if( IICRecAck() == 0 )continue;
Errorflag = 1;
break;
}
if( Errorflag == 1 )continue;
break;
}
else
{
IICStart();
IICSendByte( ControlByte );
if( IICRecAck() )continue;
while( --ByteQuantity )
{
*DataBuff++ = IICReceiveByte();
IICAck();
}
*DataBuff = IICReceiveByte(); //read last byte data
IICNoAck();
Errorflag = 0;
break;
}
}
IICStop();
IIC_SCL1;
return( Errorflag );
}
/*************************************************************
@Fn:
@Br:
@Pa:
@Rt:
*************************************************************/
void DelayI2C( void ){
u8 i = 15;
while( i )
{
i--;
}
}