📄 i2c_512.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 + -