⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_512.c

📁 程序概述: 这是个具体产品程序
💻 C
字号:
// Copyright (c)2005 - 2006 by Laser Electronics, All Rights Reserved.
/*----------------------------------------------------------------------------+
|  File Name:  I2C.c, v1.0.1                                                  |
|  Author:                                                                    |
|  Date:                                                                      |
+-----------------------------------------------------------------------------+
|  Description: 联网型智能楼宇对讲系统 -- 管理中心机对AT24C512操作的程序程序  |
|               器件选择 -- STC89C58RD+, PQFP-44                              |
|               时钟频率 -- 24.000 MHz                                        |
+-----------------------------------------------------------------------------+

/*----------------------------------------------------------------------------+
| Include files                                                               |
+----------------------------------------------------------------------------*/
#include "main.h"
#include "I2C_512.h"


/*----------------------------------------------------------------------------+
| Type Definition & Macro                                                     |
+----------------------------------------------------------------------------*/
#ifndef SCL
#define SCL   P2_1
#endif

#ifndef SDA
#define SDA   P2_0
#endif

// 定义芯片每页的的容量, 各芯片的页大小如下:
// 24C01:     8字节     0x08
// 24C02:     8字节     0x08
// 24C04:    16字节     0x10
// 24C08:    16字节     0x10
// 24C16:    16字节     0x10
// -------------------------
// 24C32:    32字节     0x20
// 24C64:    32字节     0x20
// 24C128:   64字节     0x40
// 24C256:   64字节     0x40
// 24C512:  128字节     0x80
// -------------------------
// 24C1024: 256字节     0x100

// 定义I2C操作失败时重试的次数
#define I2C_MAX_TRY_TIMES    3

/*-----------------------------------------------------------------------------
| 函数说明:开始位
-----------------------------------------------------------------------------*/
void I2CStart(void)
{
	SCL = 0;
	SCL = 1;
	SDA = 1;
	_nop_();
	_nop_();
	SDA = 0;
	_nop_();
	_nop_();
	SCL = 0;
	SDA = 1;
}

/*-----------------------------------------------------------------------------
| 函数说明:停止位
-----------------------------------------------------------------------------*/
void I2CStop(void)
{
	SCL = 0;
	SDA = 0;
	SCL = 1;
	_nop_();
	_nop_();
	_nop_();
	SDA = 1;
	_nop_();
	_nop_();
	_nop_();
	SCL = 0;
}

/*-----------------------------------------------------------------------------
| 往I2C芯片发送一个8位的数据
-----------------------------------------------------------------------------*/
BOOL I2CSendByte(BYTE aData)
{
	BYTE i = 8;

	do
	{
		SCL = 0;
		_nop_();
		SDA = (aData&0x80);
		aData <<= 1;
		SCL = 1;
	}while(--i);
	SCL = 0;

	// 等待应答
	SDA = 1;                    // For input direct
	_nop_();
	SCL = 1;
	for (i=10; i>0; i--)
	{
		if (SDA == 0)
		{
			SCL = 0;
			return TRUE;
		}
	}
	SCL = 0;
	return FALSE;
}

/*-----------------------------------------------------------------------------
| 从I2C芯片接收一个8位的数据
-----------------------------------------------------------------------------*/
BYTE I2CReceiveByte(BOOL last_char)
{
	BYTE i;
	BYTE temp;

	i = 8;
	temp = 0x00;
	do {
		SCL=1;
		temp <<= 1;
		if (SDA)
			temp |= 0x01;
		else
			_nop_();
		SCL=0;
		_nop_();
	}while(--i);

	// 应答
	if (last_char)
	{
		// 最后一个字符, 不再需要应答信号
		SDA = 1;
		_nop_();
		SCL = 1;
		_nop_();
		_nop_();
		_nop_();
		SCL = 0;
	}
	else
	{
		// 应答
		SDA=0;
		_nop_();
		SCL=1;
		_nop_();
		_nop_();
		_nop_();
		SCL=0;
		_nop_();
		_nop_();
		SDA=1;
	}
	return temp;
}

/*-----------------------------------------------------------------------------
| 尝试从24C512读多个字节
| Device:  器件地址,最低2位有效,0x00~0x03,表示I2C芯片的硬件连接
| Addr:    存储器地址, 范围从0x0000到0xFFFF
| pBuf:    指向存放读出的数据缓冲区的指针
| nLength: 需要读取的数据长度
-----------------------------------------------------------------------------*/
BOOL I2CTryReadString(BYTE Device, UINT Addr, BYTE *pBuf, BYTE nLength)
{
	BYTE PageNum;               // 当前页需要读取的字节数
	BYTE i;

	Device <<= 1;

	while (nLength)
	{
		if (nLength > (I2C_PAGE_SIZE-(Addr&(I2C_PAGE_SIZE-1)))) // 一页读不完这些数据,需要转到下一页
			PageNum = I2C_PAGE_SIZE - (Addr&(I2C_PAGE_SIZE-1));
		else
			PageNum = nLength;

		I2CStart();
		if (!I2CSendByte(0xA0|Device)) return FALSE;    // 器件地址
		if (!I2CSendByte(Addr>>8))   return FALSE;      // 数据地址高8位
		if (!I2CSendByte(Addr&0xFF)) return FALSE;      // 数据地址低8位

		I2CStart();
		if (!I2CSendByte(0xA1|Device)) return FALSE;

		for (i=1; i<PageNum; i++)
		{
			*pBuf = I2CReceiveByte(FALSE);
			pBuf ++;
		}
		*pBuf = I2CReceiveByte(TRUE);
		I2CStop();

		nLength -= PageNum;             // 下一次循环还剩下的长度
		Addr += PageNum;                // 下一次循环的起始地址
	}
	return TRUE;
}

/*-----------------------------------------------------------------------------
| 尝试往24C512写多个字节
| Device:  器件地址,最低2位有效,0x00~0x03,表示I2C芯片的硬件连接
| Addr:    存储器地址, 范围从0x0000到0xFFFF
| pBuf:    指向需要写入的数据缓冲区的指针
| nLength: 需要写入的数据长度
-----------------------------------------------------------------------------*/
BOOL I2CTryWriteString(BYTE Device, UINT Addr, BYTE *pBuf, BYTE nLength)
{
// 一次写一页,每页128字节
	BYTE PageNum;               // 当前页需要写入的字节数
	BYTE i;

	Device <<= 1;               // 最低位用来表示读(1)还是写(0)

	while (nLength)
	{
		Delayms(I2C_WRITE_CYCLE_TIME);  // 每次写操作完成后要等待一定的时间

		if (nLength > (I2C_PAGE_SIZE-(Addr&(I2C_PAGE_SIZE-1)))) // 一页写不完这些数据,需要转到下一页
			PageNum = I2C_PAGE_SIZE - (Addr&(I2C_PAGE_SIZE-1));
		else
			PageNum = nLength;

		I2CStart();
		if (!I2CSendByte(0xA0|Device)) return FALSE;    // 器件地址
		if (!I2CSendByte(Addr>>8))   return FALSE;      // 数据地址高8位
		if (!I2CSendByte(Addr&0xFF)) return FALSE;      // 数据地址低8位

		for (i=0; i<PageNum; i++)
		{
			if (!I2CSendByte(*pBuf)) return FALSE;
			pBuf ++;
		}
		I2CStop();

		nLength -= PageNum;             // 下一次循环还剩下的长度
		Addr += PageNum;                // 下一次循环的起始地址
	}
	return TRUE;
}

/*-----------------------------------------------------------------------------
| 从24C512读多个字节
| Device:  器件地址,最低2位有效,0x00~0x03,表示I2C芯片的硬件连接
| Addr:    存储器地址, 范围从0x0000到0xFFFF
| pBuf:    指向存放读出的数据缓冲区的指针
| nLength: 需要读取的数据长度
-----------------------------------------------------------------------------*/
BOOL I2CReadString(BYTE Device, UINT Addr, BYTE *pBuf, BYTE nLength)
{
	BYTE i = I2C_MAX_TRY_TIMES;

	do {
		if (I2CTryReadString(Device, Addr, pBuf, nLength))
			return TRUE;
		I2CStop();
		RESET_WDT;
		Delayms(I2C_WRITE_CYCLE_TIME);
	}while (--i);
	return FALSE;
}

/*-----------------------------------------------------------------------------
| 往24C512写多个字节
| Device:  器件地址,最低2位有效,0x00~0x03,表示I2C芯片的硬件连接
| Addr:    存储器地址, 范围从24C01的0x007F到24C16的0x07FF
| pBuf:    指向需要写入的数据缓冲区的指针
| nLength: 需要写入的数据长度
-----------------------------------------------------------------------------*/
BOOL I2CWriteString(BYTE Device, UINT Addr, BYTE *pBuf, BYTE nLength)
{
	BYTE i = I2C_MAX_TRY_TIMES;

	do {
		if (I2CTryWriteString(Device, Addr, pBuf, nLength))
			return TRUE;
		I2CStop();
		RESET_WDT;
		Delayms(I2C_WRITE_CYCLE_TIME);
	}while (--i);
	return FALSE;
}

/*----------------------------------------------------------------------------+
| End of source file                                                          |
+----------------------------------------------------------------------------*/
/*------------------------ Nothing Below This Line --------------------------*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -