iic读写测试,为什么主机接受应答时读取SDA一直为1,接受失败,求大神帮忙解决

BadJiang BadJiang 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
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);
}

...全文

相关推荐

STM32使用模拟IIC实现24C02读取

但STM32自身并不总是配备硬件IIC接口,因此有时需要通过软件模拟IIC(也称为I2C)通信协议来实现对24C02的读写操作。接下来,我们将深入探讨这一过程中涉及的关键知识点。1.

weixin_38562085

【IoT】STM32 IIC 详解 之 stm32 IIC 从机模式(中断方式收发数据)

1、IIC简介 第二节代码会用到该部分内容,对于IIC来说,从机是不能主动发送数据的,开始条件都是由主机生成。 1.1、主机发送数据流程 1) 主机在检测到总线为“空闲状态”(即 SDA、SCL 线均为高电平)时,发送一个启动信号“S”,开始一次通信的开始 2) 主机接着发送一个命令字节。该字节由 7 位的外围器件地址和 1 位读写控制位 R/W组成(此时 R/W=0) 3...

产品人卫朋

Arduino AT24C02写数据时使用示波器捕获IIC波形

Arduino AT24C02写数据时使用示波器捕获IIC波形 本示例通过学习正点原子的《嵌入式工程师必备技能–如何使用示波器查看IIC波形》在Arduino 上位机程序烧录到Arduino UNO板并连接上测试模块AT24C02的方法来捕获波形。 测试代码 /* * Wire库I2C基本读写程序 * AT24C02读写操作 * */ #include &lt;Wire.h&gt; // 使用Wire库,需要包含头文件 const int1

perseverance52

GD32E230硬件IIC读写24C04

分页读写则意味着可以一次性处理24C04中的一整页数据,而不是逐个字节操作,提高了读写速度。在这个过程中,你需要了解以下关键知识点:1.

呐咯密密

使用STM32 GPIO口模拟IIC

**错误检测**:在模拟IIC过程中,需要检测SDA线是否在SCL高电平时保持稳定,以及是否正确产生了开始和停止条件。任何异常都可能导致通信失败,需要进行相应的错误处理。7.

u010486276
评论 10
收藏 已收藏
分享
返回顶部