I2C通信从机无应答可能是什么原因
代码如下:
include "ri2c.h"
include "delay.h"
define I2C_Write 0x5A
define I2C_Read 0x5B
undef SUCCESS
define SUCCESS 0
undef FAILED
define FAILED 1
void wait(void)
{
delay_us(10);
}
void SCL_W(uint8_t data)
{
GPIO_WriteDataBits(GPIO0,I2C_SCL,data);
wait();
}
void SDA_W(uint8_t data)
{
GPIO_WriteDataBits(GPIO0,I2C_SDA,data);
wait();
}
uint8_t SDA_R(void)
{
uint8_t value = GPIO_ReadDataBits(GPIO0,I2C_SDA);
return value;
}
void RI2C_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_Pin = I2C_SCL|I2C_SDA;
GPIO_InitStructure.GPIO_Int = GPIO_Int_Disable;
GPIO_Init(GPIO0,&GPIO_InitStructure);
GPIO_SetBit(GPIO0,I2C_SCL|I2C_SDA);
}
void I2C_Start(void)
{
SDA_W(1);
SCL_W(1);
SDA_W(0);
SCL_W(0);
}
void I2C_Stop(void)
{
SDA_W(0);
SCL_W(1);
SDA_W(1);
}
void I2C_WriteAbyte(uint8_t dat)
{
uint8_t i;
for (i = 0; i < 8; i ++)
{
SDA_W(!!(dat & (0x80 >> i)));
SCL_W(1);
SCL_W(0);
}
}
uint8_t I2C_ReadAbyte(void)
{
uint8_t i, Byte = 0x00;
SDA_W(1);
for (i = 0; i < 8; i ++)
{
SCL_W(1);
if (SDA_R()){Byte |= (0x80 >> i);}
SCL_W(0);
}
return Byte;
}
void SendACK(void)
{
SDA_W(0);
SCL_W(1);
SCL_W(0);
}
void SendNAK(void)
{
SDA_W(1);
SCL_W(1);
SCL_W(0);
}
uint8_t I2C_Check_ACK(void)
{
uint8_t result;
SDA_W(1);
// GPIO_ClrOutEnable(GPIO0,I2C_SDA);
SCL_W(1);
result = SDA_R();
SCL_W(0);
// GPIO_SetOutEnable(GPIO0,I2C_SDA);
return result;
}
void WriteNbyte(uint8_t addr, uint8_t p, uint8_t num)
{
I2C_Start(); //·¢ËÍÆðʼÃüÁî
I2C_WriteAbyte(I2C_Write); //·¢ËÍÉ豸µØÖ·+дÃüÁî
I2C_Check_ACK();
I2C_WriteAbyte(addr); //·¢ËÍ´æ´¢µØÖ·
I2C_Check_ACK();
do
{
I2C_WriteAbyte(p);
p++;
I2C_Check_ACK();
}
while(--num);
I2C_Stop(); //·¢ËÍÍ£Ö¹ÃüÁî
}
void ReadNbyte(uint8_t addr, uint8_t p, uint8_t num) / WordAddress,First Data Address,Byte lenth */
{
I2C_Start(); //·¢ËÍÆðʼÃüÁî
I2C_WriteAbyte(I2C_Write); //·¢ËÍÉ豸µØÖ·+дÃüÁî
I2C_Check_ACK();
I2C_WriteAbyte(addr); //·¢ËÍ´æ´¢µØÖ·
I2C_Check_ACK();
I2C_Start(); //·¢ËÍÆðʼÃüÁî
I2C_WriteAbyte(I2C_Read); //·¢ËÍÉ豸µØÖ·+¶ÁÃüÁî
I2C_Check_ACK();
do
{
*p = I2C_ReadAbyte(); p++;
if(num != 1) SendACK(); //send ACK
}
while(--num);
SendNAK(); //send no ACK
I2C_Stop(); //·¢ËÍÍ£Ö¹ÃüÁî
}
uint8_t IIC_Write_1Byte(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t REG_data)
{
I2C_Start();
I2C_WriteAbyte(SlaveAddress<<1);
I2C_Check_ACK();
I2C_WriteAbyte(REG_Address);
I2C_Check_ACK();
I2C_WriteAbyte(REG_data);
I2C_Check_ACK();
I2C_Stop();
return SUCCESS;
}
uint8_t IIC_Read_1Byte(uint8_t SlaveAddress,uint8_t REG_Address,uint8_t *REG_data)
{
I2C_Start();
I2C_WriteAbyte(SlaveAddress<<1);
I2C_Check_ACK();
I2C_WriteAbyte(REG_Address);
I2C_Check_ACK();
I2C_Stop();
I2C_Start();
I2C_WriteAbyte((SlaveAddress<<1)+1);
I2C_Check_ACK();
*REG_data = I2C_ReadAbyte();
SendNAK();
I2C_Stop();
return SUCCESS;
}
在while循环外写入从机地址,从机没有应答,
(地址和硬件都没问题,代码本来是stc8上的,移植到32位处理器上不知道为什么就不行了)

浙公网安备 33010602011771号