#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>(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;i250) { 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; }