?? 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 + -