?? i2c.c
字號:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
//常變量定義區,端口位定義
sbit SDA=P3^4;
sbit SCL=P3^5;
//狀態標志
bit ack;
/***************************************************************
啟動總線函數
函數原型:void Start_I2C();
功能:啟動I2C總線,即發送I2C起始條件
***************************************************************/
void Start_I2C()
{
SDA=1;
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
/***************************************************************
結束總線函數
函數原型:void Stop_I2c();
功能:結束I2C總線,即發送I2C結束條件
****************************************************************/
void Stop_I2C()
{
SDA=0;
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SDA=1;
_nop_();
_nop_();
_nop_();
_nop_();
}
/****************************************************************
字節數據傳送函數
函數原型:void SendByte(uchar c)
功能:將數據c發送出去,可以時地址,也可以時數據,發完后等待應答,并對
此狀態位進行操作(不應答或非應答都使ack=0,表示應答失敗)。發送數據正常,ack=1;ack=0
表示被控器無應答或損壞
*******************************************************************/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
if((c<<BitCnt)&0x80)
SDA=1;
else SDA=0;
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
}
_nop_();
_nop_();
SDA=1; //8位發送完后釋放數據線,準備接收應答位
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
if(SDA==1) //應答時接收器必須把SDA線拉低
ack=0;
else ack=1; //判斷是否接收到應答信號
SCL=0;
_nop_();
_nop_();
}
/*************************************************************************
字節數據接受函數
函數原型:uchar RcvByte();
功能:用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號)
*************************************************************************/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
for(BitCnt=0;BitCnt<8;BitCnt++)
{
SDA=1; //置數據線為輸入方式
SCL=0; //置時鐘線低,準備接受數據位
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=1; //置時鐘線為高,使數據線上數據有效
_nop_();
_nop_();
retc=retc<<1;
if(SDA==1)
retc=retc+1;
_nop_();
_nop_();
}
SCL=0;
_nop_();
_nop_();
return(retc);
}
/***************************************************************
應答子函數
函數原型:void Ack_I2c(bit a);
功能:主控制器進行應答信號(可以是應答或非應答信號)
***************************************************************/
void Ack_I2C(bit a)
{
if(a)
SDA=1;
else
SDA=0;
_nop_();
_nop_();
_nop_();
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
_nop_();
_nop_();
}
/****************************************************************
向無子地址器件發送字節數據函數
函數原型:bit ISendByte(uchar sla,uchar c);
功能:從啟動總線到發送地址,數據,直至結束總線的全過程;從器件地址sla,c為發送內容。
如果返回1,表示操作成功,否則失敗
*********************************************************************/
bit ISendByte(uchar sla,uchar c)
{
Start_I2C();
SendByte(sla);
if(ack==0)
return(0);
SendByte(c);
if(ack==0)
return(0);
Stop_I2C();
return(1);
}
/***************************************************************
向有子地址器件發送多字節數據函數
函數原型:bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no);
功能:從啟動總線到發送地址,子地址,數據直到結束總線的全過程;從器件地址sla,子地址suba,發送的內容是s指向的內容,
發送no個字節。如果返回是1,表示成功,否則失敗。
****************************************************************/
bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2C();
SendByte(sla);
if(ack==0)
return(0);
SendByte(suba);
if(ack==0)
return(0);
for(i=0;i<no;i++)
{
SendByte(*s);
if(ack==0)
return(0);
s++;
}
Stop_I2C();
return(1);
}
/********************************************************************
向無子地址器件讀取字節數據函數
函數原型:bit IRcvByte(uchar sla,uchar *c);
功能:從啟動總線到發送地址,直至結束總線的全過程;從器件地址sla,
讀取數據返回值c.如果返回是1表示成功,否則失敗
**************************************************************************/
bit IRcvByte(uchar sla,uchar *c)
{ //立即地址讀取
Start_I2C();
SendByte(sla+1);
if(ack==0)
return(0);
*c=RcvByte();
Ack_I2C(1);
Stop_I2C();
return(1);
}
/******************************************************************************
向有子地址器件讀取多字節數據函數
函數原型:bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no);
功能:從啟動總線到發送地址,子地址,數據直到結束總線的全過程;從器件地址sla,子地址suba,到讀出內容放到s指向的存儲區,
讀no個字節。如果返回是1,表示成功,否則失敗。
****************************************************************/
bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
{
uchar i;
Start_I2C();
SendByte(sla); //偽寫操作
if(ack==0)
return(0);
SendByte(suba);
if(ack==0)
return(0);
Start_I2C();
SendByte(sla+1); //讀操作命令
if(ack==0)
return(0);
for(i=0;i<no-1;i++)
{
*s=RcvByte();
Ack_I2C(0); //發送應答信號
s++;
}
*s=RcvByte();
Ack_I2C(1); //發送非應答信號并停止讀操作
Stop_I2C();
return(1);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -