软件模拟IIC读写M24C08

1.M24c08.c

#include "M24c08.h"

#include "Delay.h"

#define  M24C08_READ_ADDR      (0xA1) //M24C08的I2C地址(7Bit模式)
#define  M24C08_WRITE_ADDR     (0xA0)


#define I2C_DELAY() rt_hw_us_delay(2)



static void i2c_start(void)
{
	M24C08_SCL_1;
	
    M24C08_SDA_1;
    I2C_DELAY();
    M24C08_SDA_0;
    I2C_DELAY();
    M24C08_SCL_0;
    I2C_DELAY();
}

static void i2c_stop(void)
{
    M24C08_SDA_0;
    I2C_DELAY();
    M24C08_SCL_1;
    I2C_DELAY();
    M24C08_SDA_1;
    I2C_DELAY();
}

static void i2c_ack(void)
{
    M24C08_SDA_0;
    I2C_DELAY();
    M24C08_SCL_1;
    I2C_DELAY();
    M24C08_SCL_0;
    I2C_DELAY();
    M24C08_SDA_1;
    I2C_DELAY();
}

static void i2c_nack(void)
{
    M24C08_SDA_1;
    I2C_DELAY();
    M24C08_SCL_1;
    I2C_DELAY();
    M24C08_SCL_0;
    I2C_DELAY();
}

static uint8_t i2c_write_byte(uint8_t byte)
{
    uint8_t i, ack;

    for (i = 0; i < 8; i++) {
        if (byte & 0x80) {
            M24C08_SDA_1;
        } else {
            M24C08_SDA_0;
        }

        I2C_DELAY();
        M24C08_SCL_1;
        I2C_DELAY();
        M24C08_SCL_0;
        I2C_DELAY();

        byte <<= 1;
    }

    M24C08_SDA_1;
    I2C_DELAY();
    M24C08_SCL_1;
    I2C_DELAY();

    ack = M24C08_SDA_INPUT ? 0 : 1;

    M24C08_SCL_0;
    I2C_DELAY();

    return ack;
}

static uint8_t i2c_read_byte(uint8_t ack)
{
    uint8_t i, byte = 0;

    M24C08_SDA_1;

    for (i = 0; i < 8; i++) {
        byte <<= 1;

        M24C08_SCL_1;
        I2C_DELAY();

        if (M24C08_SDA_INPUT) {
            byte |= 0x01;
        }

        M24C08_SCL_0;
        I2C_DELAY();
    }

    if (ack) {
        i2c_ack();
    } else {
        i2c_nack();
    }

    return byte;
}
/*
函数功能: 写一个字节
函数参数:
	uint16_t addr 数据的位置(0~1023)
	uint8_t data 数据范围(0~255)
*/
void M24C08_WriteOneByte(uint16_t addr,uint8_t data)
{
    uint8_t read_device_addr=M24C08_READ_ADDR;
	uint8_t write_device_addr=M24C08_WRITE_ADDR;
    if(addr<256*1) //第一个块
    {
        write_device_addr|=0x0<<1;
        read_device_addr|=0x0<<1;
    }
    else if(addr<256*2) //第二个块
    {
        write_device_addr|=0x1<<1;
        read_device_addr|=0x1<<1;
    }
    else if(addr<256*3) //第三个块
    {
        write_device_addr|=0x2<<1;
        read_device_addr|=0x2<<1;
    }
    else if(addr<256*4) //第四个块
    {
        write_device_addr|=0x3<<1;
        read_device_addr|=0x3<<1;
    }
    addr=addr%256; //得到地址范围

    
    i2c_start();//起始信号
    i2c_write_byte(write_device_addr);//发送设备地址
    i2c_write_byte(addr); //数据存放的地址
    i2c_write_byte(data); //发送将要存放的数据
    i2c_stop(); //停止信号
    rt_hw_us_delay(10000); //等待写
}
/*
函数功能: 读一个字节
函数参数:
	uint16_t addr 数据的位置(0~1023)
返回值: 读到的数据
*/
uint8_t M24C08_ReadOneByte(uint16_t addr)
{
    uint8_t data=0;
    uint8_t read_device_addr=M24C08_READ_ADDR;
	uint8_t write_device_addr=M24C08_WRITE_ADDR;
    if(addr<256*1) //第一个块
    {
        write_device_addr|=0x0<<1;
        read_device_addr|=0x0<<1;
    }
    else if(addr<256*2) //第二个块
    {
        write_device_addr|=0x1<<1;
        read_device_addr|=0x1<<1;
    }
    else if(addr<256*3) //第三个块
    {
        write_device_addr|=0x2<<1;
        read_device_addr|=0x2<<1;
    }
    else if(addr<256*4) //第四个块
    {
        write_device_addr|=0x3<<1;
        read_device_addr|=0x3<<1;
    }
    addr=addr%256; //得到地址范围

    i2c_start();//起始信号
    i2c_write_byte(write_device_addr);//发送设备地址
    i2c_write_byte(addr); //将要读取数据的地址
    i2c_start();//起始信号
    i2c_write_byte(read_device_addr);//发送设备地址
    data=i2c_read_byte(0);//读取数据
    i2c_stop(); //停止信号
    return data;
}


/*
函数功能: 从指定位置读取指定长度的数据
函数参数:
	uint16_t addr 数据的位置(0~1023)
	uint16_t len 读取的长度
	uint8_t *buffer 存放读取的数据
返回值: 读到的数据
*/
void M24C08_ReadByte(uint16_t addr,uint16_t len,uint8_t *buffer)
{
	uint16_t i=0;
	uint8_t read_device_addr=M24C08_READ_ADDR;
	uint8_t write_device_addr=M24C08_WRITE_ADDR;
	if(addr<256*1) //第一个块
	{
		write_device_addr|=0x0<<1;
		read_device_addr|=0x0<<1;
	}
	else if(addr<256*2) //第二个块
	{
		write_device_addr|=0x1<<1;
		read_device_addr|=0x1<<1;
	}
	else if(addr<256*3) //第三个块
	{
		write_device_addr|=0x2<<1;
		read_device_addr|=0x2<<1;
	}
	else if(addr<256*4) //第四个块
	{
		write_device_addr|=0x3<<1;
		read_device_addr|=0x3<<1;
	}
		
	i2c_start();//起始信号
	i2c_write_byte(write_device_addr);//发送设备地址
	i2c_write_byte(addr); //将要读取数据的地址	
	i2c_start();//起始信号
	i2c_write_byte(read_device_addr);//发送设备地址
	
	for(i=0;i<len;i++)
	{
			buffer[i]=i2c_read_byte(i == len - 1 ? 0 : 1);//读取数据
	}
	i2c_stop(); //停止信号
}


/*
函数功能: M24C08页写函数
函数参数:
	uint16_t addr 写入的位置(0~1023)
	uint16_t len 写入的长度(每页16字节)
	uint8_t *buffer 存放读取的数据
*/
void M24C08_PageWrite(uint16_t addr,uint16_t len,uint8_t *buffer)
{
		uint16_t i=0;
	    uint8_t read_device_addr=M24C08_READ_ADDR;
		uint8_t write_device_addr=M24C08_WRITE_ADDR;
		if(addr<256*1) //第一个块
		{
			write_device_addr|=0x0<<1;
			read_device_addr|=0x0<<1;
		}
		else if(addr<256*2) //第二个块
		{
			write_device_addr|=0x1<<1;
			read_device_addr|=0x1<<1;
		}
		else if(addr<256*3) //第三个块
		{
			write_device_addr|=0x2<<1;
			read_device_addr|=0x2<<1;
		}
		else if(addr<256*4) //第四个块
		{
			write_device_addr|=0x3<<1;
			read_device_addr|=0x3<<1;
		}
		addr=addr%256; //得到地址范围
		i2c_start();//起始信号
		i2c_write_byte(write_device_addr);//发送设备地址
		i2c_write_byte(addr); //数据存放的地址
		for(i=0;i<len;i++)
		{
			i2c_write_byte(buffer[i]); //发送将要存放的数据
		}
		i2c_stop(); //停止信号
		rt_hw_us_delay(10000); //等待写
}


/*
函数功能: 从指定位置写入指定长度的数据
函数参数:
	uint16_t addr 数据的位置(0~1023)
	uint16_t len 写入的长度
	uint8_t *buffer 存放即将写入的数据
返回值: 读到的数据
*/
void M24C08_WriteByte(uint16_t addr,uint16_t len,uint8_t *buffer)
{
		uint8_t page_byte=16-addr%16; //得到当前页剩余的字节数量
		if(page_byte>len) //判断当前页剩余的字节空间是否够写
		{
				page_byte=len; //表示一次性可以写完
		}
		while(1)
		{
				M24C08_PageWrite(addr,page_byte,buffer); //写一页
				if(page_byte==len)break; //写完了
				buffer+=page_byte; //指针偏移
				addr+=page_byte;//地址偏移
				len-=page_byte;//得到剩余没有写完的长度
				if(len>16)page_byte=16;
				else page_byte=len; //一次可以写完
		}
}
//void i2c_write(uint8_t addr, uint8_t *data, uint16_t len)
//{
//    uint16_t i;

//    i2c_start();

//    i2c_write_byte(M24C08_I2C_ADDR << 1);
//    i2c_write_byte(addr);

//    for (i = 0; i < len; i++) {
//        i2c_write_byte(data[i]);
//    }

//    i2c_stop();
//}

//void M24C08_Write(uint8_t addr, uint8_t *data, uint16_t len)
//{
//	uint16_t In,Re;
//	In = (uint16_t)(len/16);
//	Re = (uint16_t)(len%16);
//	for(uint16_t i = 0;i < In;i++)
//	{
//		i2c_write(addr+0x10*i,&data[i*16],16);
//	}
//	i2c_write(addr+0x10*In,&data[In*16],Re);
//}

//void i2c_read(uint8_t addr, uint8_t *data, uint16_t len)
//{
//    uint16_t i;

//    i2c_start();

//    i2c_write_byte(M24C08_I2C_ADDR << 1);
//    i2c_write_byte(addr);

//    i2c_start();

//    i2c_write_byte((M24C08_I2C_ADDR << 1) | 0x01);

//    for (i = 0; i < len; i++) {
//        data[i] = i2c_read_byte(i == len - 1 ? 0 : 1);
//    }

//    i2c_stop();
//}

2.M24co8.h

#ifndef  __M24C08_H__
#define  __M24C08_H__

#include <stdint.h>
#include "System.h"



#define  M24C08_WRITE_0             PDout(12)=0
#define  M24C08_WRITE_1             PDout(12)=1

#define  M24C08_SCL_0               PDout(13)=0
#define  M24C08_SCL_1               PDout(13)=1
#define  M24C08_SDA_0               PDout(14)=0
#define  M24C08_SDA_1               PDout(14)=1
#define  M24C08_SDA_INPUT           HAL_GPIO_ReadPin(GPIOD,M24C04_SDA_Pin)

//void i2c_write(uint8_t addr, uint8_t *data, uint16_t len);
//void i2c_read(uint8_t addr, uint8_t *data, uint16_t len);
//void M24C08_Write(uint8_t addr, uint8_t *data, uint16_t len);
uint8_t M24C08_ReadOneByte(uint16_t addr);
void M24C08_WriteOneByte(uint16_t addr,uint8_t data);

void M24C08_ReadByte(uint16_t addr,uint16_t len,uint8_t *buffer);
void M24C08_WriteByte(uint16_t addr,uint16_t len,uint8_t *buffer);
#endif

具体的IIC管脚只需在.h文件配置即可。

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值