使用430F5418,通过IO模拟IIC来驱动SHT20温湿度传感器。一直返回不了数据。各位有用过模拟IIC的吗?
#define SHT20ADDR 0x80
#define SHT20_ACK 0
#define SHT20_NACK 1
#define IIC_SDA_OUT P3DIR |= BIT7 //输出模式
#define IIC_SDA_IN P3DIR &= ~BIT7 //输入模式
#define IIC_SCL_OUT P5DIR |= BIT4
#define IIC_SCL_IN P5DIR &= ~BIT4
#define IIC_SDA_HIGH P3OUT |= BIT7
#define IIC_SDA_LOW P3OUT &= ~BIT7
#define IIC_SCL_HIGH P5OUT |= BIT4
#define IIC_SCL_LOW P5OUT &= ~BIT4
#define IIC_SDA_READ P3IN&0x80
#define IIC_SCL_READ P5IN&0x10
void delay(unsigned int t)
{
unsigned int i,j;
for(i=0;i<t;i++)
{for(j=0;j<200;j++)
{;}}
}
void I2CInit(void)
{
IIC_SDA_OUT;
IIC_SCL_OUT;
IIC_SDA_LOW;
IIC_SCL_LOW;
__delay_cycles(10);
IIC_SDA_HIGH;
IIC_SCL_HIGH;
__delay_cycles(80);
}
void I2CStart(void)
{
IIC_SDA_OUT;
IIC_SCL_OUT;
IIC_SDA_HIGH; //发送起始条件的数据信号
IIC_SCL_HIGH;
IIC_SDA_LOW; //发送起始信号
__delay_cycles(5); //起始条件锁定时间大于4μs
IIC_SCL_LOW; //钳住I2C总线,准备发送或接收数据
__delay_cycles(5);
}
void I2CStop(void)
{
IIC_SDA_OUT;
IIC_SCL_OUT;
IIC_SDA_LOW; //发送结束条件的数据信号--ZLG
IIC_SCL_LOW;
IIC_SCL_HIGH; //发送结束条件的时钟信号--ZLG
__delay_cycles(5); //结束条件建立时间大于4μs--ZLG
IIC_SDA_HIGH; //发送I2C总线结束信号--ZLG
__delay_cycles(5);
}
unsigned char I2C_Read_Byte(unsigned char ack)
{
unsigned char mask,RDByte=0;
IIC_SDA_OUT;
IIC_SCL_OUT;
IIC_SDA_HIGH;
for(mask=0x80; mask>0; mask>>=1)
{
IIC_SCL_HIGH;
__delay_cycles(4);
IIC_SDA_IN;
if(IIC_SDA_READ == 1)
{
RDByte = RDByte|mask;
}
IIC_SCL_LOW;
__delay_cycles(1);
}
IIC_SDA_OUT;
if(ack ==1){
IIC_SDA_HIGH;
}else{
IIC_SDA_LOW;
}
__delay_cycles(1);
IIC_SCL_HIGH;
__delay_cycles(5);
IIC_SCL_LOW;
IIC_SDA_HIGH;
__delay_cycles(20);
return RDByte;
}
unsigned char I2C_Write_Byte(unsigned char byte)
{
unsigned char mask,error=0;
IIC_SDA_OUT;
IIC_SCL_OUT;
for(mask=0x80; mask>0; mask>>=1)
{
if(mask&0x80)
{
IIC_SDA_HIGH;
}
else
{
IIC_SDA_LOW;
}
__delay_cycles(1);
IIC_SCL_HIGH;
__delay_cycles(5);
IIC_SCL_LOW;
__delay_cycles(1);
}
IIC_SDA_HIGH;
IIC_SCL_HIGH;
__delay_cycles(1);
IIC_SDA_IN;
if(IIC_SDA_READ == 1)
error= 1;
IIC_SCL_LOW;
__delay_cycles(20);
return error;
}
void SET_Resolution(void)
{
I2CStart(); //Start I2C
if(I2C_Write_Byte(SHT20ADDR&0xfe)==0) //I2C address + write + ACK
{
if(I2C_Write_Byte(0xe6)==0) //写用户寄存器
{
if(I2C_Write_Byte(0x83)==0); //设置分辨率 11bit RH% 测量时间:12ms(typ.) & 11bit T℃ 测量时间:9ms(typ.)
}
}
I2CStop(); //Stop I2C
}
float SHT2x_MeasureTempHM(void)
{
float TEMP;
unsigned char tmp1, tmp2;
unsigned int ST,i;
IIC_SCL_OUT;
I2CStart();
I2C_Write_Byte(0x80);
I2C_Write_Byte(0xE3);
I2CStart();
I2C_Write_Byte(0x81);
IIC_SCL_HIGH;
IIC_SCL_IN;
for(i=0;i<1000;i++)
{
__delay_cycles(10);
if(IIC_SCL_READ==1)break;
}
tmp1 = I2C_Read_Byte(0);
tmp2 = I2C_Read_Byte(0);
I2CStop();
ST = (tmp1 << 8) | (tmp2 << 0);
ST &= ~0x0003;
TEMP = ((float)ST * 0.00268127) - 46.85;
IIC_SCL_OUT;
return (TEMP);
}