?? i2c.c
字號:
//===================================================================
// 文件名稱: i2c.c
//===================================================================
#define I2C_SCL PIN_C0
#define I2C_SDA PIN_C1
//------------------- 私有宏定義 開始-------------------------
#define I2CWAIT8 delay_us(8)
#define I2CWAIT4 delay_us(5)
//#define EMAX_POLL 10 // Maximum nunber of polls
#define EMAX_POLL 0x96 // Maximum nunber of polls
//------------------- 私有宏定義 結束-------------------------
//===================================================================
//= 函數原型: void i2c_start()
//= 參 數: 無
//= 返 回 值: 無
//= 功 能: 提供I2C總線工作時序中的起始位
//= 函數性質: 私有函數
//= SDA ----_____
//= I2C_SCL ------____
//===================================================================
void i2c_start()
{
output_high(I2C_SDA);
I2CWAIT8;
output_high(I2C_SCL);
I2CWAIT8;
output_low(I2C_SDA);
I2CWAIT4;
output_low(I2C_SCL);
I2CWAIT4;
}
//===================================================================
//= 函數原型: void i2c_stop()
//= 參 數: 無
//= 返 回 值: 發送停止位后DSA線的狀態 是'低'則返回
//= 功 能: 提供I2C總線工作時序中的停止位
//= 函數性質: 私有函數
//= SDA ______----
//= I2C_SCL ___-------
//===================================================================
void i2c_stop()
{
// int8 i;
output_low(I2C_SDA);
I2CWAIT4;
output_high(I2C_SCL);
I2CWAIT8;
output_high(I2C_SDA);
I2CWAIT4;
// i = SDA; // Put port pin into HiZ
}
//===================================================================
//= 函數原型: bit i2c_clock()
//= 參 數: 無
//= 返 回 值: 在時鐘電平為高期間SDA信號線上的狀態
//= 功 能: 提供I2C總線的時鐘信號,并返回在時鐘電平為高期間SDA
//= 信號線上的狀態.本函數可用于數據發送或數據接收
//= 函數性質: 私有函數
//===================================================================
int1 i2c_clock()
{
int1 sample;
output_high(I2C_SCL);
I2CWAIT8;
sample = input(I2C_SDA);
output_low(I2C_SCL);
return(sample);
}
//===================================================================
//= 函數原型: bit i2c_send_8bit(int8 I_data)
//= 參 數: I_data 寫入 EEPROM 8_bit
//= 返 回 值: 如果收到應答信號返回TRUE 否則返回FALSE
//= 功 能: 向I2C總線發送8位數據,并請求一個應答信號ACK
//= 函數性質: 私有函數
//===================================================================
int1 i2c_send_8bit(int8 I_data)
{
int8 i;
int1 test_bit;
set_tris_c(0x00); // I2C_SDA output
I2CWAIT4;
for (i=0;i<8;i++)
{
output_bit(I2C_SDA, bit_test(I_data,7));
I_data <<= 1;
I2CWAIT4;
i2c_clock();
I2CWAIT4;
}
// output_high(I2C_SDA); // 請求應答信號ACK
set_tris_c(0x02); // I2C_SDA input
test_bit=i2c_clock();
set_tris_c(0x00); // I2C_SDA input
return(~test_bit); // 如果收到應答信號返回1 否則返回0
}
//===================================================================
//= 函數原型: int8 i2c_receive_8bit(bit ack)
//= 參 數: 應答信號 0/1(僅在最后一個字節時ACK為1)
//= 返 回 值: I2C總線上收到的一個字節
//= 功 能: 從I2C總線上接收8位數據信號,并將收到的8位數據作為一個字節返回
//= 函數性質: 私有函數
//===================================================================
int8 i2c_receive_8bit(int1 ack)
{
int8 I_data = 0;
int8 i;
/*
SDA = 1;
for (i=0;i<8;i++)
{
I2CWAIT8;
I_data <<= 1; // '高位在前讀數據'經典'
if (i2c_clock())
I_data++;
}
I2CWAIT4;
SDA = ack; // 發送應答信號
i2c_clock();
return(I_data);
*/
set_tris_c(0x02); // I2C_SDA input
delay_cycles(1);
for(i=0;i<8;i++)
{
I2CWAIT8;
I_data <<= 1; // '高位在前讀數據'經典'
if (i2c_clock())
I_data++;
}
I2CWAIT4;
set_tris_c(0x00); // I2C_SDA output
delay_cycles(1);
output_bit(I2C_SDA,ack); // 發送應答信號
i2c_clock();
return(I_data);
}
//===================================================================
//= 函數原型: bit i2c_pkt_write(u_int addr,int8 *s,int8 size)
//= 參 數: ipw_ch:器件地址 ipw_addr:單元地址 *s寫數據指針 size:寫入數據的個數
//= 返 回 值: 寫數據成功返回'TRUE',否則返回'FALSE'
//= 功 能: 從啟動總線到發送地址,數據,結束總線的全過程
//= 函數性質: 公有函數
//===================================================================
int1 i2c_pkt_write(int8 ipw_ch,int8 ipw_addr,int8 *s,int8 size)
{
int8 i;
// int8 *buf_pt = s;
// int8 *buf_pt;
// buf_pt = s;
if (size == 0) return FALSE;
for (i=EMAX_POLL;;)
{
i2c_start();
if (i2c_send_8bit(ipw_ch)==TRUE) // 送器件地址,同時檢查是否連接
break; // receive ACK => write finished
i2c_stop();
if (--i == 0) // Try it 1msec
return FALSE; // 等待1msec 還沒有寫完則返回出錯
}
i2c_send_8bit(ipw_addr);
do {
i2c_send_8bit(*s);
s++;
} while (--size);
i2c_stop();
}
//===================================================================
//= 函數原型: bit i2c_pkt_read(int8 ipw_ch,int8 ipw_addr,int8 *s,int8 size)
//= 參 數: addr:EEPROM地址 *s:讀數據指針 size:讀數據的個數
//= 返 回 值: 讀數據成功返回'TRUE',否則返回'FALSE'
//= 功 能: 從啟動總線到發送地址,讀數據,結束總線的全過程
//= 函數性質: 公有函數
//===================================================================
int1 i2c_pkt_read(int8 ipw_ch,int8 ipw_addr,int8 *s,int8 size)
{
// int8 *buf_pt = s;
// int8 *buf_pt;
int1 ack;
// buf_pt= s;
if (size == 0) return FALSE;
i2c_start();
if (i2c_send_8bit(ipw_ch)==FALSE) { // 送器件地址,同時檢查是否連接
i2c_stop();
return FALSE;
}
i2c_send_8bit(ipw_addr);
i2c_stop();
i2c_start();
i2c_send_8bit(ipw_ch+1); // 送讀命令
for (;;)
{
ack = --size; // last byte or last in page
*s = i2c_receive_8bit(!ack); // NACK on last byte
s++;
if (!ack) break; // 正常情況下ACK應該是1
}
i2c_stop();
return TRUE;
}
//======================= 函數原型定義完畢 ==========================
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -