|
楼主 |
发表于 2008-4-18 20:15:05
|
显示全部楼层
/*---------------------------------readme first---------------------------------
--CPU:ATmega48
--GCCAVR20070525下编译通过
--刘海成 2007-8
--ATmega48模拟24系列EEPROM
------------------------------------------------------------------------------*/
#include <avr/io.h>
#include <avr/interrupt.h>
volatile unsigned char IIC_STATE; //IIC通信状态机
#define STATE_IIC_ADDR 0xc3
#define STATE_IIC_WDATA 0xa5
#define STATE_IIC_RDATA 0x5a
#define STATE_IIC_STOP 0
volatile unsigned char IIC_ADDR,IIC_DATA; //当前数据
//------------------------------------------------------------------------------
//------------------------------TWI状态定义-------------------------------------
#define SLA_Device_Addr 0xa0 //定义器件地址
//SR 从机方式接收 ST 从机方式传输 ALL 广播
#define SR_SLA_ACK 0x60
#define SR_ALL_ACK 0x70
#define SR_DATA_ACK 0X80
#define SR_DATA_NOACK 0X88
#define SR_ALL_DATA_ACK 0x90
#define SR_ALL_DATA_NOACK 0x98
#define SR_STOP_RESTART 0xa0
#define ST_SLA_ACK 0xa8
#define ST_DATA_ACK 0xb8
#define ST_DATA_NOACK 0xc0
#define ST_LAST_DATA_ACK 0xc8
//常用TWI操作(从模式写和从模式读)
#define Twi_STATE() (TWSR&0xf8)
#define SLA_autoACK() (TWCR=(1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE))
#define SLA_Send8Bit(x) {TWDR=(x);TWCR=(1<<TWEA)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE);}
#define SLA_Resume() (TWCR=(1<<TWEA)|(1<<TWSTO)|(1<<TWINT)|(1<<TWEN)|(1<<TWIE))
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void Chip_Init(void)
{ //IIC初始化
TWAR=SLA_Device_Addr;//set slave address,不使用广播地址
TWCR=0x45; //使能IIC,并开中断
asm("sei"); //开总中断
}
//------------------------------------------------------------------------------
unsigned char eeprom_read_byte(unsigned char uiAddress)
{while(EECR&(1<<EEPE))//等待上一次写操作结束
#define EEARH _SFR_IO8 (0x22)
EEARH=0x00;
EEARL=uiAddress; //设置地址寄存器
EECR|=(1<<EERE); //设置EERE以启动读操作
return EEDR;
}
//------------------------------------------------------------------------------
int main(void)
{
Chip_Init();
while(1)
{ ;
}
}
//------------------------------------------------------------------------------
ISR(TWI_vect)
{unsigned char nc;
nc=Twi_STATE();
if(nc==SR_SLA_ACK) //从地址匹配,写传输,ACK已返回
{ IIC_STATE=STATE_IIC_ADDR; //下一步接收数据的地址
SLA_autoACK();
}
else if(nc==SR_DATA_ACK)//接收主机送来的从机数据地址或数据,ACK已返回
{ if(IIC_STATE==STATE_IIC_ADDR) //如果是地址
{IIC_ADDR=TWDR;
IIC_STATE=STATE_IIC_WDATA; //下一步接收数据
}
else //IIC_nextSTATE==STATE_IIC_WDATA:
{ IIC_DATA=TWDR;
while(EECR&(1<<EEPE));//等待上一次写操作结束
EEARH=0x00;
EEARL=IIC_ADDR++; //地址自动+1
EEDR=IIC_DATA;
EECR|=(1<<EEMPE);
EECR|=(1<<EEPE); //置位EEPE以启动写操作E
}
SLA_autoACK();
}
else if((nc==ST_SLA_ACK)||(nc==ST_DATA_ACK))//从地址匹配,读传输,或者是
{ //TWDR里数据已经发送,接收到ACK
IIC_STATE=STATE_IIC_RDATA;
IIC_DATA=eeprom_read_byte(IIC_ADDR++); //地址自动+1
SLA_Send8Bit(IIC_DATA); //发送数据
}
else if(nc==ST_DATA_NOACK) //TWDR里数据已经发送,接收到NOTACK
{
IIC_STATE=STATE_IIC_STOP;
SLA_autoACK();
}
else if(nc==SR_STOP_RESTART) //主机写命令结束或读命令重新开始
{
SLA_autoACK();
}
else
{
SLA_Resume();//从机模式到未被寻址状态,恢复TWI响应能力
}
}
//------------------------------------------------------------------------------ |
|