当前位置:文档之家› AVR与AT24C256I2C程序(TWI)

AVR与AT24C256I2C程序(TWI)

AVR与AT24C256I2C程序(TWI)
AVR与AT24C256I2C程序(TWI)

/*调试通过20130202

24c256连续读取多个数据.多写,可单读单写

*/

#include

#include

//数据类型预定义8位,16位整数

#define INT8U unsigned char

#define INT16U unsigned int

# define F_CPU 7372800UL

/* TWSR values (not bits) */

/* Master */

#define I2C_START 0x08

#define I2C_RESTART 0x10

/* Master Transmitter */

#define I2C_MT_SLA_ACK 0x18 //?

#define I2C_MT_SLA_NACK 0x20 //? #define I2C_MT_DA TA_ACK 0x28

#define I2C_MT_DA TA_NACK 0x30 //?

#define I2C_MT_ARB_LOST 0x38 //? /* Master Receiver */

#define I2C_MR_ARB_LOST 0x38 //? #define I2C_MR_SLA_ACK 0x40

#define I2C_MR_SLA_NACK 0x48 //? #define I2C_MR_DA TA_ACK 0x50 //? #define I2C_MR_DA TA_NACK 0x58 //?

/* Slave Transmitter */

#define I2C_ST_SLA_ACK 0xA8 //?

#define I2C_ST_ARB_LOST_SLA_ACK 0xB0 //?

#define I2C_ST_DA TA_ACK 0xB8 //? #define I2C_ST_DA TA_NACK 0xC0 //?

#define I2C_ST_LAST_DATA 0xC8 //?

/* Slave Receiver */

#define I2C_SR_SLA_ACK 0x60 //?

#define I2C_SR_ARB_LOST_SLA_ACK 0x68 //? #define I2C_SR_GCALL_ACK 0x70 //?

#define I2C_SR_ARB_LOST_GCALL_ACK 0x78//? #define I2C_SR_DA TA_ACK 0x80 //? #define I2C_SR_DA TA_NACK 0x88 //?

#define I2C_SR_GCALL_DATA_ACK 0x90 //? #define I2C_SR_GCALL_DATA_NACK 0x98 //? #define I2C_SR_STOP 0xA0 //?

/* Misc */

#define I2C_NO_INFO 0xF8 //?

#define I2C_BUS_ERROR 0x00 //?

/*

* The lower 3 bits of TWSR are reserved on the ATmega163.

* The 2 LSB carry the prescaler bits on the newer ATmegas.

*/

#define I2C_STATUS_MASK

(_BV(TWS7)|_BV(TWS6)|_BV(TWS5)|_BV(TWS4)|_BV(TWS3))

#define I2C_STATUS (TWSR & I2C_STA TUS_MASK)

/*

* R/~W bit in SLA+R/W address field.

*/

#define I2C_READ 1

#define I2C_WRITE 0

#define I2CStart() (TWCR=(1<

#define I2CStop() (TWCR=(1<

#define I2CWaitAck() {while(!(TWCR&(1<

#define I2CChkAck() (TWSR&0xf8) //check ack

#define I2CSendAck() (TWCR|=(1<

#define I2CSendNoAck() (TWCR&=~(1<

#define I2CSendByte(x) {TWDR=(x);TWCR=(1<

#define I2CRcvNckByte() (TWCR=(1<

#define I2CRcvAckByte() (TWCR=(1<

/* For Program */

#define I2C_Stop() I2CStop()

#define I2C_SendAck() I2CSendAck()

#define I2C_SendNoAck() I2CSendNoAck()

#define I2C_WaitAck() I2CWaitAck()

/* I2C Config */

#define I2C_ERR 0

#define I2C_CRR 1

//char data1;//为观察读取的数据的临时观察变量

#ifndef WR_DADR

#define WR_DADR 0xa0 //write device-address

#endif

#ifndef RD_DADR

#define RD_DADR 0xa1 //read device-address

#endif

//#define AT24CXX_ERR 0

//#define AT24CXX_CRR 1

//****************************** twi 初始化************************************* // TWCR: 控制寄存器,用来控制TWI操作,说明如下:

// Bit 7-TWINT:中断标志位,Bit 6-TWEA:使能应答位,Bit 5-TWSTA:START状态位// Bit 4-TWSTO:STOP状态位,Bit 3-TWWC: 写冲突标志,Bit 2-TWEN:TWI使能位

// Bit 1-RES:保留,Bit 0-TWIE:中断使能

// TWSR: 状态寄存器,Bits 7..3:表示了TWI总线的当前状态,读取时需屏蔽低三位的值,Bits 1..0-TWPS:TWI预分频位

// TWBR: 比特率寄存器,用来设置TWI的工作频率,计算公式为:SCL=CPU频率/(16+2*(TWBR)*4TWPS),TWPS在4的指数位置

// TWAR: 从机地址寄存器,Bits 7..1:存放从机地址,Bit 0:最低位为广播识别使能位

// TWDR: 数据寄存器,用来存放接收或要发送的地址和数据

//***************************************************************************** *

void twi_init(void)

{

TWBR=1;

TWSR=0;

TWCR=0x44;

}

/*--------------------------------------------------------------------

程序名称:I2C Start

程序功能:

注意事项:

提示说明:

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_Start()

{

I2CStart();

I2CWaitAck(); //202页第二步等待

if( I2CChkAck()!=I2C_START ) //202页第三步开始启动传输

return I2C_ERR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C ReStart

程序功能:

注意事项:

提示说明:

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_Restart()

{

I2CStart();

I2CWaitAck();

if( I2CChkAck()!=0x10 )

return I2C_ERR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)发送7位器件写地址: XXXX XXX0

程序功能:

注意事项:

提示说明:

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_SendWrDAdr(INT8U wrDAdr) //wrDAdr相当于202页表中提到的sla_w

{

I2CSendByte(wrDAdr); //202页第四步1 .将SLA_W载入到TWDR 寄存器,TWINT位清零,启动发送地址设置器件写地址

I2CWaitAck(); //202页第四步2 等待TWINT 置位,TWINT置位表示总线命令SLA+W 已发出,及收到应答信号ACK/NACK

if((TWSR&0xf8) != 0x18) //202页表中第5步检验TWI 状态寄存器,屏蔽预分频位,如果状态字不是MT_SLA_ACK 转出错处理

return I2C_ERR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)发送10位器件写地址: 1111 0XX0, XXXX XXXX

程序功能:

注意事项:

提示说明:兼容发送7位器件写地址: XXXX XXX0

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_SendWrDAdr_(INT16U wrDAdr)

{

if((wrDAdr & 0xf000) == 0xF000) //判断是否为10位器件地址

if(I2C_SendWrDAdr((INT8U)wrDAdr>>8 )==I2C_ERR) //设置(高位)器件写地址return I2C_ERR;

if( I2C_SendWrDAdr((INT8U)wrDAdr)==I2C_ERR) //设置(低位)器件写地址return I2C_ERR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)发送7位器件读地址: XXXX XXX1

程序功能:

注意事项:

提示说明:

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_SendRdDAdr(INT8U rdDAdr)

{

I2CSendByte(rdDAdr); //设置器件读地址

I2CWaitAck();

if( I2CChkAck()!=I2C_MR_SLA_ACK )//I2C_MR_SLA_ACK=0x40

return I2C_ERR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)发送10位器件读地址: 1111 0XX0, XXXX XXXX

程序功能:

注意事项:

提示说明:

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_SendRdDAdr_(INT8U rdDAdr)

{

if( rdDAdr&0xf000 ==0xf000 ) //判断是否为10位器件地址

if( I2C_SendWrDAdr((INT8U)rdDAdr>>8)==I2C_ERR) //设置(高位)器件读地址return I2C_ERR;

if( I2C_SendWrDAdr((INT8U)rdDAdr)==I2C_ERR) //设置(低位)器件读地址return I2C_ERR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)发送数据

程序功能:

注意事项:

提示说明:

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_SendDat(INT8U configDat) //原先位16位

{

I2CSendByte(configDat);

I2CWaitAck();

if( I2CChkAck()!=I2C_MT_DATA_ACK )

return I2C_ERR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)接收数据且不产生应答

程序功能:只读一个字节,然后停止读取

注意事项:

提示说明:读取一个字节后,发送不响应,用于读取1个字节

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_RcvNAckDat(INT8U *pRdDat)

{

I2CRcvNckByte();

I2CWaitAck();

if(I2CChkAck()!=I2C_MR_DATA_NACK)//接收到数据0x58

return I2C_ERR;

*pRdDat=TWDR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)接收数据且产生应答

程序功能:用于连续读取,读取单个字节后,在读下一个字节.最后读取n个字节后,再停止. 注意事项:

提示说明:读取一个字节后,发送响应,用于读取多个字节

输入:

返回:

--------------------------------------------------------------------*/

INT8U I2C_RcvAckDat(INT8U *pRdDat)

{

I2CRcvAckByte();

I2CWaitAck();

if( I2CChkAck()!=0x50)

return I2C_ERR;

*pRdDat=TWDR;

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)写器件,写一个数据

程序功能:

注意事项:

提示说明:

输入:wrDAdr: write device-address 写器件地址

wordAdr: word address 字地址

dat: data 数据

返回:

INT8U I2CWriteByte(INT8U wrDAdr,INT16U wordAdr,INT8U dat)

{

if( I2C_Start()==I2C_ERR )

return I2C_ERR;

if( I2C_SendWrDAdr_(wrDAdr)==0)

return I2C_ERR;

if( I2C_SendDat((wordAdr&0xff00)>>8)==I2C_ERR )

return I2C_ERR;

if( I2C_SendDat(wordAdr&0x00ff)==I2C_ERR )

return I2C_ERR;

if( I2C_SendDat(dat)==0 )

return I2C_ERR;

I2C_Stop();

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)写器件,写N个数据

程序功能:

注意事项:

提示说明:

输入:wrDAdr: write device-address 写器件地址

wordAdr: word address 存储数据的起始地址

*pWrDat: p->write data 写入数据指针

num: number 写入数据个数

返回:

--------------------------------------------------------------------*/

INT8U I2CWriteStr(INT8U wrDAdr,INT16U wordAdr,INT8U *pWrDat,INT8U num) {

INT16U i;

if( I2C_Start()==I2C_ERR )

return I2C_ERR;

if( I2C_SendWrDAdr_(wrDAdr)==0)

return I2C_ERR;

if( I2C_SendDat((wordAdr&0xff00)>>8)==I2C_ERR )

return I2C_ERR;

if( I2C_SendDat(wordAdr&0x00ff)==I2C_ERR )

return I2C_ERR;

for (i=0;i

if(I2C_SendDat(*(pWrDat+i))==0)

return I2C_ERR;

I2C_Stop();

return I2C_CRR;

}

程序名称:I2C(TWI)读器件,读一个数据

程序功能:

注意事项:

提示说明:

输入:wrDAdr: write device-address 写器件地址

wordAdr: word address 字地址

rdDAdr: read device-address 读器件地址

*pRdDat: p->read data 读取数据指针

返回:

--------------------------------------------------------------------*/

INT8U I2CReadByte(INT8U wrDAdr,INT16U wordAdr,INT8U rdDAdr,INT8U *pRdDat)

{

if( I2C_Start()==I2C_ERR )

return I2C_ERR;

if( I2C_SendWrDAdr_(wrDAdr)==I2C_ERR )

return I2C_ERR;

////16位地址拆分

if( I2C_SendDat((wordAdr&0xff00)>>8)==I2C_ERR )

return I2C_ERR;

if( I2C_SendDat(wordAdr&0x00ff)==I2C_ERR )

return I2C_ERR;

if( I2C_Restart()==I2C_ERR )

return I2C_ERR;

if( I2C_SendRdDAdr(rdDAdr)==I2C_ERR )

return I2C_ERR;

if( I2C_RcvNAckDat(pRdDat)==I2C_ERR )

return I2C_ERR;

I2C_Stop();

return I2C_CRR;

}

/*--------------------------------------------------------------------

程序名称:I2C(TWI)读器件,读N个数据

程序功能:

注意事项:

提示说明:

输入:wrDAdr: write device-address 写器件地址

wordAdr: word address 存储数据的起始地址

rdDAdr: read device-address 读器件地址

*pRdDat: p->read data 读取数据指针

num: number 读取数据个数

返回:

--------------------------------------------------------------------*/

INT8U I2CReadStr(INT8U wrDAdr,INT16U wordAdr,INT8U rdDAdr,INT8U *pRdDat,INT8U

num)

{

INT8U i;

if( I2C_Start()==I2C_ERR )

return I2C_ERR;

if( I2C_SendWrDAdr_(wrDAdr)==I2C_ERR )

return I2C_ERR;

//16位24c256存储空间地址拆分

if( I2C_SendDat((wordAdr&0xff00)>>8)==I2C_ERR ) return I2C_ERR;

if( I2C_SendDat(wordAdr&0x00ff)==I2C_ERR ) return I2C_ERR;

if( I2C_Restart()==I2C_ERR )

return I2C_ERR;

if( I2C_SendRdDAdr(rdDAdr)==I2C_ERR )

return I2C_ERR;

for(i=0;i

if( I2C_RcvAckDat(pRdDat+i)==I2C_ERR )

return I2C_ERR;

if( I2C_RcvNAckDat(pRdDat+i)==I2C_ERR )

return I2C_ERR;

I2C_Stop();

return I2C_CRR;

}

//

int main(void)

{

int i;

INT8U data2[256]={0};

INT8U data21[256]={0};

INT8U data3[]={

0x11,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x2e, 0x65,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x3e, 0x75,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x4e, 0x85,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x5e, 0x95,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x6e, 0x05,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x11, 0x54,0x88,0x1,0x1,

0x11,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x2e, 0x65,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x3e, 0x75,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x4e, 0x85,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x5e, 0x95,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x6e, 0x05,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x11,

0x54,0x88,0x1,0x1,

0x11,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x2e,

0x65,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x3e,

0x75,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x4e,

0x85,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x5e,

0x95,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x6e,

0x05,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x11,

0x54,0x88,0x1,0x1,

0x11,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x2e,

0x65,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x3e,

0x75,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x4e,

0x85,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x5e,

0x95,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x6e,

0x05,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x11,

0x54,0x88,0x1,0x1

//0x14,0x1a,0x1b,0x1c,0x1d,0x1e

};

INT8U data4[64]={

0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,

0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,

0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,

0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,

0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,

0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99,0xaa,

0x11,0x22,0x33,0x44

//0x14,0x1a,0x1b,0x1c,0x1d,0x1e

};

INT8U data5[64]={

0xaa,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11, 0xaa,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11,

0xaa,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11,

0xaa,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11,

0xaa,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11,

0xaa,0x99,0x88,0x77,0x66,0x55,0x44,0x33,0x22,0x11,

0xbb,0xcc,0xdd,0xee

//0x14,0x1a,0x1b,0x1c,0x1d,0x1e

};

INT8U data6[64]={

0x55,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x2e,

0x65,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x3e,

0x75,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x4e,

0x85,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x5e,

0x95,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x6e,

0x05,0x68,0xde,0xab,0xc4,0xaa,0xbb,0xcc,0xdd,0x7e,

0x55,0x12,0x4,0x4

//0x14,0x1a,0x1b,0x1c,0x1d,0x1e

};

INT8U dat1[1];

char c;

while(1)

{

twi_init();

_delay_ms(400);

I2CWriteStr(0xa0,0x0000,data4,64);

_delay_ms(400);

I2CWriteStr(0xa0,0x0040,data5,64);

_delay_ms(400);

I2CWriteStr(0xa0,0x0080,data6,64);

_delay_ms(400);

I2CReadStr(0xa0,0x0000,0xa1,data2,64);//多读

_delay_ms(400);

I2CReadStr(0xa0,0x0040,0xa1,data2,64);//多读

_delay_ms(400);

I2CReadStr(0xa0,0x0080,0xa1,data2,64);//多读

_delay_ms(400);

I2CReadStr(0xa0,0x0000,0xa1,data2,64);//多读

_delay_ms(400);

for (i=0;i<192;i++)

{

I2CWriteByte(0xa0,0x2000+i,0x05);//写入地址0x0001中一个数据0x64 _delay_ms(250);//延时十分必要

}

I2CReadStr(0xa0,0x2000,0xa1,data2,192);//多读

_delay_ms(400);

I2CReadStr(0xa0,0x2000,0xa1,data2,256);//多读

_delay_ms(400);

I2CReadStr(0xa0,0x2000,0xa1,data2,256);//多读

_delay_ms(400);

}

}

相关主题
文本预览
相关文档 最新文档