標(biāo)題:
51單片機(jī)與24CXX通信的C程序
[打印本頁]
作者:
daming
時間:
2014-12-30 00:47
標(biāo)題:
51單片機(jī)與24CXX通信的C程序
/******************************************************************************************
端口定義
****************************************************************************************/
sbit SCL=P2^1; //將串行時鐘總線SCL位定義在為P3.4引腳
sbit SDA=P2^0; //將串行數(shù)據(jù)總線SDA位定義在為P3.5引腳
#define OP_READ 0xa1 // 器件地址以及讀取操作,0xa1即為1010 0001B
#define OP_WRITE 0xa0 // 器件地址以及寫入操作,0xa1即為1010 0000B
/******************************************************************************************
* 函數(shù)名稱 :Start
* 功能描述 : 啟動I2C總線
* 參數(shù) : 無
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void Start()
{
SDA = 1; //SDA初始化為高電平“1”
SCL = 1; //開始數(shù)據(jù)傳送時,要求SCL為高電平“1”
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
SDA = 0; //SDA的下降沿被認(rèn)為是開始信號
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
SCL = 0; //SCL為低電平時,SDA上數(shù)據(jù)才允許變化(即允許以后的數(shù)據(jù)傳遞)
}
/******************************************************************************************
* 函數(shù)名稱 :Stop
* 功能描述 : 結(jié)束I2C總線
* 參數(shù) : 無
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void Stop()// 停止位
{
SDA = 0; //SDA初始化為低電平“0” _n
SCL = 1; //結(jié)束數(shù)據(jù)傳送時,要求SCL為高電平“1”
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
SDA = 1; //SDA的上升沿被認(rèn)為是結(jié)束信號
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
SDA=0;
SCL=0;
}
/******************************************************************************************
* 函數(shù)名稱 :TeskAsk
* 功能描述 : 檢測應(yīng)答位
* 參數(shù) : 無
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void TestAsk()
{
bit ack_bit; //儲存應(yīng)答位
SDA = 1; // 發(fā)送設(shè)備(主機(jī))應(yīng)在時鐘脈沖的高電平期間(SCL=1)釋放SDA線,
//以讓SDA線轉(zhuǎn)由接收設(shè)備(AT24Cxx)控制
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
SCL = 1; //根據(jù)上述規(guī)定,SCL應(yīng)為高電平
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
ack_bit = SDA; //接受設(shè)備(AT24Cxx)向SDA送低電平,表示已經(jīng)接收到一個字節(jié)
//若送高電平,表示沒有接收到,傳送異常 結(jié)束發(fā)送
SCL = 0; //SCL為低電平時,SDA上數(shù)據(jù)才允許變化(即允許以后的數(shù)據(jù)傳遞)
while(ack_bit!=0);
}
/******************************************************************************************
* 函數(shù)名稱 :SendAsk
* 功能描述 :發(fā)送應(yīng)答位
* 參數(shù) : 無
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void SendAsk()
{
SCL=0;
_nop_();
_nop_();
SDA=0; //將SDA拉低并持續(xù)4.5us以上
SCL=1;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SCL=0;
SDA=1;
}
/******************************************************************************************
* 函數(shù)名稱 :ReadData
* 功能描述 :從24CXX里讀一個字節(jié)
* 參數(shù) : 無
* 返回值 : x
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
unsigned char ReadData()
// 從AT24Cxx移入數(shù)據(jù)到MCU
{
unsigned char i;
unsigned char x; //儲存從AT24Cxx中讀出的數(shù)據(jù)
for(i = 0; i < 8; i++)
{
SCL = 1; //SCL置為高電平
x<<=1; //將x中的各二進(jìn)位向左移一位
x|=(unsigned char)SDA; //將SDA上的數(shù)據(jù)通過按位“或“運(yùn)算存入x中
SCL = 0; //在SCL的下降沿讀出數(shù)據(jù)
}
return(x); //將讀取的數(shù)據(jù)返回
}
/******************************************************************************************
* 函數(shù)名稱 :WriteCurrent
* 功能描述 :向AT24Cxx的當(dāng)前地址寫入數(shù)據(jù)
* 參數(shù) : y (儲存待寫入的數(shù)據(jù))
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
//在調(diào)用此數(shù)據(jù)寫入函數(shù)前需首先調(diào)用開始函數(shù)start(),所以SCL=0
void WriteCurrent(unsigned char y)
{
unsigned char i;
for(i = 0; i < 8; i++) // 循環(huán)移入8個位
{
SDA = (bit)(y&0x80); //通過按位“與”運(yùn)算將最高位數(shù)據(jù)送到S
//因?yàn)閭魉蜁r高位在前,低位在后
_nop_(); //等待一個機(jī)器周期
SCL = 1; //在SCL的上升沿將數(shù)據(jù)寫入AT24Cxx
_nop_(); //等待一個機(jī)器周期
_nop_(); //等待一個機(jī)器周期
SCL = 0; //將SCL重新置為低電平,以在SCL線形成傳送數(shù)據(jù)所需的8個脈沖
y <<= 1; //將y中的各二進(jìn)位向左移一位
}
}
/******************************************************************************************
* 函數(shù)名稱 :WriteSet
* 功能描述 :向AT24Cxx中的指定地址寫入數(shù)據(jù)
* 參數(shù) :add (儲存指定的地址);dat(儲存待寫入的數(shù)據(jù))
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void WriteSet(unsigned char add, unsigned char dat)
// 在指定地址addr處寫入數(shù)據(jù)WriteCurrent
{
Start(); //開始數(shù)據(jù)傳遞
WriteCurrent(OP_WRITE); //選擇要操作的AT24Cxx芯片,并告知要對其寫入數(shù)據(jù)
TestAsk();
WriteCurrent(add); //寫入指定地址
TestAsk();
WriteCurrent(dat); //向當(dāng)前地址(上面指定的地址)寫入數(shù)據(jù)
TestAsk();
Stop(); //停止數(shù)據(jù)傳遞
delay(4); //1個字節(jié)的寫入周期為1ms, 最好延時1ms以上
}
/******************************************************************************************
* 函數(shù)名稱 :ReadCurrent
* 功能描述 :從AT24Cxx中的當(dāng)前地址讀取數(shù)據(jù)
* 參數(shù) : 無
* 返回值 : x (儲存讀出的數(shù)據(jù))
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
unsigned char ReadCurrent()
{
unsigned char x;
Start(); //開始數(shù)據(jù)傳遞
WriteCurrent(OP_READ); //選擇要操作的AT24Cxx芯片,并告知要讀其數(shù)據(jù)
TestAsk();
x=ReadData(); //將讀取的數(shù)據(jù)存入x
Stop(); //停止數(shù)據(jù)傳遞
return x; //返回讀取的數(shù)據(jù)
}
/******************************************************************************************
* 函數(shù)名稱 :ReadSet
* 功能描述 :從AT24Cxx中的指定地址讀取數(shù)據(jù)
* 參數(shù) : set_addr
* 返回值 : x
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
unsigned char ReadSet(unsigned char set_addr)
// 在指定地址讀取
{
Start(); //開始數(shù)據(jù)傳遞
WriteCurrent(OP_WRITE); //選擇要操作的AT24Cxx芯片,并告知要對其寫入數(shù)據(jù)
TestAsk();
WriteCurrent(set_addr); //寫入指定地址
TestAsk();
return(ReadCurrent()); //從指定地址讀出數(shù)據(jù)并返回
}
/******************************************************************************************
* 函數(shù)名稱 :WritePage
* 功能描述 :從AT24Cxx中的指定頁地址寫8字節(jié)數(shù)據(jù)
* 參數(shù) : address,*s(要寫進(jìn)去的數(shù)組首地址)
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void WritePage(unsigned char address,unsigned char *s) //按頁寫
{
unsigned char i;
Start();
WriteCurrent(OP_WRITE); //發(fā)送控制寫字節(jié)
TestAsk();
WriteCurrent(address); //存儲器地址;每次讀完之后指針自動加1
TestAsk();
for(i=0;i<8;i++) //直接連續(xù)寫8次,每頁含有16個字節(jié)
{
WriteCurrent(*s);
TestAsk();
s++;
}
Stop();
delay(4); //1個字節(jié)的寫入周期為1ms, 最好延時1ms以上
}
/******************************************************************************************
* 函數(shù)名稱 :ReadPage
* 功能描述 :從AT24Cxx中的指定頁地址讀取8字節(jié)數(shù)據(jù)
* 參數(shù) : address,tmp[](存放讀出來的數(shù)據(jù))
* 返回值 : 無
* 創(chuàng)建日期 :2010-11-25
* 作者 :zzj
* 全局變量 :
* 全局靜態(tài)變量:
* 局部靜態(tài)變量:
*----------------------------------------修改歷史------------------------------------------
* 當(dāng)前版本 : 修改人: 修改日期:
* 修改說明 :
******************************************************************************************/
void ReadPage(unsigned char address,unsigned char tmp[]) //按頁讀取、可以連續(xù)讀,不需要按頁讀
{
unsigned char i;
Start();
WriteCurrent(OP_WRITE); //發(fā)送控制寫字節(jié)
TestAsk();
WriteCurrent(address); //存儲器地址;每次讀完之后指針自動加1
TestAsk();
Start();
WriteCurrent(OP_READ); //選擇要操作的AT24Cxx芯片,并告知要讀其數(shù)據(jù)
TestAsk();
tmp[0]=ReadData();
for(i=1;i<8;i++)
{
SendAsk();
tmp[i]=ReadData();
} /**/
Stop();
}
復(fù)制代碼
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1