继模拟I2C驱动到DS1307日历模块之后,顺便测试了日历模块上附带的AT24C32EEPROM芯片,这是32K内存的EEPROM,共4096*8位,也就是说其内部地址最大为4096,超过了8位地址的最大值256,其内部寻址使用的是16位地址,在I2C向器件发送内部寻址时要先发送高8位的地址,再发送低8位的地址,其读写的代码如下:
/******************************************************************************************
* 函数名称: I2C_16bitByteRead()
* 功能说明: 从指定地址addr开始获取1个字节的数据
* 输 入: uint8_t I2Caddr 器件地址
* uint16_t addr 双字节数据地址
* 输 出: uint8_t 返回读取的数值
* 备 注:
******************************************************************************************/
uint8_t SI2C_16bitByteRead(uint8_t I2Caddr,uint16_t addr)
{
uint8_t dat;
SI2C_Start(); //产生起始信号
SI2C_Send(I2Caddr); //发送器件地址及读写位,0表示写
if(SI2CIsAck()) //检测从设备是否有响应
{
SI2C_Stop(); //产生停止信号
return 2;
}
SI2C_Send(addr>>8); //发送读取数据的起始地址高8位
if(SI2CIsAck()) //检测从设备是否有响应
{
SI2C_Stop(); //产生停止信号
return 3;
}
SI2C_Send(addr|0x0F); //发送读取数据的起始地址低8位
if(SI2CIsAck()) //检测器件是否有响应
{
SI2C_Stop(); //产生停止信号
return 3;
}
SI2C_Start(); //产生Repeated Start
SI2C_Send(I2Caddr|1); //发送从设备芯片地址及读写位,1表示读
if(SI2CIsAck()) //检测从设备是否有响应
{
SI2C_Stop(); //产生停止信号
return 4;
}
dat = SI2C_Receive();
SI2CDoAck();
SI2CNoAck(); //从设备要求必须使用NOAck来结束数据读取
SI2C_Stop(); //产生停止信号
return dat;
}
/******************************************************************************************
* 函数名称: I2C_16bitByteWrite()
* 功能说明: 从指定地址addr开始写入1个字节的数据
* 输 入: uint8_t I2Caddr 器件地址
* uint16_t addr 双字节数据地址
* 输 出: uint8_t 返回读取的数值
* 备 注:
******************************************************************************************/
uint8_t SI2C_16bitByteWrite(uint8_t I2Caddr,uint16_t addr,uint8_t dat)
{
SI2C_Start(); //产生起始信号
SI2C_Send(I2Caddr|0); //发送从设备芯片地址及读写位,0表示写
if(SI2CIsAck()) //检测从设备是否有响应
{
SI2C_Stop(); //产生停止信号
return 1;
}
SI2C_Send(addr>>8); //发送读取数据的起始地址
if(SI2CIsAck()) //检测从设备是否有响应
{
SI2C_Stop(); //产生停止信号
return 3;
}
SI2C_Send(addr|0x0F); //发送读取数据的起始地址低8位
if(SI2CIsAck()) //检测器件是否有响应
{
SI2C_Stop(); //产生停止信号
return 3;
}
SI2C_Send(dat);
if(SI2CIsAck()) //检测从设备是否有响应
{
SI2C_Stop(); //产生停止信号
return 3;
}
SI2C_Stop(); //产生停止信号
return 0;
}
下面是测试代码,在主循环中每秒钟调用一次:
void AT24C32_Test(void)
{
uint8_t Txt[16];
SI2C_16bitBuffRead( 0xA0, 0, 16, Txt);
LCD_write_ASCII(0, 5, 1, Txt);
Txt[0] = 'D';
Txt[1] = year / 1000 + 0x30;
Txt[2] = year % 1000 / 100 + 0x30;
Txt[3] = year % 100 / 10 + 0x30;
Txt[4] = year % 10 + 0x30;
Txt[5] = month / 10 + 0x30;
Txt[6] = month % 10 + 0x30;
Txt[7] = day / 10 + 0x30;
Txt[8] = day % 10 + 0x30;
Txt[9] = hour / 10 + 0x30;
Txt[10] = hour % 10 + 0x30;
Txt[11] = minute / 10 + 0x30;
Txt[12] = minute % 10 + 0x30;
Txt[13] = second / 10 + 0x30;
Txt[14] = second % 10 + 0x30;
Txt[15] = 0;
SI2C_16bitBuffWrite( 0xA0, 0, 16, Txt);
}
这是测试过程的照片:
|