📄 at24cxx.c
字号:
#include <pic.h>
#include"PIC16F91X.h"
#include "at24cxx.h"
#define ADDR_AT24C64 0XA0
//IIC物理层/////////////////////////////////////////////////////////////////
//IIC物理层/////////////////////////////////////////////////////////////////
//IIC物理层/////////////////////////////////////////////////////////////////
//初始化本模块
void TwiInit(void)
/*
功能:初始化IIC模块
*/
{
bsf(TRISD, SCL);
bsf(TRISD,SDA);
}
void Twi_ack(unsigned char ack)
/*
功能:发送返回位.
参数:ack=1,发送应答位;ack=0,发送非应答位.
*/
{
if(!ack) //非应答
SDA_IN;
else //应答
CLR_SDA;
NOP();NOP();NOP();
SCL_IN;
NOP();NOP();NOP();NOP();//NOP();NOP();
CLR_SCL;
NOP();NOP();//NOP();NOP();NOP();NOP();
}
void TwiStart(void)
//功能:产生IIC起始信号.
{
SDA_IN; NOP();
SCL_IN; NOP();NOP();NOP();NOP();NOP();
CLR_SDA; NOP();NOP();NOP();NOP();NOP();
CLR_SCL; NOP();NOP();
}
void TwiStop(void)
//功能:产生IIC停止信号.
{
CLR_SDA; NOP();
SCL_IN; NOP();NOP();NOP();NOP();NOP();
SDA_IN; NOP();NOP();NOP();NOP();
}
unsigned char TwiWriteByte(unsigned char c)
/*
功能:向总线写一字节,并返回有无应答
返回:0--失败,1--成功
*/
{
unsigned char i,ack;
for(i=0;i<8;i++)
{
if((c<<i)&0x80)
{ SDA_IN;}
else
{ CLR_SDA;}
NOP();
SCL_IN; NOP();NOP();NOP();NOP();NOP();NOP();
CLR_SCL;
}
NOP();NOP();
SDA_IN; NOP();NOP(); //NOP();NOP();NOP();NOP();
SCL_IN; NOP();NOP();NOP();
if(SDA)
ack=0; //失败
else
ack=1;
CLR_SCL; NOP();NOP(); //NOP();NOP();NOP();NOP();
return ack;
}
unsigned char TwiReadByte(unsigned char *c, unsigned char ack)
//读一字节 ack: 1时应答,0时不应答
{
unsigned char i,ret;
ret=0;
SDA_IN;
for(i=0;i<8;i++)
{
NOP();
CLR_SCL; NOP();NOP();NOP();NOP();NOP();
SCL_IN; NOP();NOP();
ret<<=1;
if(SDA)
ret++;
NOP();NOP();
}
CLR_SCL; NOP();NOP();
Twi_ack(ack);
*c=ret;
return(ret);
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
void At24cxxWaitBusy(void)
/*
器件忙检测,原理:器件忙时不会对主机的写操作应答,
忙检测接口函数,只有一种情况才需要调用这个函数,
即:当刚写完成,要读数据时,而连续的读或者写操作之间不需要调用这个函数.
*/
{
unsigned char i;
while(1)
{
TwiStart();
i=TwiWriteByte(ADDR_AT24C64);
TwiStop();
if(i==NO_BUSY)
break;
}
return ;
}
void At24WriteStr(unsigned int addr,unsigned char *dat,unsigned char length)
/*
功能:写AT24C64数据
参数:addr-->数据块起始地址,dat-->所要写的数据缓冲区首址,所要写的数据长度.
注意:由于at24c64的每一页为32字节,所以每次写入数据不可超过下一页
改进:添加返回是否写入成功.
*/
{
unsigned char i;
At24cxxWaitBusy();
EEPROM_WRITE_ENABLE;
TwiStart();
TwiWriteByte(ADDR_AT24C64);
TwiWriteByte((unsigned char)(addr>8));//写地址高字节
TwiWriteByte((unsigned char)addr);//写地址低字节
for(i=0;i<length;i++)
TwiWriteByte(dat[i]);//写数据字节
TwiStop();
EEPROM_WRITE_DISABLE;
}
void At24ReadStr(unsigned int addr,unsigned char *dat,unsigned char len)
/*
功能:读AT24C64数据
参数:addr-->数据块起始地址,dat-->所读的数据缓冲区首址,所读的数据长度.
*/
{
unsigned char i;
At24cxxWaitBusy();
TwiStart();
TwiWriteByte(ADDR_AT24C64);
TwiWriteByte((unsigned char)(addr>>8));
TwiWriteByte((unsigned char)addr);
TwiStart();
TwiWriteByte(ADDR_AT24C64| TW_READ);
for(i=0;i<len-1;i++)
{
TwiReadByte(dat++,TW_ACK);
}
TwiReadByte(dat,TW_NOACK);//NO ACK
TwiStop();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -