?? iic.c
字號:
//[IIC.c]IIC總線通信-------------------------------------------------------*
//外部函數: *
// (1)IICinit:IIC模塊初始化 *
// (2)IICread1:MCU從從機讀1個字節 *
// (3)IICwrite1:MCU向從機寫1個字節 *
// (4)IICreadN:MCU從從機讀N個字節 *
// (5)IICwriteN:MCU向從機寫N個字節 *
//內部函數: *
// (1) SendSignal:在IIC總線上發送起停信號 *
// (2) Wait:等待應答或一個字節數據的傳送完成 *
//硬件連接: *
// MCU的IIC接口與從機的IIC接口相連,DG128的IIC模塊的引腳SDA和SCL分別與 *
// PTC2和PTC3引腳復用,這兩個引腳應分別與從機的IIC模塊的SDA和SCL相連 *
//說明:本文件與具體的芯片型號有關 *
//-------------------------------------------------------------------------*
//頭文件
#include "IIC.h" //IIC通信頭文件
//IICinit:IIC模塊初始化----------------------------------------------------*
//功 能:對IIC模塊進行初始化,默認為允許IIC,IIC總線頻率:62.5KHz,禁止IIC中 *
// 斷,從機接收模式,不發送應答信號 *
//參 數:無 *
//返 回:無 *
//-------------------------------------------------------------------------*
void IICInit(void)
{
IBFD = 0x60;//總線頻率:20MHz,IIC總線頻率:62.5KHz,SDA保持時間:2.45us
IBAD = 0xF0; //D7-D0位是MCU作為從機時的地址,最低位不使用
//不發送應答信號
//接收模式
//從機模式
//禁止IIC中斷
//使能IIC模塊
IBCR = 0x88;
}
//SendSignal:在IIC總線上發送起停信號---------------------------------------*
//功 能:根據需要產生開始或停止信號 *
//參 數:Signal = 'S'(Start),產生開始信號;Signal = 'O'(Over),產生停止信號 *
//返 回:無 *
//-------------------------------------------------------------------------*
void SendSignal(INT8U Signal)
{
if (Signal == 'S')
IBCR |= 0x20; //主機模式選擇位MST由0變為1,可以產生開始信號
else if (Signal == 'O')
IBCR &= ~0x20; //主機模式選擇位MST由1變為0,可以產生停止信號
}
//Wait:等待應答或一個字節數據的傳送完成------------------------------------*
//功能:在時限內,循環檢測接收應答標志位,或傳送完成標志位,判斷MCU是否接收到應*
// 答信號或一個字節是否已在總線上傳送完畢 *
//參數:x = 'A'(Ack),等待應答;x = 'T'(Transmission),等待一個字節數據傳輸完成*
//返回:0:收到應答信號或一個字節傳送完畢;1:未收到應答信號或一個字節沒傳送完 *
//-------------------------------------------------------------------------*
INT8U Wait(INT8U x)
{
INT8U ErrTime, i;
ErrTime = 255; //定義查詢超時時限
for (i = 0;i < ErrTime;i++)
{
if (x == 'A') //等待應答信號
{
if ((IBSR & 0x01) == 0)
SCISend1('c');
return 0; //傳送完一個字節后,收到了從機的應答信號
}
else if (x == 'T') //等待傳送完成一個字節信號
{
if ((IBSR & 0x02) != 0)
{
IBSR |= 0x02; //清IICIF標志位
SCISend1('d');
return 0; //成功發送完一個字節
}
}
}
if (i >= ErrTime)
SCISend1('f');
return 1; //超時,沒有收到應答信號或發送完一個字節
}
//IICread1:從從機讀1個字節數據---------------------------------------------*
//功 能:從從機讀1個字節數據 *
//參 數: *
// (1) DeviceAddr:設備地址 *
// (2) AccessAddr:訪問地址 *
// (3) Data:帶回收到的一個字節數據 *
//返 回:為0,成功讀一個字節;為1,讀一個字節失敗 *
//內部調用:SendSignal,Wait *
//-------------------------------------------------------------------------*
INT8U IICread1(INT8U DeviceAddr, INT8U AccessAddr, INT8U *Data)
{
IBCR |= 0x10; //TX = 1,MCU設置為發送模式
SendSignal('S'); //發送開始信號
IBDR = DeviceAddr & 0xfe; //發送設備地址,并通知從機接收數據
if (Wait('T')) //等待一個字節數據傳送完成
return 1; //沒有傳送成功,讀一個字節失敗
if (Wait('A')) //等待從機應答信號
return 1; //沒有等到應答信號,讀一個字節失敗
IBDR = AccessAddr; //發送訪問地址
if (Wait('T')) //等待一個字節數據傳送完成
return 1; //沒有傳送成功,讀一個字節失敗
if (Wait('A')) //等待從機應答信號
return 1; //沒有等到應答信號,讀一個字節失敗
IBCR |= 0x04; //主機模式下,RSTA位置1,產生重復開始信號
IBDR = DeviceAddr | 0x01; //通知從機改為發送數據
if (Wait('T')) //等待一個字節數據傳送完成
return 1; //沒有傳送成功,讀一個字節失敗
if (Wait('A')) //等待從機應答信號
return 1; //沒有等到應答信號,讀一個字節失敗
IBCR &= 0xef; //TX = 0,MCU設置為接收模式
*Data = IBDR; //讀出IBDR,準備接收數據
if (Wait('T')) //等待從機應答信號
return 1; //沒有等到應答信號,讀一個字節失敗
SendSignal('O'); //發送停止信號
*Data = IBDR; //讀出接收到的一個數據
return 0; //正確接收到一個字節數據
}
//IICwrite1:向從機寫1個字節數據--------------------------------------------*
//功 能:向從機寫1個字節數據 *
//參 數: *
// (1) DeviceAddr:設備地址 *
// (2) AccessAddr:訪問地址 *
// (3) Data:要發給從機的1個字節數據 *
//返 回:為0,成功寫一個字節;為1,寫一個字節失敗 *
//內部調用 :Start, SendByte, WaitAck, Stop *
//-------------------------------------------------------------------------*
INT8U IICwrite1(INT8U DeviceAddr, INT8U AccessAddr, INT8U Data)
{
IBCR |= 0x10; //TX = 1,MCU設置為發送模式
SendSignal('S'); //發送開始信號
IBDR = DeviceAddr & 0xfe; //發送設備地址,并通知從機接收數據
if (Wait('T')) //等待一個字節數據傳送完成
return 1; //沒有傳送成功,寫一個字節失敗
if (Wait('A')) //等待從機應答信號
return 1; //沒有等到應答信號,寫一個字節失敗
IBDR = AccessAddr; //發送訪問地址
if (Wait('T')) //等待一個字節數據傳送完成
return 1; //沒有傳送成功,寫一個字節失敗
if (Wait('A')) //等待從機應答信號
return 1; //沒有等到應答信號,寫一個字節失敗
IBDR = Data; //寫數據
if (Wait('T')) //等待一個字節數據傳送完成
return 1; //沒有傳送成功,寫一個字節失敗
if (Wait('A')) //等待從機應答信號
return 1; //沒有等到應答信號,寫一個字節失敗
SendSignal('O'); //發送停止信號
return 0;
}
//IICreadN:從從機讀N個字節數據---------------------------------------------*
//功 能:從從機讀N個字節數據 *
//參 數: *
// (1) DeviceAddr:設備地址 *
// (2) AccessAddr:訪問地址 *
// (3) Data:讀出數據的緩沖區 *
// (4) N:從從機讀的字節個數 *
//返 回:為0,成功讀N個字節;為1,讀N個字節失敗 *
//內部調用:IICread1 *
//-------------------------------------------------------------------------*
INT8U IICreadN(INT8U DeviceAddr, INT8U AccessAddr, INT8U Data[], INT8U N)
{
INT8U i, j;
for (i = 0;i < N;i++)
{
for(j = 0;j < 15;j++); //最小延時(發送的每個字節之間要有時間間隔)
if (IICread1(DeviceAddr, AccessAddr + i, &Data[i]))
return 1; //其中一個字節沒有接收到,返回失敗標志:1
}
if (i >= N)
return 0; //成功接收N個數據,返回成功標志:0
}
//IICwriteN:向從機寫N個字節數據--------------------------------------------*
//功 能:向從機寫N個字節數據 *
//參 數: *
// (1) DeviceAddr:設備地址 *
// (2) AccessAddr:訪問地址 *
// (3) Data:要寫入的數據 *
// (4) N:寫入數據個數 *
//返 回:為0,成功寫N個字節;為1,寫N個字節失敗 *
//內部調用:IICwrite1 *
//-------------------------------------------------------------------------*
INT8U IICwriteN(INT8U DeviceAddr, INT8U AccessAddr, INT8U Data[], INT8U N)
{
INT8U i, j;
for (i = 0;i < N;i++)
{
for(j = 0;j < 15;j++); //最小延時(發送的每個字節之間要有時間間隔)
if (IICwrite1(DeviceAddr, AccessAddr + i, Data[i]))
return 1; //其中一個字節沒有發送出去,返回失敗標志:1
}
if (i >= N)
return 0; //成功發送N個數據,返回成功標志:0
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -