您的位置 首页 汽车

怎么使用AVR单片机完成AT24C256的数据高速安稳的读取

如何利用AVR单片机实现AT24C256的数据高速稳定的读取-最近刚买回一块AT24C256 EEPROM ,容量为32K Byte ,数据地址宽度为 16Bit ,支持IIC 1M (5V)400K (2.7V) 速度模式 ,利用AVR M16 片内IIC 可以高速稳定地读取数据! 经过调试的,与各位大虾分享分享。

最近刚买回一块AT24C256 EEPROM ,容量为32K Byte ,数据地址宽度为 16Bit ,支撑IIC 1M (5V)400K (2.7V) 速度形式 ,使用AVR M16 片内IIC 能够高速稳定地读取数据! 通过调试的,与各位大虾共享共享。


 

程序如下:(winavr)

#include

#include

#include

#include

#define FREQ 8

#include

#include

#include

#define uchar unsigned char

#define uint unsigned int

#define ulong unsigned long

//管脚界说

#define pinSCL 0 //PC0 SCL

#define pinSDA 1 //PC1 SDA

//为稳妥起见,最好在SCL/SDA接上1~10K的外部上拉电阻到VCC。

#define fSCL 1000000 //TWI时钟为1000KHz

//预分频系数=1(TWPS=0)

#if F_CPU 《 fSCL*36

#define TWBR_SET 2; //TWBR有必要大于等于10

#else

#define TWBR_SET (F_CPU/fSCL-16)/2; //核算TWBR值

#endif

#define TW_ACT (1《//TWCR只能IN/OUT,直接赋值比逻辑运算(|= &=)更节约空间

#define SLA_24CXX 0xA0 //24Cxx系列的厂商器材地址(高四位)

#define ADDR_24C256 0x00

// AT24C256的地址线A2/1/0悉数接地,SLAW=0xA0+0x00《《1+0x00,SLAR=0xA0+0x00《《1+0x01

//TWI_操作状况

#define TW_BUSY 0

#define TW_OK 1

#define TW_FAIL 2

//TWI_读写指令状况

#define OP_BUSY 0

#define OP_RUN 1

//TWI读写操作公共过程

#define ST_FAIL 0 //犯错状况

#define ST_START 1 //START状况查看

#define ST_SLAW 2 //SLAW状况查看

#define ST_WADDR_H 3 //ADDR状况查看

#define ST_WADDR_L 4 //ADDR状况查看

//TWI读操作过程

#define ST_RESTART 5 //RESTART状况查看

#define ST_SLAR 6 //SLAR状况查看

#define ST_RDATA 7 //读取数据状况查看,循环n字节

//TWI写操作过程

#define ST_WDATA 8 //写数据状况查看,循环n字节

#define FAIL_MAX 1 //重试次数最大值

void delay_nms(uint ms)//若干毫秒延时

{

int i;

for(i=0;i{

_delay_loop_2(FREQ*250);

}

}

unsigned char TWI_RW(unsigned char sla,unsigned int addr,unsigned char *ptr,unsigned int len);

unsigned char BUFFER[256]; //缓冲区

void Test(void);

struct str_TWI //TWI数据结构

{

volaTIle unsigned char STATUS; //TWI_操作状况

unsigned char SLA; //从设备的器材地址

unsigned char ADDR_H; //从设备的数据地址

unsigned char ADDR_L; //从设备的数据地址

unsigned char *pBUF; //数据缓冲区指针

unsigned int DATALEN; //数据长度

unsigned char STATE; //TWI读写操作过程

unsigned char FAILCNT; //失利重试次数

};

struct str_TWI strTWI; //TWI的数据结构变量

//AT24C256的读写函数(包含随机读,连续读,字节写,页写)

//依据sla的最低位决议(由中止程序中判别)

//bit0=1 TW_READ 读

//bit0=0 TW_WRITE 写

// sla 器材地址(不能搞错)

// addr EEPROM地址(0~32767)

// *ptr 读写数据缓冲区

// len 读数据长度(1~32768),写数据长度(1 or 8 or 16 or 32 or 64)

// 返回值 是否能履行当时操作

unsigned char TWI_RW(unsigned char sla,unsigned int addr,unsigned char *ptr,unsigned int len)

{

// unsigned char i;

if (strTWI.STATUS==TW_BUSY)

{//TWI忙,不能进行操作

return OP_BUSY;

}

strTWI.STATUS=TW_BUSY;

strTWI.SLA=sla;

strTWI.ADDR_H=(unsigned char)((addr》》8)&0xff);

strTWI.ADDR_L=(unsigned char)(addr&0xff);

strTWI.pBUF=ptr;

strTWI.DATALEN=len;

strTWI.STATE=ST_START;

strTWI.FAILCNT=0;

TWCR=(1《 return OP_RUN;

}

SIGNAL(SIG_2WIRE_SERIAL)

{//IIC中止

unsigned char acTIon,state,status;

acTIon=strTWI.SLA&TW_READ; //取操作形式

state=strTWI.STATE;

status=TWSR&0xF8; //屏蔽预分频位

if ((status》=0x60)||(status==0x00))

{//总线过错或从机形式引发的中止,不予处理

return;

}

switch(state)

{

case ST_START: //START状况查看

if(status==TW_START)

{//发送start信号成功

TWDR=strTWI.SLA&0xFE; //发送器材地址写SLAW

TWCR=TW_ACT; //触发下一步动作,一起清start发送标志

}

else

{//发送start信号犯错

state=ST_FAIL;

}

break;

case ST_SLAW: //SLAW状况查看

if(status==TW_MT_SLA_ACK)

{//发送器材高位地址成功

TWDR=strTWI.ADDR_H; //发送eeprom地址

TWCR=TW_ACT; //触发下一步动作

}

else

{//发送器材地址犯错

state=ST_FAIL;

}

break;

case ST_WADDR_H: //ADDR状况查看

if(status==TW_MT_DATA_ACK)

{//发送器材低位地址成功

TWDR=strTWI.ADDR_L; //发送eeprom地址

TWCR=TW_ACT; //触发下一步动作

}

else

{//发送器材地址犯错

state=ST_FAIL;

}

break;

case ST_WADDR_L: //ADDR状况查看

if(status==TW_MT_DATA_ACK)

{//发送eeprom地址成功

if (acTIon==TW_READ)

{//读操作形式

TWCR=(1《 }

else

{//写操作形式

TWDR=*strTWI.pBUF++; //写第一个字节

strTWI.DATALEN–;

state=ST_WDATA-1; //下一步将跳到WDATA分支

TWCR=TW_ACT; //触发下一步动作

}

}

else

{//发送eeprom地址犯错

state=ST_FAIL;

}

break;

case ST_RESTART: //RESTART状况查看,只要读操作形式才干跳到这儿

if(status==TW_REP_START)

{//发送restart信号成功

TWDR=strTWI.SLA; //发器材地址读SLAR

TWCR=TW_ACT; //触发下一步动作,一起清start发送标志

}

else

{//重发start信号犯错

state=ST_FAIL;

}

break;

case ST_SLAR: //SLAR状况查看,只要读操作形式才干跳到这儿

if(status==TW_MR_SLA_ACK)

{//发送器材地址成功

if (strTWI.DATALEN–)

{//多个数据

TWCR=(1《 }

else

{//只要一个数据

TWCR=TW_ACT; //设定NAK,触发下一步动作

}

}

else

{//发送器材地址犯错

state=ST_FAIL;

}

break;

case ST_RDATA: //读取数据状况查看,只要读操作形式才干跳到这儿

state–; //循环,直到读完指定长度数据

if(status==TW_MR_DATA_ACK)

{//读取数据成功,但不是最终一个数据

*strTWI.pBUF++=TWDR;

if (strTWI.DATALEN–)

{//还有多个数据

TWCR=(1《 }

else

{//预备读最终一个数据

TWCR=TW_ACT; //设定NAK,触发下一步动作

}

}

else if(status==TW_MR_DATA_NACK)

{//现已读完最终一个数据

*strTWI.pBUF++=TWDR;

TWCR=(1《 strTWI.STATUS=TW_OK;

}

else

{//读取数据犯错

state=ST_FAIL;

}

break;

case ST_WDATA: //写数据状况查看,只要写操作形式才干跳到这儿

state–; //循环,直到写完指定长度数据

if(status==TW_MT_DATA_ACK)

{//写数据成功

if (strTWI.DATALEN)

{//还要写

TWDR=*strTWI.pBUF++;

strTWI.DATALEN–;

TWCR=TW_ACT; //触发下一步动作

}

else

{//写够了

TWCR=(1《 strTWI.STATUS=TW_OK;

//发动写指令后需求10ms(最大)的编程时刻才干真实的把数据记录下来

//编程期间器材不响应任何指令

}

}

else

{//写数据失利

state=ST_FAIL;

}

break;

default:

//过错状况

state=ST_FAIL;

break;

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/346756.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部