切換
舊版
前往
大廳
主題

I2C Bus implement code(8051 Keil C)

小超一世 | 2007-08-14 16:20:14 | 巴幣 0 | 人氣 9186

I2CBus是一般微處理器常用的溝通介面,因為使用的I/O腳PIN很少,只需要SDA,SCL這兩隻腳PIN,所以廣為控制器使用,以下由我使用Keil C寫了一些I2C的Driver,有心人士可以研究參考。
#include <AT89X51.H>


/*====================================
AT89C51 I2CBus Control by Henry Chou
Pins function define
=====================================*/
sbit SB_SDA = P1 ^ 0;
sbit SB_SCL = P1 ^ 1;
sbit RST_35010A = P1 ^ 2;

sbit SPI_Q = P1 ^ 4;
sbit SPI_D = P1 ^ 5;
sbit SPI_C = P1 ^ 6;
sbit SPI_S = P1 ^ 7;

sbit PLAY_KEY = P2 ^ 0;
sbit STOP_KEY = P2 ^ 1;

/*====================================
Serial Bus Control Function
=====================================*/
void SBUS_start(void);
void SBUS_stop(void);
bool SBUS_shift_out_byte(unsigned char);
bool SBUS_select_index(unsigned char, unsigned char);
int SBUS_read_data(unsigned char, unsigned char);
bool SBUS_write_data(unsigned char, unsigned char, unsigned char);

/********************************************/
/* 2-wire Serial Bus basic function */
/********************************************/
/* P1.0 SDA */
/* P1.1 SCL */
/* */
/* Note : */
/* The serial bus only 2 logical */
/* 0 : output low */
/* Z : input mode and pull-up */
/* */
/* So, if SDA or SCL is assigned '1', */
/* it is input mode and using pull-up */
/* */
/* [S] : START */
/* [P] : STOP */
/* [R] : READ (1) */
/* [W] : WRITE (0) */
/* [ADDR] : device address (7-bit) */
/* [DATA] : 8-bit data */
/* [INDEX]: 8-bit data */
/* [A] : ACK (acknowledge) */
/* [NA] : NACK (none-acknowledge) */
/* */
/********************************************/

void SBUS_start(void)
{
SB_SDA = 0;
SB_SCL = 0;
}

void SBUS_stop(void)
{
SB_SDA = 0;
SB_SCL = 1;
while ( SB_SCL == 0 ); /* wait device(35010A) release SCL */
SB_SDA = 1;
}


bool SBUS_shift_out_byte(unsigned char data_byte)
{
unsigned char i;

for ( i = 0 ; i < 8 ; i++ )
{
if ( data_byte & 0x80 )
{
SB_SDA = 1;
}
else
{
SB_SDA = 0;
}
SB_SCL = 1; /* release SCL , SCL pulse */
while ( SB_SCL == 0 ); /* wait device release SCL */
SB_SCL = 0; /* SCL pulse complete */
data_byte = data_byte << 1; /* shift next bit */
}

/* ACK */
SB_SDA = 1;
SB_SCL = 1;
while ( SB_SCL == 0 ); /* wait device release SCL */
if ( SB_SDA == 1 )
{
SB_SCL = 0;
SBUS_stop();
return (false); /* non-acknowledge */
}
else
{
SB_SCL = 0;
return(true);
}
}


bool SBUS_select_index(unsigned char device_addr, unsigned char index_reg)
{
/* START */
SBUS_start();

/* ADDR + R/W */
if ( !SBUS_shift_out_byte( device_addr << 1 ) ) /* WRITE */
{
return (false);
}

/* INDEX */
if ( !SBUS_shift_out_byte( index_reg ) )
{
return (false);
}

/* STOP */

SBUS_stop();

return (true);
}


int SBUS_read_data(unsigned char device_addr, unsigned char index_reg)
{
unsigned char i;
unsigned char read_data;

if ( !SBUS_select_index( device_addr , index_reg) )
{
return (-1);
}

/* START */
SBUS_start();

/* ADDR + R/W */
if ( !SBUS_shift_out_byte( (device_addr << 1) | 0x01 ) ) /* READ */
{
return (-1);
}

/* SHIFT IN DATA */

for ( i = 0 ; i < 8 ; i++ )
{
read_data = read_data << 1;

SB_SCL = 1; /* shift in SCL pulse */
while ( SB_SCL == 0 ); /* wait device release SCL */
if ( SB_SDA == 1 ) /* SCL high, get SDA data bit */
{
read_data = read_data | 0x01;
}
SB_SCL = 0; /* SCL pulse complete */
}


SB_SDA = 1; /* response NACK to 35010A */
SB_SCL = 1; /* ACK/NACK SCL pulse */
while ( SB_SCL == 0 ); /* wait device release SCL */
SB_SCL = 0; /* SCL pulse complete */

/* STOP */

SBUS_stop();

return ((int)read_data);
}


bool SBUS_write_data(unsigned char device_addr, unsigned char index_reg, unsigned char data_reg)
{
/* START */
SBUS_start();

/* ADDR + R/W */
if ( !SBUS_shift_out_byte( device_addr << 1 ) ) /* WRITE */
{
return (false);
}

/* INDEX */
if ( !SBUS_shift_out_byte( index_reg ) )
{
return (false);
}

/* DATA */
if ( !SBUS_shift_out_byte( data_reg ) )
{
return (false);
}

/* STOP */
SBUS_stop();

return (true);
}



創作回應

小超一世
喔~小波過獎了,今天才加你入好友,之前你有邀請連署,忘了加你抱歉,blog的文章我打算多元化,所以有些東西會看起來很苦澀,像是給自己學習的札記,但又不同於我在酸甜開的日記;有些會比較生活人生走向的,打算平均分佈,不然都PO程式跟原理,這裡遲早變成我的自言自語。
2007-08-15 14:27:08
花生俊
看不懂.....不過好像很利害= =
2007-08-16 00:09:21
水舞梨
標題是英文ABC...好棒!

(點進來)

我沒一句看得懂,嗚嗚、小超人太厲害了!
2007-08-16 01:26:52
小超一世
喔....好像一次進太多階了,這篇是給電子電機系裡面,有修過微處理機,還有C語言程式的人看的,當然許多在電子業工作的工程師高手應該也會蠻有興趣的。
2007-08-16 10:33:04
曉華
大師 請問I2C的原理是什麼
2009-06-10 20:22:45
小超一世
喔...這篇已經放了很久.居然還有人回文.
I2C BUS是一種資料介面傳輸,就我所研究所知,
是飛利浦的專利規格,I2C的精神就是用兩條傳輸線來輸入及輸出資料,
常有的應用就是資料傳遞,像是一些smart battery電路、筆電裡的充電電路、EEPROM的控制,用的都是I2C BUS控制。
2009-06-10 20:39:30

更多創作