iic读写测试,为什么主机接受应答时读取SDA一直为1,接受失败,求大神帮忙解决
#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.
【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 <Wire.h> // 使用Wire库,需要包含头文件 const int1
GD32E230硬件IIC读写24C04
分页读写则意味着可以一次性处理24C04中的一整页数据,而不是逐个字节操作,提高了读写速度。在这个过程中,你需要了解以下关键知识点:1.
使用STM32 GPIO口模拟IIC
**错误检测**:在模拟IIC过程中,需要检测SDA线是否在SCL高电平时保持稳定,以及是否正确产生了开始和停止条件。任何异常都可能导致通信失败,需要进行相应的错误处理。7.


驱动开发/核心开发
