目录
一、 有关M24LR04的介绍
二、 I2C的读写时序
三、 参考代码
四、 调试中遇到的问题
一、 有关M24LR04的介绍
M24LR04是ST公司的一款NFC芯片,支持ISO15693和ISO1800-3等协议,存储结构2048x32位。在RF模式下,采用13.56Mhz无线电载波通信;在I2C模式下,作为从机应答主机的请求。
该芯片支持写数据加密,支持一组I2C密码和三组RF密码。
二、 I2C的读写时序
设备选择码:当作为I2C的从机时,设备选择码组成为1010+E2 E1 E0+读写位。其中E1和E0默认为00;当读写数据时,E2的值为0,当访问扇区安全字节区时,E2的值为1。
以下是I2C的读写数据和写密码的时序图。
三、 参考代码
/*------------------------------------------------------------------------*/
sbit SCL = P1^2;
sbit SDA = P3^0;
#define SDA_IO_Out (P3CON |= (1<<0)) //设置IO口为输出
#define SDA_IO_In (P3CON &= ~(1<<0)) //设置IO口为输入
/***************************************以下为模拟I2C部分****************************************************/
void delay(uint cnt)
{
uint m,n;
for(m=0;m<cnt;m++)
for(n=0;n<10;n++);
}
static void I2c_start()
{
SDA_IO_Out;
SDA=1;
delay(1);
SCL=1;
delay(1);
SDA=0;
delay(1);
SCL=0;
delay(1);
}
static void I2c_stop()
{
SDA_IO_Out;
SDA=0;
delay(1);
SCL=1;
delay(1);
SDA=1;
delay(1);
}
//发送ack或者nack
static void I2c_sendAck(bit ack)
{
SDA_IO_Out;
SDA = ack;
SCL = 1;
delay(1);
SCL = 0;
delay(1);
}
//等待ack
static bit I2c_getAck(void)
{
bit ack;
SDA_IO_In;
SCL = 1;
delay(1);
ack = SDA;
SCL = 0;
delay(1);
return ack;
}
static u8 I2c_read()
{
u8 i,dat=0;
SDA_IO_In;
for(i=0;i<8;i++)
{
SDA =1;
SCL=1;
delay(1);
dat=dat<<1;
dat|=SDA;
delay(1);
SCL=0;
delay(1);
}
return dat;
}
static void I2c_write(u8 dat)
{
u8 i;
SDA_IO_Out;
for(i=0;i<8;i++)
{
SDA=dat>>7;
dat<<=1;
delay(1);
SCL=1;
delay(1);
SCL=0;
delay(1);
}
I2c_getAck();
}
void WriteOneByteToDevice(u8 deviceCode,u16 datAddr,u8 dat)
{
I2c_start();
I2c_write(deviceCode);
I2c_write(datAddr<<8);
I2c_write((u8)datAddr);
I2c_write(dat);
I2c_stop();
}
u8 ReadOneByteFromDevice(u8 deviceCode,u16 datAddr )
{
u8 dat;
I2c_start();
I2c_write(deviceCode);
I2c_write(datAddr<<8);
I2c_write((u8)datAddr);
I2c_start();
I2c_write(deviceAddr+1);
dat=I2c_read();
I2c_sendAck(1);
I2c_stop();
return dat;
}
/******demo*********/
WriteOneByteToDevice(0xA6,0x0004,0x55);
ReadOneByteFromDevice(0xA6,0x0004);
四、 调试中遇到的问题
1. 因为是模拟的I2C,SDA脚在数据交互时,有可能作为输出脚向从机发送数据,也有可能作为输入脚读取从机返回的数据。所以要特别注意控制改引脚对应的IO口方向(对应代码中的SDA_IO_Out 和 SDA_IO_In)。如果不加上IO口方向控制,I2c波形可能出现畸形,导致读取数据失败。如下图
正常读取数据的波形
2.以上代码展示的是简单的读写一字节数据,如果要想进行加密写的话,只需要先写对应的密码,再写数据就好了。读数据不受加密限制。