EEPROM 读写驱动 (AT24C256 , C8051F020)
MCU是 8051F020 ,,,,, EEPROM 是AT24C256
当初设计板子没注意, 结果SDA用的P45 ,SCL用的P46 。 因为P4口不能按位寻址,所以SDA和SCL都是用直接操作,很麻烦。
比如SDA = 1 就要写成P4 = P4 | 0x20 了。 所以把同学用的程序(AT89C52上调试通过的程序,用P3口调试的,比如P3 = P3 | 0x20 )改写了下,但是再自己的MCU上就是读取不成功。郁闷了2天了 ,说请高手看下,希望能有意见。谢谢!
/////////////////////////////////////
// Generated Initialization File //
/////////////////////////////////////
#include "C8051F020.h"
#include "INTRINS.H"
// Peripheral specific initialization functions,
// Called from the Init_Device() function
void Reset_Sources_Init()
{
WDTCN = 0xDE;
WDTCN = 0xAD;
}
void Oscillator_Init()
{
int i = 0;
OSCXCN = 0x67;
for (i = 0; i < 3000; i++); // Wait 1ms for initialization
while ((OSCXCN & 0x80) == 0);
OSCICN = 0x08;
}
// Initialization function for device,
// Call Init_Device() from your main program
void Init_Device(void)
{
Reset_Sources_Init();
Oscillator_Init();
}
//////////////////////////////以上部分是MCU的初始化,晶振的设置,关看门狗。
#include "INTRINS.H"
#define unchar unsigned char
#define unint unsigned int
#define uchar unsigned char
#define uint unsigned int
#define unlong unsigned long
data bank0=0x00 , addr=0x00 ;
uchar FromIIC = 0 , FromIIC2 ;
uchar pp ;
bit ISDA , ISCL ;
//*************** 端口分配 SDA=>P45 ; SCL=>P46 ; WP=>P47*************************/
/********************************************************************************
ISDA = 1 <===> P4 = P4 | 0x20 ; ISDA = 0 <===> P4 = P4 & 0xDF ;
ISCL = 1 <===> P4 = P4 | 0x40 ; ISCL = 0 <===> P4 = P4 & 0xBF ;
*******************************************************************************/
/*****************************延时程序****************************************/
void delay_ms (uint ms)
{
uint i,j;
for(i=0;i<ms;i++)
for(j=0;j<1000;j++)
;
}
//-----------EEPROM读写模块开始-----------------------------------------------
//=============================================
//Wait for some time to get proper I2C timing //EEPROM 开始
void I2cWait (void)
{
_nop_();
_nop_();
}
/*=============================================
I2c start condition
SDA high->low while SCL=high
=============================================*/
void I2cStart(void)
{
P4 = P4 | 0x20 ; //ISDA = 1;
P4 = P4 | 0x40 ; //ISCL = 1;
I2cWait();
P4 = P4 & 0xDF ; //ISDA = 0;
I2cWait();
P4 = P4 & 0xBF ; //ISCL = 0;
}
/*=============================================
I2c stop condition
SDA low->high while SCL=high
=============================================*/
void I2cStop(void)
{
P4 = P4 & 0xDF ; //ISDA = 0;
I2cWait();
P4 = P4 | 0x40 ; //ISCL = 1;
I2cWait();
P4 = P4 | 0x20 ; //ISDA = 1;
}
//master transfer data to slave and return acknowledge bit
bit I2cSentByte(uchar bytedata)
{
uchar i;
bit ack;
P4 = P4 | 0x20 ; //ISDA = 1;
for(i=0; i<8; i++)
{
bytedata = _crol_(bytedata, 1);
if(bytedata & 0x01)
P4 = P4 | 0x20 ; //ISDA = 1;
else
P4 = P4 & 0xDF ; //ISDA = 0;
P4 = P4 | 0x40 ; //ISCL = 1;
I2cWait();
P4 = P4 & 0xBF ; //ISCL = 0;
I2cWait();
}
P4 = P4 | 0x20 ; //ISDA = 1;
I2cWait();
P4 = P4 | 0x40 ; //ISCL = 1;
I2cWait();
ack = P4 & 0x20 ; //ack = ISDA;
P4 = P4 & 0xBF ; //ISCL = 0;
I2cWait();
return ack;
}
//slave transfer data to master
uchar I2cReceiveByte(void)
{
uchar i, bytedata = 0;
//Receive byte (MSB first)
for(i=0; i<8; i++)
{
P4 = P4 | 0x40 ; //ISCL = 1;
I2cWait();
bytedata <<= 1;
ISDA = P4 & 0x20 ;
if ( ISDA ) bytedata |= 0x01; ///////////
P4 = P4 & 0xBF ; //ISCL = 0;
I2cWait();
}
return bytedata;
}
//Master send acknowledge bit to slave
//acknowledge="0",non-acknowledge="1"
void SendAcknowledge (bit ack)
{
//ISDA = ack
if ( ack )
P4 = P4 | 0x20 ; //ISDA = 1 ;
else
P4 = P4 & 0xDF ; //ISDA = 0 ;
P4 = P4 | 0x40 ; //ISCL = 1;
I2cWait();
P4 = P4 & 0xBF ; //ISCL = 0;
}
//do 1 times, and un-check acknowledge
void I2cByteWrite(uchar device, uchar address, uchar bytedata)
{
I2cStart();
I2cSentByte (device);
I2cSentByte (address);
I2cSentByte (bytedata);
I2cStop();
delay_ms(10);
}
uchar I2cByteRead(uchar device, uchar address)
{
uchar bytedata;
I2cStart();
I2cSentByte(device);
I2cSentByte(address);
I2cStart();
// I2cSentByte (device|0x01);
I2cSentByte(device+0x01);
bytedata = I2cReceiveByte();
SendAcknowledge(1);
I2cStop();
return bytedata;
}
//Write byte data into EEPROM
void EEPROMByteWrite0(uchar bank, uchar addr, uchar value) //bank,addr->地址,value->所写值
{
I2cByteWrite((0xA0|bank), addr, value);
}
void EEPROMDataWrite(uchar bank, uchar addr, uchar *dat, uchar n) //写数组
{
uchar i;
for(i=0x00;i<n;i++)
EEPROMByteWrite0( bank, addr+i,*(dat+i));
}
//Read byte data from EEPROM
uchar EEPROMByteRead0(uchar bank, uchar addr) //bank,addr->地址
{
return(I2cByteRead((0xA0|bank), addr));
}
void EEPROMDataRead(uchar bank, uchar addr, uchar *dat, uchar n) //读数组
{
uchar i;
for(i=0x00;i<n;i++)
*(dat+i)=EEPROMByteRead0(bank,addr+i);
}
//-----------EEPROM读写模块结束-----------------------------------------------
void main ()
{
Init_Device();
pp = 2 ;
P4 = 0x00 ;
while ( 1 )
{
delay_ms ( 1000 ) ; //调试用的看P4口是不是通的
P4 = P4 | 0x01 ; //调试用的看P4口是不是通的
delay_ms ( 1000 ) ;
P4 = P4 & 0xFE ;
delay_ms ( 1000 ) ;
EEPROMByteWrite0 ( bank0 , 0x00 + addr , pp ) ; //写
FromIIC = EEPROMByteRead0( bank0 , addr) ; //总是读出来的255 ,而不是2
}
}