串行I2C总线E2PROM AT24CXXX的应用3
接上一篇
unsigned char code BMP1[]={ //字节倒序
//-- 调入一幅图像:E:!Program!BmpSample12864.bmp
//宽度x高度=1264
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xE0,0xF0,0xFC,0xFE,0xFE,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0x9F,0xCF,0xDF,0x9F,
0x9E,0x3E,0xFF,0xFE,0xFE,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFA,0xFC,0xF8,0xE0,0xC0,0x80,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xC0,0xF0,0xF8,0xFC,0xFE,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xEF,
0xCF,0xDF,0x9F,0x0F,0x1F,0x7F,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFE,0xFC,0xF0,0xC0,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xC0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x10,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFD,0xFB,0xFF,
0xFF,0xFF,0xFF,0xFE,0xF8,0xFE,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xBF,0x3F,
0x37,0x37,0x37,0x27,0x63,0x43,0x03,0x03,
0x03,0x03,0x03,0x07,0x67,0x27,0x0F,0x0F,
0x1F,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x80,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x10,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x7F,0x7F,
0x7F,0x7F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
0x3F,0x3F,0x3F,0x3F,0x3F,0x7F,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x7F,0x3F,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x80,0xE0,0xFC,0xFE,0xFE,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xDF,0x0F,0x07,0x07,0x03,
0x03,0x03,0x03,0x02,0xC0,0xAC,0xBF,0xA0,
0x80,0x00,0x00,0x00,0x02,0x02,0x06,0x06,
0x04,0x00,0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,0xF0,0xE0,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x03,0x07,0x0F,0x1F,0x3F,0x3F,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xBF,0x3F,0x3F,0x3D,
0x7D,0xF8,0xF0,0xF0,0xC0,0x00,0x00,0x00,
0x08,0x8C,0xFC,0xFE,0xEE,0xE6,0xC2,0xC0,
0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
0x1F,0x1F,0x87,0x0D,0x7D,0x70,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xC0,
0xF0,0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,0xE0,0x00,
0x00,0x00,0x02,0xE7,0xE7,0xE7,0xE7,0xC3,
0xC3,0xC1,0x82,0x87,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xE3,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFC,0xF8,0xE0,0xC0,0x80,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,
0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xDF,0x1F,0x1F,0x1F,0x1B,0xF9,
0xF9,0xFF,0xFF,0xFF,0xFF,0x80,0x00,0x00,
0x00,0x01,0x01,0x03,0x03,0x83,0x83,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x01,0x03,0x00,0x00,0x00,0x00,
0xF8,0xFC,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFE,0xFC,0xF8,0xFE,0x8F,0x8F,0x0E,0x06,
0x0E,0x0C,0x0C,0x00,0x01,0x00,0x00,0x80,
0xC0,0xF0,0xFC,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0xFC,
0xF8,0xF0,0xF0,0xE0,0x00,0x00,0x00,0x00,
0x00,0x03,0x07,0x0F,0x1F,0x1F,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFE,0xFC,0xFC,0xFE,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xDF,0xCF,0xDE,
0xD4,0xC2,0x82,0x80,0x80,0x83,0xC7,0xC7,
0x0F,0x04,0x00,0x00,0x00,0x00,0x00,0x00,
0xC0,0xF4,0xFC,0xFC,0xFC,0xFC,0xF8,0xF8,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0x7F,0x3F,0x1F,0x1F,0xDF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3F,0x1E,
0x1E,0x0E,0x0C,0x04,0x02,0x06,0x1F,0xFF,
0xFF,0xCF,0x0F,0x0F,0x0F,0x1F,0x3F,0x7F,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x7F,0x1F,0x1F,0x03,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0xC1,0xE7,
0xEF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFB,0xFB,
0xF3,0xF9,0x71,0x31,0x00,0x00,0x00,0x01,
0x00,0x00,0x00,0x00,0x00,0x80,0xE0,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x03,0x07,0x0F,0x1F,0x1F,0x3F,0x3F,0x1F,
0x1F,0x1F,0x0F,0x4F,0x67,0x27,0x33,0x31,
0x38,0x38,0x78,0x7C,0x7E,0x7F,0x7F,0x7F,
0x7F,0x7F,0x7F,0x7F,0x3F,0x3F,0x7F,0x7F,
0x7F,0x7F,0x7D,0x79,0x79,0x70,0x70,0x70,
0x70,0x70,0x70,0x78,0x78,0x3C,0x5E,0x6F,
0x3F,0x77,0x0F,0x0C,0x7C,0x78,0x78,0x40,
0x00,0x01,0x01,0x03,0x07,0x0F,0x1F,0x1F,
0x1F,0x1F,0x1F,0x1F,0x0F,0x07,0x03,0x00,
0x00,0x00,0x00,0x40,0x60,0x70,0x70,0x78,
0x78,0x7C,0x7E,0x7F,0x7F,0x7F,0x7F,0x7F,
0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,
0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7C,
0x7C,0x7C,0x78,0x78,0x70,0x58,0x00,0x00,
0x40,0x70,0x78,0x7C,0x7F,0x7F,0x7F,0x7F,
0x7F,0x7F,0x07,0x07,0x0F,0x1F,0x3F,0x7F
};
uchar code ASC_5x7[]={
0x00, 0x00, 0x00, 0x00, 0x00, //
0x00, 0x00, 0x4F, 0x00, 0x00, //
0x00, 0x07, 0x00, 0x07, 0x00, //
0x14, 0x7F, 0x14, 0x7F, 0x14, //
0x24, 0x2A, 0x7F, 0x2A, 0x12, //
0x23, 0x13, 0x08, 0x64, 0x62, //
0x36, 0x49, 0x55, 0x22, 0x50, //
0x00, 0x05, 0x03, 0x00, 0x00, //
0x00, 0x1C, 0x22, 0x41, 0x00, //
0x00, 0x41, 0x22, 0x1C, 0x00, //
0x14, 0x08, 0x3E, 0x08, 0x14, //
0x08, 0x08, 0x3E, 0x08, 0x08, //
0x00, 0x50, 0x30, 0x00, 0x00, //
0x08, 0x08, 0x08, 0x08, 0x00, //
0x00, 0x60, 0x60, 0x00, 0x00, //
0x20, 0x10, 0x08, 0x04, 0x02, //
0x3E, 0x51, 0x49, 0x45, 0x3E, //
0x00, 0x42, 0x7F, 0x40, 0x00, //
0x42, 0x61, 0x51, 0x49, 0x46, //
0x21, 0x41, 0x45, 0x4B, 0x31, //
0x18, 0x14, 0x12, 0x7F, 0x10, //
0x27, 0x45, 0x45, 0x45, 0x39, //
0x3C, 0x4A, 0x49, 0x49, 0x30, //
0x01, 0x01, 0x79, 0x05, 0x03, //
0x36, 0x49, 0x49, 0x49, 0x36, //
0x06, 0x49, 0x49, 0x29, 0x1E, //
0x00, 0x36, 0x36, 0x00, 0x00, //
0x00, 0x56, 0x36, 0x00, 0x00, //
0x08, 0x14, 0x22, 0x41, 0x00, //
0x14, 0x14, 0x14, 0x14, 0x14, //
0x00, 0x41, 0x22, 0x14, 0x08, //
0x02, 0x01, 0x51, 0x09, 0x06, //
0x32, 0x49, 0x79, 0x41, 0x3E, //
0x7E, 0x11, 0x11, 0x11, 0x7E, //
0x41, 0x7F, 0x49, 0x49, 0x36, //
0x3E, 0x41, 0x41, 0x41, 0x22, //
0x41, 0x7F, 0x41, 0x41, 0x3E, //
0x7F, 0x49, 0x49, 0x49, 0x49, //
0x7F, 0x09, 0x09, 0x09, 0x01, //
0x3E, 0x41, 0x41, 0x49, 0x7A, //
0x7F, 0x08, 0x08, 0x08, 0x7F, //
0x00, 0x41, 0x7F, 0x41, 0x00, //
0x20, 0x40, 0x41, 0x3F, 0x01, //
0x7F, 0x08, 0x14, 0x22, 0x41, //
0x7F, 0x40, 0x40, 0x40, 0x40, //
0x7F, 0x02, 0x0C, 0x02, 0x7F, //
0x7F, 0x06, 0x08, 0x30, 0x7F, //
0x3E, 0x41, 0x41, 0x41, 0x3E, //
0x7F, 0x09, 0x09, 0x09, 0x06, //
0x3E, 0x41, 0x51, 0x21, 0x5E, //
0x7F, 0x09, 0x19, 0x29, 0x46, //
0x26, 0x49, 0x49, 0x49, 0x32, //
0x01, 0x01, 0x7F, 0x01, 0x01, //
0x3F, 0x40, 0x40, 0x40, 0x3F, //
0x1F, 0x20, 0x40, 0x20, 0x1F, //
0x7F, 0x20, 0x18, 0x20, 0x7F, //
0x63, 0x14, 0x08, 0x14, 0x63, //
0x07, 0x08, 0x70, 0x08, 0x07, //
0x61, 0x51, 0x49, 0x45, 0x43, //
0x00, 0x7F, 0x41, 0x41, 0x00, //
0x02, 0x04, 0x08, 0x10, 0x20, //
0x00, 0x41, 0x41, 0x7F, 0x00, //
0x04, 0x02, 0x01, 0x02, 0x04, //
0x40, 0x40, 0x00, 0x40, 0x40, //
0x01, 0x02, 0x04, 0x00, 0x00, //
0x20, 0x54, 0x54, 0x54, 0x78, //
0x7F, 0x48, 0x44, 0x44, 0x38, //
0x38, 0x44, 0x44, 0x44, 0x28, //
0x38, 0x44, 0x44, 0x48, 0x7F, //
0x38, 0x54, 0x54, 0x54, 0x18, //
0x00, 0x08, 0x7E, 0x09, 0x02, //
0x0C, 0x52, 0x52, 0x4C, 0x3E, //
0x7F, 0x08, 0x04, 0x04, 0x78, //
0x00, 0x44, 0x7D, 0x40, 0x00, //
0x20, 0x40, 0x44, 0x3D, 0x00, //
0x00, 0x7F, 0x10, 0x28, 0x44, //
0x00, 0x41, 0x7F, 0x40, 0x00, //
0x7C, 0x04, 0x78, 0x04, 0x78, //
0x7C, 0x08, 0x04, 0x04, 0x78, //
0x38, 0x44, 0x44, 0x44, 0x38, //
0x7E, 0x0C, 0x12, 0x12, 0x0C, //
0x0C, 0x12, 0x12, 0x0C, 0x7E, //
0x7C, 0x08, 0x04, 0x04, 0x08, //
0x58, 0x54, 0x54, 0x54, 0x64, //
0x04, 0x3F, 0x44, 0x40, 0x20, //
0x3C, 0x40, 0x40, 0x3C, 0x40, //
0x1C, 0x20, 0x40, 0x20, 0x1C, //
0x3C, 0x40, 0x30, 0x40, 0x3C, //
0x44, 0x28, 0x10, 0x28, 0x44, //
0x1C, 0xA0, 0xA0, 0x90, 0x7C, //
0x44, 0x64, 0x54, 0x4C, 0x44, //
0x00, 0x08, 0x36, 0x41, 0x00, //
0x00, 0x00, 0x77, 0x00, 0x00, //
0x00, 0x41, 0x36, 0x08, 0x00, //
0x02, 0x01, 0x02, 0x04, 0x02, //
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, //
};
unsigned char code HZK_12[]={ //字节颠倒
//-- 文字: 鹰 --*
//- 宋体11; 此字体下对应的点阵为:宽x高=11x
0x42,0x00,0x22,0x00,0x12,0x00,0xFA,0x07,0x4E,0x01,0x4B,0x01,0x4A,0x01,0x4A,0x05,
0xFA,0x07,0x02,0x00,0x02,0x00,0x00,0x00,/*"有",{0}*/
0x42,0x04,0xAE,0x04,0x93,0x04,0x9A,0x02,0xA6,0x01,0xC0,0x00,0xA6,0x04,0x9A,0x04,
0x8A,0x04,0x96,0x03,0x20,0x00,0x00,0x00,/*"努",{1}*/
0x00,0x04,0x08,0x04,0x08,0x02,0x08,0x01,0xC8,0x00,0x3F,0x00,0x08,0x04,0x08,0x04,
0x08,0x04,0xFC,0x03,0x08,0x00,0x00,0x00,/*"力",{2}*/
0x02,0x02,0xFA,0x01,0x4B,0x04,0xCA,0x07,0x7A,0x01,0x02,0x04,0x08,0x03,0xFF,0x00,
0xC8,0x07,0x0E,0x04,0x08,0x07,0x00,0x00,/*"就",{3}*/
0x42,0x00,0x22,0x00,0x12,0x00,0xFA,0x07,0x4E,0x01,0x4B,0x01,0x4A,0x01,0x4A,0x05,
0xFA,0x07,0x02,0x00,0x02,0x00,0x00,0x00,/*"有",{4}*/
0x00,0x04,0xFC,0x03,0x24,0x01,0x24,0x02,0xE4,0x01,0x04,0x04,0x7F,0x02,0x84,0x01,
0x45,0x02,0x36,0x04,0x04,0x07,0x00,0x00,/*"成",{5}*/
0x02,0x01,0x02,0x01,0xFE,0x00,0x82,0x04,0x82,0x04,0x08,0x02,0x88,0x01,0x7F,0x04,
0x08,0x04,0x08,0x04,0xF8,0x03,0x00,0x00,/*"功",{6}*/
0x00,0x00,0x1C,0x00,0x7E,0x03,0x7E,0x03,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00/*"!",{7}*/
};
上面代码的各个函数部分我就不说了,只说说AT24C16的调试,也就是主函数部分:
void Main( void )
{
uchar x,i;
uchar *ascii; //先定义一个字符型指针变量
uchar abcd[]="iic test"; //定义一个字符数组内容为“iic test”
LcmInit();
LcmClear();
ascii=abcd; //将字符数组的首地址交给指针变量
write_nbyte(0,0,ascii,8); //向AT24C16写进以ascii为首地址的八个字节数据。
//read_nbyte(0,0,ascii,8); //读AT24C16语句补注释掉了
while(1)
{
LcmClear();
LcmPutBMP(BMP1);
Delay(3000);
LcmClear();
//LcmReverseBMP();
Delay(1000);
//LcmClear();
/*
x=0;
for(i=0;i<8;i++)
{
LcmPutHZ_12(x,i*7,i);
x=x+16;
}
*/
LcmPutstr( 3,40,ascii ); //向LCD12864显示所定义的字符数组(这时还不是从AT2416内读取的)
LcmPutstr( 5,40,"AT24C16!" );
Delay(5000);
}
}
对代码进行编译成HEX文件写入S51后运行:
好!数据已写入AT24C16内,下面修改程序,看看读取出的内容是否正确。
void Main( void )
{
uchar x,i;
uchar *ascii;
uchar abcd[9]; //定义一个字符数组,内容为空
LcmInit();
LcmClear();
ascii=abcd; //将字符数组的首地址交给指针变量
//write_nbyte(0,0,ascii,8); //写AT24C16语句被注释掉
read_nbyte(0,0,ascii,8); //从AT24C16读取8个字节的数据存入以ascii为首地址的abcd变量内
while(1)
{
LcmClear();
LcmPutBMP(BMP1);
Delay(3000);
LcmClear();
//LcmReverseBMP();
Delay(1000);
//LcmClear();
/*
x=0;
for(i=0;i<8;i++)
{
LcmPutHZ_12(x,i*7,i);
x=x+16;
}
*/
LcmPutstr( 3,40,ascii ); //显示从AT24C16内读取的内容
LcmPutstr( 5,40,"AT24C16!" );
Delay(5000);
}
}
重新编译后写入S51芯片运行:
第一幅:
第二幅:
OK,成功!这次"iic test"这行字符是从AT24C16内读取的。你可以试着拔掉那两根SDA,SCL的数据线,再按下复位键重新运行,你会发现那行“iic test”没有显示了。说明没有读取到数据。再装上数据线,重按复位键运行,又正常了。后面就可以将存储在S51代码段的字模,图形数据等,都写到AT24C16里了。
在网上找到一个写的不错的读写AT24CXXX的通用程序函数,也很好用,程序见下面:
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define ERRORCOUNT 10
sbit SDA=P1^6;
sbit SCL=P1^7;
enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256};
enum eepromtype mType;
bit RW24XX(unsigned char *DataBuff,unsigned char ByteQuantity,unsigned int Address,
unsigned char ControlByte,enum eepromtype mType);
//DataBuff为读写数据输入/输出缓冲区的首址
//ByteQuantity 为要读写数据的字节数量
//Address 为EEPROM的片内地址
//ControlByte 为EEPROM的控制字节,具体形式为(1)(0)(1)(0)(A2)(A1)(A0)(R/W),其中R/W=1,
//表示读操作,R/W=0为写操作,A2,A1,A0为EEPROM的页选或片选地址;
//EepromType为枚举变量,需为M2401至M24256中的一种,分别对应24C01至24C256;
//函数返回值为一个位变量,若返回1表示此次操作失效,0表示操作成功;
//ERRORCOUNT为允许最大次数,若出现ERRORCOUNT次操作失效后,则函数中止操作,并返回1
//SDA和SCL由用户自定义,这里暂定义为P0^0和P0^1;
//其余的用户不用管,只要把只子程序放在你的程序中并调用它就可以了;
/***********************************************************************************/
bit RW24XX(unsigned char *DataBuff,unsigned char ByteQuantity,unsigned int Address,
unsigned char ControlByte,enum eepromtype mType)
{
void Delay1(uchar DelayCount);
void IICStart(void);
void IICStop(void);
bit IICRecAck(void);
void IICNoAck(void);
void IICAck(void);
unsigned char IICReceiveByte(void);
void IICSendByte(unsigned char sendbyte);
unsigned char data j,i=ERRORCOUNT;
bit errorflag=1;
while(i--)
{
IICStart();
IICSendByte(ControlByte&0xfe);
if(IICRecAck())
continue;
if(mType>M2416)
{
IICSendByte((unsigned char)(Address>>8));
if(IICRecAck())
continue;
}
IICSendByte((unsigned char)Address);
if(IICRecAck())
continue;
if(!(ControlByte&0x01))
{
j=ByteQuantity;
errorflag=0; //********clr errorflag
while(j--)
{
IICSendByte(*DataBuff++);
if(!IICRecAck())
continue;
errorflag=1;
break;
}
if(errorflag==1)
continue;
break;
}
else
{
IICStart();
IICSendByte(ControlByte);
if(IICRecAck())
continue;
while(--ByteQuantity)
{
*DataBuff++=IICReceiveByte();
IICAck();
}
*DataBuff=IICReceiveByte(); //read last byte data
IICNoAck();
errorflag=0;
break;
}
}
IICStop();
if(!(ControlByte&0x01))
{
Delay1(255);
Delay1(255);
Delay1(255);
Delay1(255);
}
return(errorflag);
}
/*****************以下是对IIC总线的操作子程序***/
/*****************启动总线**********************/
void IICStart(void)
{
SCL=0; //
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
SDA=1; //
}
/*****************停止IIC总线****************/
void IICStop(void)
{
SCL=0;
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
SCL=0;
}
/**************检查应答位*******************/
bit IICRecAck(void)
{
SCL=0;
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
CY=SDA; //因为返回值总是放在CY中的
SCL=0;
return(CY);
}
/***************对IIC总线产生应答*******************/
void IICACK(void)
{
SDA=0;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
SDA=1;
}
/*****************不对IIC总线产生应答***************/
void IICNoAck(void)
{
SDA=1;
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
/*******************向IIC总线写数据*********************/
void IICSendByte(unsigned char sendbyte)
{
unsigned char data j=8;
for(;j>0;j--)
{
SCL=0;
sendbyte<<=1; //无论C51怎样实现这个操作,始终会使CY=sendbyte^7;
SDA=CY;
SCL=1;
}
SCL=0;
}
/**********************从IIC总线上读数据子程序**********/
unsigned char IICReceiveByte(void)
{
register receivebyte,i=8;
SCL=0;
while(i--)
{
SCL=1;
receivebyte=(receivebyte<<1)|SDA;
SCL=0;
}
return(receivebyte);
}
/***************一个简单延时程序************************/
void Delay1(uchar DelayCount)
{
while(--DelayCount);
}
但实际使用中发现它有个严重的错误。就是没有考虑到不同的I2C器件在写页操作时,是有一页数据限制的,AT24C01是8个字节,AT24C02-16是16个字节,AT24C33-64是32个字节。AT24C128-256是64个字节。AT24C512是128个字节。AT24C1024是256个字节。
这是器件说明书上的资料,我手上只有AT24C02、AT24C16和AT24C256,实际使用了一下,AT24C02的页限制是8个字节。另两个是和说明书上一致的。当我写的数据量超出页限制时,地址指针就会回到起始点覆盖原来的数据。例如我以页方式写10个字节的数据到AT24C02时。前8个字节的数据正常写入,第9、第10个数据就回头覆盖掉了第一、第二个数据。
你如果把265个字节的数据往AT24C02进行写页操作,它也不报错,就一个劲地反复覆盖你8个字节的空间,再比如你往AT24C256里输入一个字节的地址,或往AT24C02里输入两个字节的地址,它也不报错,就这么胡乱地把地址当数据或把数据当成地址往里一阵乱写。当你读取数据时才发现里面混乱不堪。这使得上面那个读写AT24CXXX器件的程序怎么运行都不会出错。我觉得这是AT24CXX器件设计上比较弱智的地方。
所以上面的程序得修改。
未完待续。。。