?? iic.c
字號:
#include <reg51.h> /*頭文件的包含*/
#include <intrins.h>
#define BYTE unsigned char /*宏定義*/
#define WORD unsigned int
#define _Nop() _nop_() /*定義空指令*/
/* 常量、變量定義區 */
/*端口位定義*/
sbit SDA = P1^3; /*模擬I2C數據傳送位*/
sbit SCL = P1^2; /*模擬I2C時鐘控制位*/
/*狀態標志*/
bit ack; /*應答標志位*/
/*******************************************************************
起動總線函數
函數原型:
void Start_I2C();
功能:
啟動I2C總線,即發送I2C起始條件。
參數:
無。
返回值:
無。
********************************************************************/
void Start_I2C()
{
SDA = 1; /*發送起始條件的數據信號*/
_Nop();
SCL = 1;
_Nop(); /* 起始條件建立時間大于4us,延時 */
_Nop();
_Nop();
_Nop();
_Nop();
SDA = 0; /* 發送起始信號 */
_Nop(); /* 起始條件鎖定時間大于4 us */
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 0; /* 準備發送或接收數據 */
_Nop();
_Nop();
}
/*******************************************************************
結束總線函數
函數原型:
void Stop_I2C();
功能:
結束I2C總線,即發送I2C結束條件。
參數:
無。
返回值:
無。
********************************************************************/
void Stop_I2C()
{
SDA = 0; /* 發送結束條件的數據信號 */
_Nop(); /* 發送結束條件的時鐘信號 */
SCL = 1; /* 結束條件建立時間大于4 us */
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA = 1; /* 發送I2C總線結束信號 */
_Nop();
_Nop();
_Nop();
_Nop();
}
/*******************************************************************
字節數據傳送函數
函數原型:
void SendByte(BYTE data);
功能:
將數據data發送出去,可以是地址,也可以是數據,發完后等待應答,并對此狀態
位進行操作。(不應答或非應答都使ack = 0) 發送數據正常,ack=1;ack=0
表示接收器無應答或損壞。
參數:
需要發送的數據。
返回值:
無。
********************************************************************/
void SendByte(BYTE data)
{
BYTE BitCount;
for(BitCount = 0; BitCount < 8; BitCount ++) /* 要傳送的數據長度為8位 */
{
if((data << BitCount) & 0x80) SDA = 1; /* 判斷發送位 */
else SDA = 0;
_Nop();
SCL = 1; /* 置時鐘線為高,通知被控器開始接收數據位 */
_Nop();
_Nop(); /* 保證時鐘高電平周期大于4 us */
_Nop();
_Nop();
_Nop();
SCL = 0;
}
_Nop();
_Nop();
SDA = 1; /* 8位發送完后釋放數據線,準備接收應答位*/
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA == 1) ack = 0;
else ack = 1; /* 判斷是否接收到應答信號*/
SCL=0;
_Nop();
_Nop();
}
/*******************************************************************
字節數據傳送函數
函數原型:
BYTE RecByte();
功能:
用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),發完后請用
應答函數。
參數:
無。
返回值:
讀取到的數據。
********************************************************************/
BYTE RecByte()
{
BYTE RecData;
BYTE BitCount;
RecData = 0;
SDA = 1; /* 置數據線為輸入方式 */
for(BitCount = 0; BitCount < 8; BitCount ++)
{
_Nop();
SCL=0; /* 置時鐘線為低,準備接收數據位 */
_Nop();
_Nop(); /* 時鐘低電平周期大于4.7us */
_Nop();
_Nop();
_Nop();
SCL= 1; /* 置時鐘線為高使數據線上數據有效 */
_Nop();
_Nop();
RecData = RecData << 1;
if(SDA==1) RecData = RecData +1; /* 讀數據位,接收的數據位放入retc中 */
_Nop();
_Nop();
}
SCL= 0;
_Nop();
_Nop();
return(RecData);
}
/********************************************************************
應答子函數
原型:
void Ack_I2C(bit a);
功能:
主控器進行應答信號,,(可以是應答或非應答信號)
參數:
應答信號。
返回值:
無。
********************************************************************/
void Ack_I2c(bit a)
{
if(a == 0) SDA = 0; /* 在此發出應答或非應答信號 */
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL = 1;
_Nop();
_Nop(); /* 時鐘低電平周期大于4us */
_Nop();
_Nop();
_Nop();
SCL = 0; /* 清除時鐘線,以便繼續接收 */
_Nop();
_Nop();
}
/*******************************************************************
向無子地址器件發送字節數據函數
函數原型:
bit SendByteData(BYTE Slave,BYTE Data);
功能:
從啟動總線到發送地址,數據,結束總線的過程。
參數:
slave--從器件地址。
data --要發送的數據。
返回值:
如果返回1表示操作成功,否則操作有誤。
注意:
使用前必須已結束總線。
********************************************************************/
bit SendByteData (BYTE Slave, BYTE Data)
{
Start_I2C(); /* 啟動總線 */
SendByte(Slave); /* 發送器件地址 */
if(ack == 0) return(0);
SendByte(Data); /* 發送數據 */
if(ack == 0) return(0);
Stop_I2C(); /* 結束總線 */
return(1);
}
/*******************************************************************
向有子地址器件發送多字節數據函數
函數原型:
bit SendStr(BYTE Slave, BYTE SubAddress, BYTE *Source, BYTE Num);
功能:
從啟動總線到發送地址,子地址,數據,結束總線的過程。
參數:
Slave--從器件地址
SubAddress--子地址
Source--指向發送內容的指針
Num--發送字節個數
返回值:
如果返回1表示操作成功,否則操作有誤。
注意:
使用前必須已結束總線。
********************************************************************/
bit SendStr(BYTE Slave, BYTE SubAddress, BYTE *Source, BYTE Num)
{
BYTE i;
Start_I2C(); /* 啟動總線 */
SendByte(Slave); /* 發送器件地址 */
if(ack == 0) return(0);
SendByte(SubAddress); /* 發送器件子地址 */
if(ack == 0) return(0);
for(i = 0; i < Num; i++)
{
SendByte(*Source); /* 發送數據 */
if(ack == 0) return(0);
Source ++;
}
Stop_I2C(); /* 結束總線 */
return(1);
}
/*******************************************************************
向無子地址器件讀字節數據函數
函數原型:
bit RecByteData(BYTE Slave,BYTE *Data);
功能:
從啟動總線到發送地址,讀數據,結束總線的過程。
參數:
從器件地址Slave,返回值在Data。
返回值:
如果返回1表示操作成功,否則操作有誤。
注意:
使用前必須已結束總線。
********************************************************************/
bit RecByteData(BYTE Slave,BYTE *Data)
{
Start_I2C(); /* 啟動總線 */
SendByte(Slave+1); /* 發送器件地址 */
if(ack == 0) return(0);
*Data = RecByte(); /* 讀取數據 */
Ack_I2C(1); /* 發送非就答位 */
Stop_I2C(); /* 結束總線 */
return(1);
}
/*******************************************************************
向有子地址器件讀取多字節數據函數
函數原型:
bit RecStr(BYTE Slave, BYTE SubAddress, BYTE *Source, BYTE Num);
功能:
從啟動總線到發送地址,子地址,讀數據,結束總線的過程。
參數:
Slave--從器件地址。
SubAddress--子地址
Source--指向讀出的內容放入的存儲區的指針
Num--讀字節個數。
返回值:
如果返回1表示操作成功,否則操作有誤。
注意:
使用前必須已結束總線。
********************************************************************/
bit RecStr(BYTE Slave, BYTE SubAddress, BYTE *Source, BYTE Num)
{
BYTE i;
Start_I2C(); /* 啟動總線 */
SendByte(Slave); /* 發送器件地址 */
if(ack == 0) return(0);
SendByte(SubAddress); /* 發送器件子地址 */
if(ack == 0) return(0);
Start_I2C();
SendByte(Slave+1);
if(ack == 0) return(0);
for(i = 0; i < Num-1; i++)
{
*Source = RecByte(); /* 發送數據 */
Ack_I2C(0); /* 發送就答位 */
Source++;
}
* Source =RecByte();
Ack_I2C(1); /* 發送非應位 */
Stop_I2C(); /* 結束總線 */
return(1);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -