⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 at24c64drive.c

📁 用ATMEGA16中的TWI总路线实现的AT24C64驱动程序,功能:实现单字节,多字节,多页读写
💻 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 + -