//ICC-AVR application builder : 2010-3-5 13:51:50
// Target : M88
// Crystal: 8.0000Mhz
#include
#include
#include
//I2C(TWI)基本指令
#define I2C_START() TWCR = BIT(TWINT)|BIT(TWEN)|BIT(TWSTA)
#define I2C_STOP() TWCR = BIT(TWINT)|BIT(TWEN)|BIT(TWSTO)
#define I2C_ACK() TWCR = BIT(TWINT)|BIT(TWEN)|BIT(TWEA)
#define I2C_NAK() TWCR = BIT(TWINT)|BIT(TWEN)
#define I2C_CHECK_STATUS(X) {while(!(TWCR&BIT(TWINT))); if((TWSR&0xF8)!=(X)) return 0;}
#define I2C_WRITE(X) TWDR = (X)
#define I2C_READ(X) (X) = TWDR
//TWSR&0xF8 状态码
#define START 0x08
#define RE_START 0x10
#define MT_SLA_ACK 0x18
#define MT_SLA_NAK 0x20
#define MT_DATA_ACK 0x28
#define MT_DATA_NAK 0x30
#define SLA_DATA_FAIL 0x38
#define MR_SLA_ACK 0x40
#define MR_SLA_NAK 0x48
#define MR_DATA_ACK 0x50
#define MR_DATA_NAK 0x58
//器件地址及参数
#define SLA_R_24C64 0xA1
#define SLA_W_24C64 0xA0
#define PAGE_SIZE_24C64 32
#define NUM_PAGE_24C64 256
#define SLA_R_PCF8563 0xA3
#define SLA_W_PCF8563 0xA2
#define PAGE_SIZE_PCF8563 16
#define NUM_PAGE_PCF8563 1
//毫秒级延时
void delay_ms(unsigned int x)
{
int i,j;
for(j=0;j>8);
I2C_NAK();
I2C_CHECK_STATUS(MT_DATA_ACK);
}
I2C_WRITE((unsigned char)ADDR);
I2C_NAK();
I2C_CHECK_STATUS(MT_DATA_ACK);
for(i=0;i>8);
I2C_NAK();
I2C_CHECK_STATUS(MT_DATA_ACK);
}
I2C_WRITE((unsigned char)ADDR);
I2C_NAK();
I2C_CHECK_STATUS(MT_DATA_ACK);
I2C_START();
I2C_CHECK_STATUS(RE_START);
I2C_WRITE(SLA_R);
I2C_NAK();
I2C_CHECK_STATUS(MR_SLA_ACK);
if(N>1)
{
for(i=0;iNUM_PAGE-1)
{
//not enough memory
return;
}
PAGE=ADDR/PAGE_SIZE;
NBYTES[0]=(PAGE+1)*PAGE_SIZE-ADDR;
NBYTES[1]=(ADDR+N)-(END_PAGE*PAGE_SIZE);
if(NBYTES[0])
{
i2c_write_n_bytes(SLA_W,ADDR,NBYTES[0],DAT);
//delay_ms(10);//仿真时用延时代替器件忙检测
while(i2c_check_busy(SLA_W));//器件忙检测
}
if(END_PAGE>PAGE)
{
i=0;
while(END_PAGE>++PAGE)
{
i2c_write_n_bytes(SLA_W,(PAGE*PAGE_SIZE),PAGE_SIZE,(DAT+NBYTES[0]+(i++)*PAGE_SIZE));
//delay_ms(10);//仿真时用延时代替器件忙检测
while(i2c_check_busy(SLA_W));//器件忙检测
}
if(NBYTES[1])
{
i2c_write_n_bytes(SLA_W,(PAGE*PAGE_SIZE),NBYTES[1],(DAT+NBYTES[0]+i*PAGE_SIZE));
//delay_ms(10);//仿真时用延时代替器件忙检测
while(i2c_check_busy(SLA_W));//器件忙检测
}
}
}
/************************************************************************
I2C主机从从器件(EEPROM)读N字节数据
编程:许工 QQ11520389
时间:2010.03.05
参数说明:
SLA_R: 从器件读地址
PAGE_SIZE: EEPROM页大小(单位:字节)
NUM_PAGE: EEPROM总页数
ADDR: 从器件内部读数据起始地址
N: 读数据字节数
DAT: 目标数据起始地址
************************************************************************/
void SEEPROM_read_n_bytes(unsigned char SLA_R,unsigned int PAGE_SIZE,unsigned int NUM_PAGE,
unsigned int ADDR,unsigned int N,unsigned char *DAT)
{
unsigned int PAGE,END_PAGE,NBYTES[2],i;
END_PAGE=(ADDR+N)/PAGE_SIZE;
if(END_PAGE>NUM_PAGE-1)
{
//not enough memory
return;
}
PAGE=ADDR/PAGE_SIZE;
NBYTES[0]=(PAGE+1)*PAGE_SIZE-ADDR;
NBYTES[1]=(ADDR+N)-(END_PAGE*PAGE_SIZE);
if(NBYTES[0])
{
i2c_read_n_bytes(SLA_R,ADDR,NBYTES[0],DAT);
}
if(END_PAGE>PAGE)
{
i=0;
while(END_PAGE>++PAGE)
{
i2c_read_n_bytes(SLA_R,(PAGE*PAGE_SIZE),PAGE_SIZE,(DAT+NBYTES[0]+(i++)*PAGE_SIZE));
}
if(NBYTES[1])
{
i2c_read_n_bytes(SLA_R,(PAGE*PAGE_SIZE),NBYTES[1],(DAT+NBYTES[0]+i*PAGE_SIZE));
}
}
}
//PCF8563时钟停止指令
void PCF8563_stop(void)
{
unsigned char stopcode=0x20;
i2c_write_n_bytes(SLA_W_PCF8563,0,1,&stopcode);
}
//PCF8563时钟启动指令
void PCF8563_start(void)
{
unsigned char startcode=0x00;
i2c_write_n_bytes(SLA_W_PCF8563,0,1,&startcode);
}
/************************************************************************
PCF8563时钟设置
编程:许工 QQ11520389
时间:2010.03.05
参数说明:(BCD码)
yy: 年(0x00到0x99)
mm: 月(0x01到0x12)
dd: 日(0x01到0x31)
hh: 时(0x00到0x23)
mi: 分(0x00到0x59)
ss: 秒(0x00到0x59)
da: 星期(0x01到0x07)
************************************************************************/
void PCF8563_set(unsigned char yy,unsigned char mm,unsigned char dd,
unsigned char da,unsigned char hh,unsigned char mi,unsigned char ss)
{
unsigned char time[7];
time[6]=yy; //年
time[5]=mm;//月
time[4]=da; //星期
time[3]=dd; //日
time[2]=hh;//时
time[1]=mi;//分
time[0]=ss;//秒
PCF8563_stop();
i2c_write_n_bytes(SLA_W_PCF8563,2,7,time);
PCF8563_start();
}
/************************************************************************
PCF8563时钟读取
编程:许工 QQ11520389
时间:2010.03.05
参数说明:(BCD码)
time: 存放读出时间的数组名
time[6]: 年(0x00到0x99)
time[5]: 月(0x01到0x12)
time[3]: 日(0x01到0x31)
time[2]: 时(0x00到0x23)
time[1]: 分(0x00到0x59)
time[0]: 秒(0x00到0x59)
time[4]: 星期(0x01到0x07)
************************************************************************/
void PCF8563_read(unsigned char *time)
{
i2c_read_n_bytes(SLA_R_PCF8563,2,7,time);
//time[6] //年
time[5] &= 0x1F;//月
time[4] &= 0x07;//星期
time[3] &= 0x3F;//日
time[2] &= 0x3F;//时
time[1] &= 0x7F;//分
time[0] &= 0x7F;//秒
}
void main(void)
{
unsigned char dat[132];
unsigned int i;
DDRD|=3;//RED ON
PORTD|=1;
DDRC&=~(BIT(PC4)|BIT(PC5));//Pull up the pin SDA and SCL
PORTC|=BIT(PC4)|BIT(PC5);
TWCR=0;
TWBR=12; //set bit rate
TWSR=0; //set prescale
/*
PCF8563_set(0x10,0x03,0x04,0x04,0x11,0x25,0x45);
delay_ms(1000);
PCF8563_read(dat);
//*/
//*
for(i=0;i<132;i++) dat=i;
for(i=0;i<2;i++)
SEEPROM_write_n_bytes(SLA_W_24C64,PAGE_SIZE_24C64,NUM_PAGE_24C64,i*66+4,66,dat);
//*/
//*
for(i=0;i<132;i++) dat=255;
SEEPROM_read_n_bytes(SLA_R_24C64,PAGE_SIZE_24C64,NUM_PAGE_24C64,4,132,dat);
//*/
EEPROM_WRITE(0, dat);
PORTD&=~1;
PORTD|=2;//GREEN ON
}