模塊名:I2C總線驅動 型號:I2C
功能描述:
此模塊包括發(fā)送數(shù)據(jù)及接收數(shù)據(jù),應答位發(fā)送,并提供了幾個直接面對器件的操作函數(shù),能很
方便的與用戶程序進行連接并擴展。
需要注意的是,函數(shù)是采用延時方法產生 SCL 脈沖,對高晶振頻率要做一定的修改?。?br/> 在寫E2PROM的時候一定要延時?。?!
說明:
1us機器周期,晶振頻率要小于12MHz
返回 1 則操作成功,返回 0 則操作失敗。
sla 為器件從地址,suba 為器件子地址。
*************************************************************************************/
#include "AT89X52.h"
#include
#define _Nop() _nop_() //定義空指令
sbit SDA = P1^3; //模擬I2C數(shù)據(jù)傳輸位
sbit SCL = P1^2; //模擬I2C時鐘控制位
bit bdata I2C_Ack; //應答標志位
/************************************ I2C_Start ************************************
函數(shù)名:void I2C_Start()
入口:
出口:
功能描述:啟動I2C總線,即發(fā)送I2C初始條件
調用函數(shù):
全局變量:
創(chuàng)建者:陳曦 日期:2005-6-15
修改者: 日期:
**********************************************************************************/
void I2C_Start()
{
SDA = 1; //發(fā)送起始條件的數(shù)據(jù)信號
_Nop();
SCL = 1;
_Nop(); //起始條件建立時間大于4.7us,延時
_Nop();
_Nop();
_Nop();
_Nop();
SDA = 0; //發(fā)送起始信號
_Nop(); //起始條件建立時間大于4us,延時
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 0; //鉗住I2C總線準備發(fā)送或接收數(shù)據(jù)
_Nop();
_Nop();
}
/************************************ I2C_Stop ************************************
函數(shù)名:void I2C_Stop()
入口:
出口:
功能描述:結束I2C總線,即發(fā)送I2C結束條件
調用函數(shù):
全局變量:
創(chuàng)建者:陳曦 日期:2005-6-15
修改者: 日期:
**********************************************************************************/
void I2C_Stop()
{
SDA = 0; //發(fā)送結束條件的數(shù)據(jù)信號
_Nop();
SCL = 1; //發(fā)送結束條件的時鐘信號
_Nop(); //結束條件建立時間大于4us,延時
_Nop();
_Nop();
_Nop();
_Nop();
SDA = 1; //發(fā)送I2C總線結束信號
_Nop();
_Nop();
_Nop();
_Nop();
}
/************************************ I2C_CheckAck ************************************
函數(shù)名:bit I2C_CheckAck(void)
入口:
出口:0(無應答),1(有應答)
功能描述:
檢驗I2C總線應答信號,有應答則返回1,否則返回0,超時值取255
調用函數(shù):void I2C_Stop()
全局變量:
創(chuàng)建者:陳曦 日期:2005-6-15
修改者: 日期:
**********************************************************************************/
bit I2C_CheckAck(void)
{
uchar errtime = 255; // 因故障接收方無 Ack,超時值為255
SDA = 1;
_Nop();
_Nop();
_Nop();
SCL = 1;
_Nop(); //時鐘電平周期大于 4 us
_Nop();
_Nop();
_Nop();
_Nop();
while(SDA)
{
errtime--;
if(errtime==0)
{
I2C_Stop();
return(0);
}
}
SCL = 0;
_Nop();
return(1);
}
/************************************ I2C_SendB ************************************
函數(shù)名:void I2C_SendB(uchar c)
入口:uchar 型數(shù)據(jù)
出口:
功能描述:
字節(jié)數(shù)據(jù)傳送函數(shù),將數(shù)據(jù) c 發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應答,并對
此狀態(tài)位進行操作
調用函數(shù):bit I2C_CheckAck()
全局變量:I2C_Ack
創(chuàng)建者:陳曦 日期:2005-6-15
修改者: 日期:
**********************************************************************************/
void I2C_SendB(uchar c)
{
uchar BitCnt;
for (BitCnt=0; BitCnt<8; BitCnt++) //要傳送的數(shù)據(jù)長度為8位
{
if((c<
SDA = 1;
}
else
{
SDA = 0;
}
_Nop();
_Nop();
SCL = 1; //置時鐘線為高通知被控器開始接收數(shù)據(jù)位
_Nop(); //保證時鐘高電平周期大于 4us
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 0;
}
_Nop();
_Nop();
I2C_Ack = I2C_CheckAck(); //檢驗應答信號
_Nop();
_Nop();
}
/************************************ I2C_RcvB ************************************
函數(shù)名:uchar I2C_RcvB()
入口:
出口:uchar型數(shù)據(jù)
功能描述:
接收從器件傳來的數(shù)據(jù),并判斷總線錯誤(不發(fā)應答信號),收完后需要調用應答函數(shù)。
調用函數(shù):
全局變量:
創(chuàng)建者:陳曦 日期:2005-6-15
修改者: 日期:
**********************************************************************************/
uchar I2C_RcvB()
{
uchar retc;
uchar BitCnt; //位
retc = 0;
SDA = 1; //置數(shù)據(jù)總線為輸入方式
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL = 0; //置時鐘線為低準備接收數(shù)據(jù)位
_Nop(); //時鐘低電平周期大于4.7us
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 1; //置時鐘線為高使數(shù)據(jù)有效
_Nop();
_Nop();
retc = retc<<1;
if(SDA==1)
{
retc = retc + 1; //讀數(shù)據(jù)位,接收的數(shù)據(jù)放入retc中
}
_Nop();
_Nop();
}
SCL = 0;
_Nop();
_Nop();
return(retc);
}
/************************************ I2C_Ackn ************************************
函數(shù)名:void I2C_Ackn(bit a)
入口:0或1
出口:
功能描述:主控制器進行應答信號(可以是應答或非應答信號)
調用函數(shù):
全局變量:
創(chuàng)建者:陳曦 日期:2005-6-15
修改者: 日期:
**********************************************************************************/
void I2C_Ackn(bit a)
{
if(a==0) //在此發(fā)送應答或非應答信號
{
SDA = 0;
}
else
{
SDA = 1;
}
_Nop();
_Nop();
_Nop();
SCL = 1;
_Nop(); //時鐘電平周期大于 4 us
_Nop();
_Nop();
_Nop();
_Nop();
SCL = 0; //清時鐘線鉗住I2C總線以便繼續(xù)接收
_Nop();
_Nop();
}
/******************************** I2C_ISendB ************************************
函數(shù)名:bit I2C_ISendB(uchar sla, uchar suba, uchar c)
入口:從器件地址 sla,子地址 suba, 發(fā)送字節(jié) c
出口:0(操作有誤),1(操作成功)
功能描述:從啟動總線到發(fā)送地址、數(shù)據(jù),結束總線的全過程,
如果返回1,表示操作成功,否則操作有誤。
調用函數(shù):I2C_Start(),I2C_SendB(uchar c),I2C_Stop()
全局變量:I2C_Ack
創(chuàng)建者:陳曦 日期:2005-6-15
修改者: 日期:
**********************************************************************************/
bit I2C_ISendB(uchar sla, uchar suba, uchar c)
{
I2C_Start(); //啟動總線
I2C_SendB(sla); //發(fā)送器件地址
if(!I2C_Ack)
{
return(0);
}
I2C_SendB(suba); //發(fā)送器件子地址
if(!I2C_Ack)
{
return(0);
}
I2C_SendB(c); //發(fā)送數(shù)據(jù)
if(!I2C_Ack)
{
return(0);
}
I2C_Stop(); //結束總線
return(1);
}
/********************************** I2C_IRcvB ************************************
函數(shù)名:bit I2C_IRcvB(uchar sla, uchar suba, uchar *c)
入口:從器件地址 sla, 子地址 suba, 收到的數(shù)據(jù)在 c
出口:1(操作成功),0(操作有誤)
功能描述:從啟動總線到發(fā)送地址、讀數(shù)據(jù),結束總線的全過程。
調用函數(shù): I2CS_tart(),
I2C_SendB(uchar c),
I2C_RcvB(),
I2C_Ackn(bit a),
I2C_Stop()
全局變量:I2C_Ack
創(chuàng)建者:陳曦 日期:2005-5-15
修改者: 日期:
**********************************************************************************/
bit I2C_IRcvB(uchar sla, uchar suba, uchar *c)
{
I2C_Start(); //啟動總線
I2C_SendB(sla);
if(!I2C_Ack)
{
return(0);
}
I2C_SendB(suba); //發(fā)送器件子地址
if(!I2C_Ack)
{
return(0);
}
I2C_Start(); //重復起始條件
I2C_SendB(sla+1); //發(fā)送讀操作的地址
if(!I2C_Ack)
{
return(0);
}
*c = I2C_RcvB(); //讀取數(shù)據(jù)
I2C_Ackn(1); //發(fā)送非應答位
I2C_Stop(); //結束總線
return(1);
}
上海意泓電子科技有限責任公司 版權所有 未經授權禁止復制或鏡像
CopyRight 2020-2025 www.jlodreman.com All rights reserved 滬ICP備2021005866號