iic读写测试,为什么主机接受应答时读取SDA一直为1,接受失败,求大神帮忙解决
ii2c.h
#ifndef __I2C_H
#define __I2C_H
#include "stm32f10x.h"
void I2C_Configuration(void);
void I2C_SDA_OUT(void);
void I2C_SDA_IN(void);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_Ack(void);
void I2C_NAck(void);
u8 I2C_Wait_Ack(void);
void I2C_Send_Byte(u8 txd);
u8 I2C_Read_Byte(void);
void I2CWriteByteToDevice16(u8 deviceWriteAddr,u16 registerAddr,u8 dat);
u8 I2CReadByteFromDevice16(u8 deviceWriteAddr,u16 registerAddr);
#endif
i2c.c
#include "delay.h"
#include "I2C.h"
#define I2C_SCL GPIO_Pin_6
#define I2C_SDA GPIO_Pin_7
#define GPIO_I2C GPIOB
#define I2C_SCL_H GPIO_SetBits(GPIO_I2C,I2C_SCL)
#define I2C_SCL_L GPIO_ResetBits(GPIO_I2C,I2C_SCL)
#define I2C_SDA_H GPIO_SetBits(GPIO_I2C,I2C_SDA)
#define I2C_SDA_L GPIO_ResetBits(GPIO_I2C,I2C_SDA)
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=I2C_SCL|I2C_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
I2C_SCL_H;
I2C_SDA_H;
}
void I2C_SDA_OUT(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=I2C_SDA;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void I2C_SDA_IN(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=I2C_SDA;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
//产生起始信号
void I2C_Start(void)
{
I2C_SDA_OUT();
I2C_SDA_H;
I2C_SCL_H;
delay_us(5);
I2C_SDA_L;
delay_us(6);
I2C_SCL_L;
}
//产生停止信号
void I2C_Stop(void)
{
I2C_SDA_OUT();
I2C_SCL_L;
I2C_SDA_L;
delay_us(6);
I2C_SCL_H;
I2C_SDA_H;
delay_us(6);
}
//主机产生应答信号ACK
void I2C_Ack(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_L;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//主机不产生应答信号NACK
void I2C_NAck(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_H;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//等待从机应答信号
//返回值:1 接收应答失败
// 0 接收应答成功
u8 I2C_Wait_Ack(void)
{
u8 tempTime=0;
I2C_SDA_IN();
I2C_SDA_H;
delay_us(1);
I2C_SCL_H;
delay_us(1);
while(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
{
tempTime++;
if(tempTime>250)
{
I2C_Stop();
return 1;
}
}
I2C_SCL_L;
return 0;
}
//I2C 发送一个字节
void I2C_Send_Byte(u8 txd)
{
u8 i=0;
I2C_SDA_OUT();
I2C_SCL_L;//拉低时钟开始数据传输
for(i=0;i<8;i++)
{
if((txd&0x80)>0) //0x80 1000 0000
I2C_SDA_H;
else
I2C_SDA_L;
txd<<=1;
I2C_SCL_H;
delay_us(2); //发送数据
I2C_SCL_L;
delay_us(2);
}
}
//I2C 读取一个字节
u8 I2C_Read_Byte(void)
{
u8 i=0,receive=0;
I2C_SDA_IN();
for(i=0;i<8;i++)
{
I2C_SCL_L;
delay_us(2);
I2C_SCL_H;
receive<<=1;
if(GPIO_ReadInputDataBit(GPIO_I2C,I2C_SDA))
receive|=0x01; //////////////////////////////////////////////////
delay_us(1);
}
return receive;
}
void I2CWriteByteToDevice16(u8 deviceWriteAddr,u16 registerAddr,u8 dat)
{
I2C_Start();
I2C_Send_Byte(deviceWriteAddr); //设备写地址
I2C_Wait_Ack();
I2C_Send_Byte(registerAddr>>8); //先写高8位地址
I2C_Wait_Ack();
I2C_Send_Byte(registerAddr&0x00ff); //再写低8位地址
I2C_Wait_Ack();
I2C_Send_Byte(dat);
I2C_Wait_Ack();
I2C_Stop();
delay_ms(10);
}
u8 I2CReadByteFromDevice16(u8 deviceWriteAddr,u16 registerAddr)
{
u8 dat=0;
I2C_Start();
I2C_Send_Byte(deviceWriteAddr); //设备写地址
I2C_Wait_Ack();
I2C_Send_Byte(registerAddr>>8); //先写高8位地址
I2C_Wait_Ack();
I2C_Send_Byte(registerAddr&0x00ff); //再写低8位地址
I2C_Wait_Ack();
I2C_Start();
I2C_Send_Byte(deviceWriteAddr|0x01); //修改设备地址的读写标志位
I2C_Wait_Ack();
dat=I2C_Read_Byte();
I2C_NAck();
I2C_Stop();
return dat;
}
main.c
#include "stm32f10x.h"
#include "system.h"
#include "i2c.h"
#include "delay.h"
void RCC_Configuration(void);
u8 dat=7;
u8 rece;
#define AT24C64_WRITE_ADDR 0xA0 //AT24C64的IIC写地址
int main(void)
{
RCC_Configuration();
delay_init(72);
NVIC_Config();
I2C_Configuration();
delay_ms(1);
I2CWriteByteToDevice16(AT24C64_WRITE_ADDR,0x01,dat);
delay_ms(10);
rece=I2CReadByteFromDevice16(AT24C64_WRITE_ADDR,0x01);
delay_ms(10);
while(1);
}