290 lines
5.1 KiB
C
290 lines
5.1 KiB
C
#include "24cxx.h"
|
||
#include "led.h"
|
||
|
||
static void IIC1_Start(void); //发送起始信号
|
||
static void IIC1_Stop(void); //发送停止信号
|
||
static void IIC1_Write_Byte(u8 dat);//发送一个字节
|
||
static u8 IIC1_Read_Byte(unsigned char ack);//接收一个字节
|
||
static u8 IIC1_Wait_Ack(void);//等待ACK信号
|
||
static void IIC1_Ack(void);//发送ACK信号
|
||
static void IIC1_NAck(void);//不发送ACK信号
|
||
|
||
void I2C_delay(uint16_t n)
|
||
{
|
||
u8 i = 5*n; //这里可以优化速度 ,经测试最低到5还能写入
|
||
while(i)
|
||
{
|
||
i--;
|
||
}
|
||
}
|
||
|
||
//初始化IIC
|
||
void AT24cxx_init(void)
|
||
{
|
||
GPIO_InitTypeDef GPIO_InitStructure;
|
||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); /* 打开GPIO时钟 */
|
||
|
||
|
||
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10|GPIO_Pin_11;//SDA,SCL
|
||
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//GPIO_Mode_Out_OD;
|
||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||
GPIO_Init(GPIOB,&GPIO_InitStructure);
|
||
IIC_SDA1;
|
||
IIC_SCL1;
|
||
|
||
}
|
||
|
||
//在AT24CXX指定地址读取一个数据
|
||
//ReadAddr :开始读数的地址
|
||
//返回值 :读取到的数据
|
||
u8 AT24cxx_ReadOneByte(u16 ReadAddr)
|
||
{
|
||
u8 temp=0;
|
||
IIC1_Start();
|
||
if(EE_TYPE>AT24C16)
|
||
{
|
||
IIC1_Write_Byte(0xa0);//发送写命令
|
||
IIC1_Wait_Ack();
|
||
IIC1_Write_Byte(ReadAddr/256);//发送高地址
|
||
}
|
||
else IIC1_Write_Byte(0xa0+((ReadAddr/256)<<1));//发送器件地址0xA0,写数据
|
||
IIC1_Wait_Ack();
|
||
IIC1_Write_Byte(ReadAddr%256);//发送低地址
|
||
IIC1_Wait_Ack();
|
||
IIC1_Start();
|
||
if(EE_TYPE>AT24C16)IIC1_Write_Byte(0xa1); //进入接收模式
|
||
else IIC1_Write_Byte(0xa1+((ReadAddr/256)<<1));//进入接收模式
|
||
IIC1_Wait_Ack();
|
||
temp=IIC1_Read_Byte(1);
|
||
IIC1_Stop();//产生一个停止条件
|
||
return temp;
|
||
}
|
||
//在AT24CXX指定地址写一个数据
|
||
//WriteAddr:写入数据的目的地址
|
||
//data :要写入的数据
|
||
void AT24cxx_WriteOneByte(u16 WriteAddr,u8 data)
|
||
{
|
||
IIC1_Start();
|
||
if(EE_TYPE>AT24C16)
|
||
{
|
||
IIC1_Write_Byte(0xa0);
|
||
IIC1_Wait_Ack();
|
||
IIC1_Write_Byte(WriteAddr/256);//发送高地址
|
||
}
|
||
else IIC1_Write_Byte(0xa0+((WriteAddr/256)<<1));
|
||
IIC1_Wait_Ack();
|
||
IIC1_Write_Byte(WriteAddr%256);//发送低地址
|
||
IIC1_Wait_Ack();
|
||
IIC1_Write_Byte(data);
|
||
IIC1_Wait_Ack();
|
||
IIC1_Stop();//产生一个停止条件
|
||
I2C_delay(2);
|
||
}
|
||
//在AT24CXX指定地址开始写入指定长度的数据
|
||
//该函数用于写入16位或32位的数据
|
||
//WriteAddr:开始写入的地址
|
||
//data :要写入的数据
|
||
//len :要写入数据的长度2,4
|
||
void AT24cxx_WriteLenByte(u16 WriteAddr,u32 data,u8 len)
|
||
{
|
||
u8 i;
|
||
for(i=0;i<len;i++)
|
||
{
|
||
AT24cxx_WriteOneByte(WriteAddr+i,(data>>(8*i))&0xff);
|
||
}
|
||
}
|
||
//在AT24CXX指定地址开始读出指定长度的数据
|
||
//该函数用于读出16bit或者32bit的数据.
|
||
//ReadAddr :开始读出的地址
|
||
//返回值 :数据
|
||
//len :要读出数据的长度2,4
|
||
u32 AT24cxx_ReadLenByte(u16 ReadAddr,u8 len)
|
||
{
|
||
u8 i;
|
||
u32 temp=0;
|
||
for(i=0;i<len;i++)
|
||
{
|
||
temp<<=8;
|
||
temp+=AT24cxx_ReadOneByte(ReadAddr+len-i-1);
|
||
}
|
||
return temp;
|
||
}
|
||
|
||
//在AT24CXX指定地址开始写入指定长度的数据
|
||
//该函数用于写入指定的字节数
|
||
//WriteAddr:开始写入的地址
|
||
//buf :数据数组首地址
|
||
//len :要写入数据的个数
|
||
void AT24cxx_Write(u16 WriteAddr,u8 *buf,u16 len)
|
||
{
|
||
u16 i;
|
||
for(i=0;i<len;i++)
|
||
{
|
||
IWDG_Feed();
|
||
AT24cxx_WriteOneByte(WriteAddr,*buf);
|
||
WriteAddr++;
|
||
buf++;
|
||
}
|
||
}
|
||
//在AT24CXX指定地址开始读出指定长度的数据
|
||
//该函数用于读出指定的字节数
|
||
//ReadAddr:开始读出数据的地址
|
||
//len :要写入数据的个数
|
||
//buf :数据数组首地址
|
||
void AT24cxx_Read(u16 ReadAddr,u8 *buf,u16 len)
|
||
{
|
||
while(len--)
|
||
{
|
||
IWDG_Feed();
|
||
*buf++=AT24cxx_ReadOneByte(ReadAddr++);
|
||
}
|
||
}
|
||
//检查AT24CXX是否正常
|
||
//这里用了24XX的第一个地址(0)来存储标志字.
|
||
//返回1:检测失败
|
||
//返回0:检查成功
|
||
u8 AT24cxx_Check(void)
|
||
{
|
||
u8 temp1,temp2;
|
||
AT24cxx_WriteOneByte(0x010,0x55);
|
||
temp1=AT24cxx_ReadOneByte(0x010);//避免每次开机都写AT24CXX
|
||
temp2=temp1;
|
||
if(temp2==0x55)return 0;
|
||
else
|
||
{
|
||
AT24cxx_WriteOneByte(0x010,0x55);
|
||
temp1=AT24cxx_ReadOneByte(0x010);
|
||
temp2=temp1;
|
||
if(temp2==0x55)return 0;
|
||
}
|
||
return 1;
|
||
}
|
||
|
||
|
||
|
||
|
||
//产生IIC起始信号
|
||
static void IIC1_Start(void)
|
||
{
|
||
|
||
IIC_SDA1;
|
||
IIC_SCL1;
|
||
I2C_delay(4);
|
||
IIC_SDA0;
|
||
I2C_delay(4);
|
||
IIC_SCL0;
|
||
I2C_delay(4);
|
||
}
|
||
//产生IIC停止信号
|
||
static void IIC1_Stop(void)
|
||
{
|
||
IIC_SDA0;
|
||
IIC_SCL1;
|
||
I2C_delay(2);
|
||
IIC_SDA1;
|
||
I2C_delay(4);
|
||
// IIC_SCL0;
|
||
}
|
||
//返回1,接收应答失败,返回0,接收应答成功
|
||
static u8 IIC1_Wait_Ack(void)
|
||
{
|
||
u8 i;
|
||
SDA_IN();
|
||
IIC_SCL0;
|
||
I2C_delay(2);
|
||
IIC_SCL1;
|
||
I2C_delay(2);
|
||
while(Read_IIC_SDA())
|
||
{
|
||
i++;
|
||
if(i>250)
|
||
{
|
||
|
||
IIC1_Stop();
|
||
return 1;
|
||
}
|
||
}
|
||
IIC_SCL0;
|
||
I2C_delay(2);
|
||
return 0;
|
||
}
|
||
//产生ACK应答
|
||
static void IIC1_Ack(void)
|
||
{
|
||
IIC_SCL0;
|
||
SDA_OUT();
|
||
IIC_SDA0;
|
||
I2C_delay(2);
|
||
IIC_SCL1;
|
||
I2C_delay(2);
|
||
IIC_SCL0;
|
||
}
|
||
//不产生ACK应答
|
||
static void IIC1_NAck(void)
|
||
{
|
||
IIC_SCL0;
|
||
SDA_OUT();
|
||
IIC_SDA1;
|
||
I2C_delay(2);
|
||
IIC_SCL1;
|
||
I2C_delay(2);
|
||
IIC_SCL0;
|
||
}
|
||
//IIC发送一个字节
|
||
//返回从机有无应答
|
||
//0,有应答
|
||
//1,无应答
|
||
void IIC1_Write_Byte(u8 dat)
|
||
{
|
||
u8 t;
|
||
SDA_OUT();
|
||
I2C_delay(2);
|
||
for(t=0;t<8;t++)
|
||
{
|
||
IIC_SCL0;
|
||
if(dat&0x80)
|
||
{
|
||
IIC_SDA1;
|
||
}
|
||
else
|
||
{
|
||
IIC_SDA0;
|
||
}
|
||
I2C_delay(2);
|
||
IIC_SCL1;
|
||
dat<<=1;
|
||
I2C_delay(2);
|
||
|
||
}
|
||
IIC_SCL0;
|
||
I2C_delay(2);
|
||
}
|
||
//读1个字节,ack=0时,发送ACK,ack=1,发送NACK
|
||
u8 IIC1_Read_Byte(unsigned char ack)
|
||
{
|
||
u8 i,receive;
|
||
SDA_IN();//SDA设为输入
|
||
IIC_SDA0;
|
||
I2C_delay(2);
|
||
for(i=0;i<8;i++)
|
||
{
|
||
IIC_SCL0;
|
||
I2C_delay(2);
|
||
IIC_SCL1;
|
||
receive<<=1;
|
||
I2C_delay(2);
|
||
if(Read_IIC_SDA())receive++;
|
||
I2C_delay(2);
|
||
}
|
||
IIC_SDA1;
|
||
I2C_delay(2);
|
||
IIC_SCL0;
|
||
I2C_delay(2);
|
||
if(!ack)
|
||
IIC1_Ack();
|
||
else
|
||
IIC1_NAck();
|
||
return receive;
|
||
}
|
||
|