|
发表于 2011-10-1 21:26:18
|
显示全部楼层
some quick comments:
"//读一字节 ack: 1时应答,0时不应答
unsigned char I2C_read(unsigned char ack) "
define two constants:
#define I2C_ACK 0 //send ack
#define I2C_NOACK 1 //send noack
so when you call I2C_read(), use I2C_read(I2C_ACK); or I2C_read(I2C_NOACK); to make the code easier to read and more portable.
" SDA_Hight; "
use SDA_High, not SDA_Hight - that "t" makes zero sense and sounds silly.
" I2C_Delay; //这一句原来在for循环的开始,挪到此处 "
I would implement that delay into SDA_HIGH or SDA_LOW, just to make it more readable.
" for(i=0;i<8;i++) "
I would use mask
" if(SDA_Input)
ret++; "
this will yield uneven timing: slower when SDA_Input = 1 and faster when SDA_Input = 0. try this
if(SDA_Input) ret+=1;
else ret+=0;
" if(ack) //非应答
SDA_Low;
else //应答
SDA_Hight; "
use
if(I2C_ACK==ack) //send ack
SDA_Low;
else
SDA_High;
for stylistic purposes, I would use I2C_LOW(I2C_SCL / I2C_SDA) or I2C_HIGH(I2C_SCL / I2C_SDA) instead. they are far more consistent than what you have here.
this is what I do:
//-----------------------i2c read------------------------------
//to be consistent with i2c protocol, use negative logic
//ack = 0 -> send ack
//ack = 1 -> no ack
unsigned char i2c_read(unsigned char ack) {
unsigned char i, data_t=0;
I2C_HIZ(I2C_SDA); //let sda float
i=0x80;
do {
I2C_LOW(I2C_SCL); //clear i2c_scl
data_t <<=1; //left shift the data
i = i >> 1;
I2C_HIGH(I2C_SCL); //let scl float to high
if (I2C_PORT_IN & I2C_SDA) data_t |= 0x01; //set the last bit high
else data_t |= 0x00;
} while (i);
I2C_LOW(I2C_SCL); //pull scl low
if (ack==I2C_ACK)
{I2C_LOW(I2C_SDA);} //send ack
else
{I2C_HIGH(I2C_SDA);} //send no-ack
I2C_HIGH(I2C_SCL); //send ack/no-ack
I2C_LOW(I2C_SCL);
return data_t;
} |
|