|
楼主 |
发表于 2015-1-6 13:32:16
|
显示全部楼层
再发一次源码
- //ICC-AVR application builder : 2010-2-22 13:51:50
- // Target : M88
- // Crystal: 8.0000Mhz
- #include <iom88v.h>
- #include <macros.h>
- #include <eeprom.h>
- //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<x;j++)
- for(i=0;i<1141;i++);
- }
- /************************************************************************
- I2C主机写N字节数据到从器件
- 编程:许工 QQ11520389
- 时间:2010.03.05
- 参数说明:
- SLA_W: 从器件写地址
- ADDR: 从器件内部写数据起始地址
- N: 写数据字节数
- DAT: 源数据起始地址
- ************************************************************************/
- unsigned char i2c_write_n_bytes(unsigned char SLA_W, unsigned int ADDR,
- unsigned int N, unsigned char *DAT)
- {
- unsigned int i;
- I2C_START();
- I2C_CHECK_STATUS(START);
-
- I2C_WRITE(SLA_W);
- I2C_NAK();
- I2C_CHECK_STATUS(MT_SLA_ACK);
-
- if(SLA_W!=SLA_W_PCF8563)
- {
- I2C_WRITE((unsigned char)(ADDR>>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<N;i++)
- {
- I2C_WRITE(DAT[i]);
- I2C_NAK();
- I2C_CHECK_STATUS(MT_DATA_ACK);
- }
-
- I2C_STOP();
- return 1;
- }
- /************************************************************************
- I2C主机从从器件读N字节数据
- 编程:许工 QQ11520389
- 时间:2010.03.05
- 参数说明:
- SLA_R: 从器件读地址
- ADDR: 从器件内部读数据起始地址
- N: 读数据字节数
- DAT: 目标数据起始地址
- ************************************************************************/
- unsigned char i2c_read_n_bytes(unsigned char SLA_R, unsigned int ADDR,
- unsigned int N, unsigned char *DAT)
- {
- unsigned int i;
-
- I2C_START();
- I2C_CHECK_STATUS(START);
-
- I2C_WRITE((SLA_R)-1);
- I2C_NAK();
- I2C_CHECK_STATUS(MT_SLA_ACK);
-
- if(SLA_R!=SLA_R_PCF8563)
- {
- I2C_WRITE((unsigned char)(ADDR>>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;i<N-1;i++)
- {
- I2C_ACK();
- I2C_CHECK_STATUS(MR_DATA_ACK);
- I2C_READ(DAT[i]);
- }
- }
- I2C_NAK();
- I2C_CHECK_STATUS(MR_DATA_NAK);
- DAT[N-1]=TWDR;
-
- I2C_STOP();
- return 1;
- }
- /************************************************************************
- I2C主机检测从器件忙
- 编程:许工 QQ11520389
- 时间:2010.03.05
- 参数说明:
- SLA_W: 从器件写地址
- 器件忙返回 1,否则返回 0,用于判断EEPROM是否编程完成
- ************************************************************************/
- unsigned char i2c_check_busy(unsigned char SLA_W)
- {
- unsigned char retv=0;
- I2C_START();
- I2C_CHECK_STATUS(START);
- I2C_WRITE(SLA_W);
- I2C_NAK();
- while(!(TWCR&BIT(TWINT)));
- if((TWSR&0xF8)!=MT_SLA_ACK) retv=1;
- I2C_STOP();
- return retv;
- }
- /************************************************************************
- I2C主机写N字节数据到从器件(EEPROM)
- 编程:许工 QQ11520389
- 时间:2010.03.05
- 参数说明:
- SLA_W: 从器件写地址
- PAGE_SIZE: EEPROM页大小(单位:字节)
- NUM_PAGE: EEPROM总页数
- ADDR: 从器件内部写数据起始地址
- N: 写数据字节数
- DAT: 源数据起始地址
- ************************************************************************/
- void SEEPROM_write_n_bytes(unsigned char SLA_W,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_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]=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[i]=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
- }
复制代码 |
|