电路原理图
EEPROM为ATMEL公司的AT24C01A。单片机为ATMEL公司的AT89C51。
软件说明
C语言为Franklin C V3.2。将源程序另存为testi2c.c,用命令
C51 testi2c.c
L51 TESTI2C.OBJ
OHS51 TESTI2C
编译,连接,得到TESTI2C.HEX文件,即可由编程器读入并进行写片,实验。
3.源程序
#include <reg51.h> #include <intrins.h> #define uchar unsigned char #define uint unsigned int #define AddWr 0xa0 /*器件地址选择及写标志*/ #define AddRd 0xa1 /*器件地址选择及读标志*/ #define Hidden 0x0e /*显示器的消隐码*/ /*有关全局变量*/ sbit Sda= P3^; /*串行数据*/ sbit Scl= P3^; /*串行时钟*/ sbit WP= P3^; /*硬件写保护*/ void mDelay(uchar j) { uint i; ;j--) { ;i<;i--) {;} } } /*发送起始条件*/ void Start(void) /*起始条件*/ { Sda=; Scl=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); Sda=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); } void Stop(void) /*停止条件*/ { Sda=; Scl=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); Sda=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); } void Ack(void) /*应答位*/ { Sda=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); Scl=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); Scl=; } void NoAck(void) /*反向应答位*/ { Sda=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); Scl=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); Scl=; } /*发送数据子程序,Data为要求发送的数据*/ void Send(uchar Data) { uchar BitCounter=; /*位数控制*/ uchar temp; /*中间变量控制*/ do { temp=Data; Scl=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); if((temp&0x80)==0x80)/* 如果最高位是1*/ Sda=; else Sda=; Scl=; temp=Data<<; /*RLC*/ Data=temp; BitCounter--; }while(BitCounter); Scl=; } /*读一个字节的数据,并返回该字节值*/ uchar Read(void) { uchar temp=; uchar temp1=; uchar BitCounter=; Sda=; do{ Scl=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); Scl=; _nop_ (); _nop_ (); _nop_ (); _nop_ (); if(Sda) /*如果Sda=1;*/ temp=temp|0x01; /*temp的最低位置1*/ else temp=temp&0xfe; /*否则temp的最低位清0*/ ) { temp1=temp<<; temp=temp1; } BitCounter--; }while(BitCounter); return(temp); } void WrToROM(uchar Data[],uchar Address,uchar Num) { uchar i; uchar *PData; PData=Data; ;i<Num;i++) { Start(); /*发送启动信号*/ Send(0xa0); /*发送SLA+W*/ Ack(); Send(Address+i); /*发送地址*/ Ack(); Send(*(PData+i)); Ack(); Stop(); mDelay(); } } void RdFromROM(uchar Data[],uchar Address,uchar Num) { uchar i; uchar *PData; PData=Data; ;i<Num;i++) { Start(); Send(0xa0); Ack(); Send(Address+i); Ack(); Start(); Send(0xa1); Ack(); *(PData+i)=Read(); Scl=; NoAck(); Stop(); } } void main() { uchar Number[]={,,,}; WP= ; WrToROM(Number,,); /*将初始化后的数值写入EEPROM*/ mDelay(); Number[]=; Number[]=; Number[]=; Number[]=; /*将数组中的值清掉,以验证读出的数是否正确*/ RdFromROM(Number,,); }
问题:本程序中未采用块读写的方法,显得有点‘笨’,这是由于项目原因,现项目已完成,程序已写好,短时不会修改,也不会花上一定的精力去做,虽然理论上已很成熟,就这样写一下,未必不对,但与我的本栏目要求不符,所以就未做上去,如果以后我做了,将再补上。