用逐飞库实现单片机的IIC通信

最近准备智能车比赛,收到指导老师启发,准备做一个模块,实现手机和单片机之间通过WIFi通信修改参数,并存在EEPROM中的功能.由于WIFI模块没到,所以先解决EEPROM的读写.
EEPROM选的AT24C02,也是比较常见的储存器了,由于32和51都有例程,所以开始的时候根据逐飞的库照着例程写程序,想着能方便点.结果碰到了问题,写不进数据也读不了,又没有标准例程,就只好看看库函数找问题,最后发现问题出在库函数对地址的处理上.
下面是地址说明:
器件地址
在这里插入图片描述

在这里插入图片描述
先看51例程的读写函数:

/*******************************************************************************
* 函数名         : void At24c02Write(unsigned char addr,unsigned char dat)
* 函数功能		   : 往24c02的一个地址写入一个数据
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/

void At24c02Write(unsigned char addr,unsigned char dat)
{
	I2cStart();
	I2cSendByte(0xa0);//发送写器件地址
	I2cSendByte(addr);//发送要写入内存地址
	I2cSendByte(dat);	//发送数据
	I2cStop();
}
/*******************************************************************************
* 函数名         : unsigned char At24c02Read(unsigned char addr)
* 函数功能		   : 读取24c02的一个地址的一个数据
* 输入           : 无
* 输出         	 : 无
*******************************************************************************/

unsigned char At24c02Read(unsigned char addr)
{
	unsigned char num;
	I2cStart();
	I2cSendByte(0xa0); //发送写器件地址
	I2cSendByte(addr); //发送要读取的地址
	I2cStart();
	I2cSendByte(0xa1); //发送读器件地址
	num=I2cReadByte(); //读取数据
	I2cStop();
	return num;	
}

由于三个地址位都接了地,AT24C02的地址前7位是0101000,所以写地址就是01010000(即0xA0),读地址就是01010001(即0xA1)

再看到逐飞的库函数:

//-------------------------------------------------------------------------------------------------------------------
// @brief		模拟IIC写数据到设备寄存器函数
// @param		dev_add			设备地址(低七位地址)
// @param		reg				寄存器地址
// @param		dat				写入的数据
// @return		void						
// @since		v1.0
// Sample usage:				
//-------------------------------------------------------------------------------------------------------------------
void simiic_write_reg(uint8 dev_add, uint8 reg, uint8 dat)
{
	simiic_start();
	send_ch( (dev_add<<1) | 0x00);													// 发送器件地址加写位
	send_ch( reg );																	// 发送从机寄存器地址
	send_ch( dat );																	// 发送需要写入的数据
	simiic_stop();
}

//-------------------------------------------------------------------------------------------------------------------
// @brief		模拟IIC从设备寄存器读取数据
// @param		dev_add			设备地址(低七位地址)
// @param		reg				寄存器地址
// @param		type			选择通信方式是IIC  还是 SCCB
// @return		uint8			返回寄存器的数据
// @since		v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
uint8 simiic_read_reg(uint8 dev_add, uint8 reg, IIC_type type)
{
	uint8 dat;
	simiic_start();
	send_ch( (dev_add<<1) | 0x00);													// 发送器件地址加写位
	send_ch( reg );																	// 发送从机寄存器地址
	if(type == SCCB)simiic_stop();

	simiic_start();
	send_ch( (dev_add<<1) | 0x01);													// 发送器件地址加读位
	dat = read_ch(SEEKFREE_NACK);													// 读取数据
	simiic_stop();

	return dat;
}

虽然写地址还是0xA0,读地址还是0xA1,但是可以看到在读写函数里都进行了(地址左移一位+读/写位)的操作,所以我们应该填的地址不是0xA0或者0xA1,而是01010000,即0x50.

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值