c51单片机嵌入式开发总结2
自己学习记录用,有些乱,
1、IIC,eeprom24c02驱动配置
本实验是基于EEPROM的24C02驱动配置的编程,主要记录一些编程的重点节点的理解:
1、IIC驱动配置:精准的时钟配置,计算每一步所需要的指令周期,相加是10us。
2、IIC的起始信号配置,根据IIC的时序特性配置。
3、IIC终止信号配置,根据IIC的时序特性配置。
4、I2cSendByte(unsignedchardat):通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定。
5、I2cReadByte(),函数功能:使用I2c读取一个字节
6、voidAt24c02Write(unsignedcharaddr,unsignedchardat)函数功能:向24c02的一个地址写入一个数据。
发送写器件地址是根据24C02的电路特性和地址特性获得。24C02是有E0,E1,E2寻址,根据下面两图片可知是8位寻址,因E0、E1、E2引脚接地,而是写所以,RW位为零。,即发送器件地址位0xa0,同理接收时,接收器件地址为0xa1。
7、unsignedcharAt24c02Read(unsignedcharaddr)函数功能:读取24c02的一个地址的一个数据
2、24C02或者24C16进行字节、页读取、页存取voidi2cStart(void)开始时序{SDA1;SCL1;delay(2);延时2sSDA0;delay(2);SCL0;}
voidi2cStop(void)结束时序{SDA0;delay(2);SCL1;delay(2);SDA1;}
voidi2cAckMCU(void)应答时序{SDA0;delay(2);SCL1;delay(2);SCL0;delay(2);SDA1;delay(4);}
voidi2cNoAckMCU(void)非应答时序{SDA1;delay(2);SCL1;delay(2);SCL0;delay(2);}
24C0216存储空间大小
24C02就是有2Kbit20008250个字节,24C16就是有16kbit2000个字节,24C02一页最多可以写入8个字节,因此可以分成32页,24C16一页最多可以写入16个字节,因此可以分成128页。
1、字节写操作
voidWriteByte24LC16B(unsignedcharinput)
{
unsignedcharbitcount;
for(bitcount8;bitcount!0;bitcount)
{
delay(2);
SDA(Bool)(input0x80);
delay(2);
SCL1;
delay(2);
SCL0;
inputinput1;
delay(2);
}
SDA1;
SDACTRL1;这里需要看自己使用的芯片设置SDA的IO口为输入状态,我用的是HT45F67芯片,SDA端口设置为输入状态,用于判断SDA是否接到主机的应答信号
delay(2);
SCL1;
delay(2);
if(SDA1)
ack0;
else
ack1;
SCL0;
SDACTRL0;此处根据自己所使用的芯片将SDA所在的Io口设置为输出状态
}
voidWrite24LC16B(unsignedcharWdata,unsignedintRomAddress)
{
unsignedcharblock;
WriteDeviceAddress0B10100000;
blockRomAddress256;
RomAddressRomAddress256;
WriteDeviceAddressWriteDeviceAddress(block1);
i2cStart();
WriteByte24LC16B(WriteDeviceAddress);
WriteByte24LC16B((unsignedchar)RomAddress);
WriteByte24LC16B(Wdata);
i2cStop();
delay(5500);
}
2、字节读操作
unsignedcharReadByte24LC16B()
{
unsignedcharbitcount,rbyte0;
SDA1;
SDACTRL1;
delay(10);
for(bitcount8;bitcount!0;bitcount)
{
rbyterbyte1;
delay(2);
SCL1;
rbyterbyte((unsignedchar)(SDA));
delay(2);
SCL0;
delay(2);
}
SDACTRL0;
return(rbyte);
}
unsignedcharRead24LC16B(unsignedintRomAddress)
{
unsignedcharoutput,block;
ReadDeviceAddress0B10100001;
WriteDeviceAddress0B10100000;
blockRomAddress256;
RomAddressRomAddress256;
WriteDeviceAddressWriteDeviceAddress(block1);
ReadDeviceAddressReadDeviceAddress(block1);
i2cStart();
WriteByte24LC16B(WriteDeviceAddress);
WriteByte24LC16B((unsignedchar)RomAddress);
i2cStart();
WriteByte24LC16B(ReadDeviceAddress);
outputReadByte24LC16B();
i2cNoAckMCU();
i2cStop();
delay(2000);
return(output);
}
3、页写操作
Wdata为输入数组的首地址,RomAddress为需要进行存储的地址,范围在02047之间,cnt为一次需要写入的字节个数,建议采用8的倍数的cnt,因为本函数不采用自动分页,不是8的倍数会在超出页写入最多的字节数之后覆盖掉原来的数。
voidWritePage24LC16B(unsignedcharWdata,unsignedintRomAddress,unsignedcharcnt)
{
unsignedcharblock;
WriteDeviceAddress0B10100000;
blockRomAddress256;
RomAddressRomAddress256;
WriteDeviceAddressWriteDeviceAddress(block1);
i2cStart();
WriteByte24LC16B(WriteDeviceAddress);
WriteByte24LC16B((unsignedchar)RomAddress);
while(cnt)
{
WriteByte24LC16B(Wdata);
}
i2cStop();
}
注意:连续进行多页写操作,需要在WritePage24LC16B函数后添加150s以上的延迟,这段时间,24C02内部需要将数据存储到芯片内部。
例子:
Dbuffer〔8〕{1,2,3,4,5,6,7,8};
WritePage24LC16B(Dbuffer,0,8);
delay(150);延迟150s以及以上
WritePage24LC16B(Dbuffer,8,8);
4、页读操作
voidReadPage24LC16B(unsignedcharRdata,unsignedintRomAddress,unsignedcharcnt)
{
unsignedcharblock;
ReadDeviceAddress0B10100001;
WriteDeviceAddress0B10100000;
blockRomAddress256;
RomAddressRomAddress256;
WriteDeviceAddressWriteDeviceAddress(block1);
ReadDeviceAddressReadDeviceAddress(block1);
i2cStart();
WriteByte24LC16B(WriteDeviceAddress);
WriteByte24LC16B((unsignedchar)RomAddress);
i2cStart();
WriteByte24LC16B(ReadDeviceAddress);
while(cnt1)
{
RdataReadByte24LC16B();
cnt;
i2cAckMCU();发送完读地址后,需要应答一下
}
RdataReadByte24LC16B();
i2cNoAckMCU();读取最后一个字节需要非应答
i2cStop();
delay(2000);
}