51单片机模拟I2C读写M24LR04

mac2024-04-05  33

目录

一、 有关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.以上代码展示的是简单的读写一字节数据,如果要想进行加密写的话,只需要先写对应的密码,再写数据就好了。读数据不受加密限制。

最新回复(0)