📄 at24c64drive.c
字号:
/*-------------------------------------------------
----------------------陈晓涛-----------------------
---------------------------------------------------
名称:TWI总路线实现的AT24C64驱动程序
功能:实现单字节,多字节,多页读写
说明:晶振为内部1MHZ,SDA和SCL分别接10K上拉电阻,
AT24C64 A2-0悬空 写保护端悬空
时间:2007年8月26日
--------------------------------------------------*/
#include "iom16.h"
#include"intrinsics.h"
#define uchar unsigned char
#define uint unsigned int
#define SLA_W 0XA0 //芯片写地址
#define SLA_R 0XA1 //芯片读地址
#define twbr 0 //时钟频率分频系数
/*-------------------------------------------------
---------------产生TWI时序的函数-------------------
-------------------------------------------------*/
void start(void); //启动
void restart(void); //重新启动
void stop(void); //停止
void SLA_WEN(void); //芯片写使能
void SLA_REN(void); //芯片读使能
void write_addr(uint addr);//操作地址写入
void data_in(void); //控制数据写入
void currentdata_out(void);//控制非末尾的数据读出控制
void lastdata_out(void); //最后一数据读出控制
/*--------------------------------------------------
-------------------功能函数-------------------------
--------------------------------------------------*/
void error(uchar type) ;
void writechar(uint addr, uchar data); //写一字节
void writechars(uint addr,uchar *data,uchar num) ;//写32个以内的字符串
void writepages(uint addr,uchar *data,uint num); //写32个以上的字符串
void readchar(uint addr,uchar *data); //读一字节
void readanychars(uint addr,uchar *data,uint num);//读任意多个字节
/*-------------------------------------------------
---------------------试验程序----------------------
-------------------------------------------------*/
uchar b[11];
uchar f[]="OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO";
uchar e[256];
uchar temp;
void main(void)
{
writechar(0x0000, 'L');
readchar(0x0000,&temp);
writechars(0x0001,"YULUIBIN",8);
readanychars(0x0001,b,8);
writepages(0x0220,f,256);
readanychars(0x0220,e,256);
while (1) ;
}
/*--------------------START函数-------------------------*/
void start(void)
{
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);//start 启动
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x08)
error(TWSR);
}
/*-------------------RESTART函数-----------------------*/
void restart(void)
{
TWCR = (1 << TWINT) | (1 << TWSTA) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x10)
error(TWSR);
}
/*------------------stop时序产生语句-----------------------*/
void stop(void)
{
TWCR = (1 << TWINT) | (1 << TWEN) | (1 << TWSTO);
}
/*----------------------芯片写使能函数----------------------*/
void SLA_WEN(void)
{
TWDR = SLA_W; // 芯片地址
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x18)
error(TWSR);
}
/*----------------------芯片读使能函数---------------------*/
void SLA_REN(void)
{
TWDR = SLA_R; // 芯片读地址
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x40)
error(TWSR);
}
/*---------------------操作地址写入----------------------*/
void write_addr(uint addr)
{
TWDR = addr/256; //高8位
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x28)
error(TWSR);
TWDR = addr%256; //低8位
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x28)
error(TWSR);
}
/*----------------------控制数据写入函数-------------------*/
void data_in(void)
{
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x28)
error(TWSR);
}
/*----------------控制非末尾的数据读出控制----------------*/
void currentdata_out(void)
{
TWCR = (1 << TWINT) | (1 << TWEN)|(1<<TWEA);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x50)
error(TWSR);
}
/*-------------------最后一数据读出控制--------------------*/
void lastdata_out(void)
{
TWCR = (1 << TWINT) | (1 << TWEN);
while (!(TWCR & (1 << TWINT)));
if ((TWSR & 0xF8) != 0x58)
error(TWSR);
}
/*---------------I2C总线主机模式错误处理--------------------*/
void error(unsigned char type)
{
switch (type & 0xF8)
{
case 0x20: /*址址写失败*/
stop();break;
case 0x30: /*数据写失败*/
stop();break;
case 0x38: /*仲裁失败*/
break;
case 0x48: /*址址读失败*/
stop();break;
}
}
/*-------------------单字节写入----------------------*/
void writechar(uint addr, uchar data)
{
TWBR =0; //比特率设置为50K
start(); //产生开始时序
SLA_WEN(); //芯片写使能
write_addr(addr);//addr 操作地址
/*dd 写入数据*/
TWDR = data;
data_in(); //将TWDR中的数据写入E2PROM中
stop();
}
///////////////////////////////////////////////////////
/*--------------------单字节读取--------------------*/
void readchar(uint addr,uchar *data)
{
TWBR =0; //比特率设置为50K
start(); //产生开始时序
SLA_WEN(); //芯片写使能
write_addr(addr); //addr 操作地址
restart(); //restart时序
SLA_REN(); //芯片读使能
lastdata_out(); //最后一位数据读出
*data = TWDR;
stop();
}
//////////////////////////////////////////////////////
/*----------------32个以内字节写入------------------*/
void writechars(uint addr, uchar *data ,uchar num)
{
uchar i;
TWBR =0; //比特率设置为50K
start(); //产生开始时序
SLA_WEN(); //芯片写使能
write_addr(addr); //addr 操作地址
/*data写入数据*/
for(i=0;i<num;i++)
{
TWDR = *(data+i);
data_in(); //将TWDR中的数据写入E2PROM中
}
stop();
}
//////////////////////////////////////////////////////
/*---------------------------------------------------
---------------------多页写入------------------------
---------------------------------------------------*/
void writepages(uint addr,uchar *data,uint num)
{
while(num>=32)
{
writechars(addr,data,32);//写入一页32个数据
__delay_cycles(2000); //完成一页写入后内部所须时间
addr+=32;
data+=32;
num-=32;
}
writechars(addr,data,num);//余下不够一页的数据写入
}
/////////////////////////////////////////////////////
/*-------------------多字节读取--------------------*/
void readanychars(uint addr,uchar *data,uint num)
{
uint i;
TWBR =0; //比特率设置为50K
start(); //产生开始时序
SLA_WEN(); //芯片写使能
write_addr(addr); //addr 操作地址
restart(); //restart时序
SLA_REN(); //芯片读使能
/*读取数据*/
for(i=0;i<num-1;i++)
{
currentdata_out(); //非末位数据读出控制
*(data+i) = TWDR;
}
lastdata_out(); //最后一位数据读出
*(data+num-1) = TWDR;
/*stop 停止*/
stop();
}
//////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -