上次写的IIC程序对AT24C02可以进行一个字节的读取和写入,但是不能连续读取跟连续写入,这次采用连续写跟连续读的方式,如下图所示
本人用逻辑分析仪抓取波形显示正常,而且调试的时候写入读取都正确,现在贴上整体代码如下:
#include "AT24C02_iic.h"
#define SCL_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_12)
#define SCL_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_12)
#define SDA_HIGH GPIO_SetBits(GPIOC,GPIO_Pin_11)
#define SDA_LOW GPIO_ResetBits(GPIOC,GPIO_Pin_11)
#define READ_SDA GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_11)
static void IIC_Delay(u32 cnt)
{
u32 i,j;
for(i=0;i<cnt;i++)
{
for(j=0;j<36;j++);
}
}
void MYIIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; //设置成开路模式,读取DIR寄存器可以获取该引脚的电平高低
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
//GPIO_ResetBits(GPIOC,GPIO_Pin_12);
GPIO_SetBits(GPIOC,GPIO_Pin_11 | GPIO_Pin_12);//SCL SDA引脚都输出高
}
//发送玩每一个数据后,SCL 电平都为高
//开始传输
static void IIC_Start(void)
{
SDA_HIGH;
SCL_HIGH;
IIC_Delay(1);
SDA_LOW;
IIC_Delay(1);
SCL_LOW;//拉低准备发送数据
IIC_Delay(1);
}
//停止传输
static void IIC_Stop(void)
{
SCL_LOW;
IIC_Delay(1);
SDA_LOW;
IIC_Delay(1);
SCL_HIGH;
IIC_Delay(1);
SDA_HIGH;
}
//等待应答信号
static unsigned char IIC_WaitACK(void)
{
unsigned int ErrCnt=0;
SDA_HIGH;
SCL_HIGH;
IIC_Delay(1);
while(READ_SDA)
{
IIC_Delay(1);
if(++ErrCnt > 1000)
{
IIC_Stop();
return 1;
}
}
IIC_Delay(1);
SCL_LOW;
//IIC_Delay(1);
return 0;
}
//产生应答信号
static void IIC_WriteACK(unsigned char ack)
{
if(ack)
{
SDA_LOW;
}
else
{
SDA_HIGH;
}
IIC_Delay(1);
SCL_HIGH;
IIC_Delay(1);
SCL_LOW;
IIC_Delay(1);
SDA_HIGH;
IIC_Delay(1);
}
//mcu 发送数据
unsigned char IIC_SendByte(u8 data)
{
unsigned char i;
//SCL_LOW;
//IIC_Delay(1);
for(i=0;i<8;i++)
{
if(data&0x80)
{
SDA_HIGH;
}
else
{
SDA_LOW;
}
data<<=1;
IIC_Delay(1);
SCL_HIGH;
IIC_Delay(1);
SCL_LOW;
IIC_Delay(1);
}
return (IIC_WaitACK());
}
//mcu 接收数据
unsigned char IIC_ReceiveByte(void)
{
unsigned char i,data=0;
for(i=0;i<8;i++)
{
IIC_Delay(1);
SCL_HIGH;
IIC_Delay(1);
data<<=1;
if(READ_SDA)
{
data |= 0x1;
}
else
{
data &= ~0x1;
}
SCL_LOW;
IIC_Delay(1);
}
return data;
}
void AT24C02_Init(void)
{
MYIIC_Init();
AT24C02_test();
}
void AT24C02_ReadByte(u16 Addr,unsigned char *databuf,unsigned char len)
{
IIC_Start();
if(1==IIC_SendByte(0xA0)) return;
if(1==IIC_SendByte(Addr&255)) return;//发送地址
IIC_Start();
if(1==IIC_SendByte(0xA1)) return;
while(len != 0)
{
*(databuf++) = IIC_ReceiveByte();
if(--len == 0)
{
IIC_WriteACK(0);
}
else
{
IIC_WriteACK(1);
}
}
IIC_Stop();
return;
}
void AT24C02_WriteByte(u16 Addr, unsigned char *databuf,unsigned char len)
{
IIC_Start();
if(1==IIC_SendByte(0xA0)) return;
if(1==IIC_SendByte(Addr&255)) return;//发送地址
do
{
if(1==IIC_SendByte(*(databuf++))) return;
}while(--len != 0);
IIC_Stop();
//IIC_Delay(10000);//10ms
}
unsigned char IIC_Buf[10]={0xAA, 0xBB, 0x45, 0x78, 0x34, 0x78, 0x89,0xAC, 0xBC, 0xDD};
//unsigned char IIC_Buf1[10]={0};
void AT24C02_test(void)
{
AT24C02_WriteByte(0x0000, IIC_Buf, 10);
//AT24C02_ReadByte(0x0000,IIC_Buf1,10);
}