STM32 IIC写入读取出现问题

我写了一个IIC的字节读取写入,但是写入读取时没有变化,运行阶段都正常运行了,没有出现报错,请问这是什么问题?

这是主程序

#include "hxy_config.h"



int main(void)
{
    BSP_USART_INIT();
    printf("你好");
       I2c_Config();

    uint8_t  arr[] = {15}, b[10];
    printf("%d", b[0]);
    I2c_Bity_Write(30, &arr[0]);
    printf("你好");
    I2c_Bity_Read(30,b,1);
    
    printf("%d", b[0]);
  
    while(1)
    {
    
    }
        
    

}




这是i2c头文件


#ifndef _BSP_I2C_H
#define _BSP_I2C_H


#include "hxy_config.h"

#define I2C_TIME_OUT  (0xA000)
#define EEPROM_ADDRESS (0xA0) 
#define EEPROM_SZIE 256


void I2c_Config(void);
static uint32_t  i2c_error_show(uint16_t i);

uint32_t  I2c_Bity_Write(uint8_t   bityaddr , uint8_t  * pbuffer);

void I2c_Wait_EE_Ready(void);

uint8_t  I2c_Bity_Read(uint8_t bityaddr, uint8_t  * pbuffer, uint16_t bity_num);
static uint8_t  i2c_read_error_show(uint16_t i);

#endif


这是i2c

#include "bsp_i2c.h"


void I2c_Config(void)
{
    //初始化GPIO,PB6为SCL,PB7为SDA
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE );  //开启I2C时钟
    GPIO_InitTypeDef  i2c_gpio_pb6;
    GPIO_InitTypeDef  i2c_gpio_pb7;
    
    i2c_gpio_pb6.GPIO_Pin = GPIO_Pin_6;
    i2c_gpio_pb6.GPIO_Mode = GPIO_Mode_AF_OD;
    i2c_gpio_pb6.GPIO_Speed = GPIO_Speed_50MHz;
    
    i2c_gpio_pb7.GPIO_Pin = GPIO_Pin_7;
    i2c_gpio_pb7.GPIO_Mode = GPIO_Mode_AF_OD;
    i2c_gpio_pb7.GPIO_Speed = GPIO_Speed_50MHz;
    
    GPIO_Init(GPIOB, &i2c_gpio_pb6);
    GPIO_Init(GPIOB, &i2c_gpio_pb7);
    
    
    
    I2C_InitTypeDef  i2c_init_struct;
    
    i2c_init_struct.I2C_ClockSpeed = 400000;
    i2c_init_struct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    i2c_init_struct.I2C_DutyCycle = I2C_DutyCycle_2 ;
    i2c_init_struct.I2C_Mode = I2C_Mode_I2C;
    i2c_init_struct.I2C_OwnAddress1 = 0x0A;   //只需不同就可
    i2c_init_struct.I2C_Ack = I2C_Ack_Enable;
    I2C_Init(I2C1, &i2c_init_struct);      //初始化i2c
    
    I2C_Cmd(I2C1,ENABLE);
    
    
    

    
}



static uint32_t  i2c_error_show(uint16_t i)
{
    printf("i2c传输出现错误,错误原因为 :%d" , i);
    return  0;
    
}

uint32_t  I2c_Bity_Write(uint8_t   bityaddr , uint8_t * pbuffer)
{
    //while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY) != RESET);
    I2C_GenerateSTART(I2C1,ENABLE);
    
    uint32_t time_out = I2C_TIME_OUT;
    
  while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))        //开始位    
    {
        if(time_out == 0)
            return i2c_error_show(0);
        
        time_out--;
    }
    
    time_out = I2C_TIME_OUT;
    
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS,I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))        //输入EEROM地址位
    {
        if(time_out <= 0)
            return i2c_error_show(0);
        
        time_out--;
    }
    
    time_out = I2C_TIME_OUT;
    I2C_SendData(I2C1, bityaddr);
    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED ))        //输入字节存放在EEROM位置
    {
        if(time_out <= 0)
            return i2c_error_show(0);
        
        time_out--;
    }
    
    time_out = I2C_TIME_OUT;
    I2C_SendData(I2C1, *pbuffer);
    
    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED ))        
    {
        if(time_out <= 0)
            return i2c_error_show(0);
        
        time_out--;
    }
    
    I2C_GenerateSTOP(I2C1, ENABLE );
    
    
    return 0;
    
    
}  


    


static uint8_t  i2c_read_error_show(uint16_t i)
{
    printf("i2c读取出现错误,错误原因为 :%d" , i);
    return  0;
    
}

uint8_t  I2c_Bity_Read(uint8_t bityaddr, uint8_t  * pbuffer, uint16_t bity_num)
{
    I2c_Wait_EE_Ready();
    while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY) != RESET);        //确认是否在占用数据传输
    I2C_GenerateSTART(I2C1,ENABLE);
    
    uint32_t time_out = I2C_TIME_OUT;
    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))        //开始位
    {
        if(time_out <= 0)
            return i2c_read_error_show(0);
        
        time_out--;
    }
    
    time_out = I2C_TIME_OUT;
    
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS,I2C_Direction_Transmitter);
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))        //输入EEROM地址位
    {
        if(time_out <= 0)
            return i2c_read_error_show(1);
        
        time_out--;
    }
    
    time_out = I2C_TIME_OUT;
    I2C_SendData(I2C1, bityaddr);
    
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED))        //输入字节存放在EEROM位置
    {
        if(time_out <= 0)
            return i2c_read_error_show(2);
        
        time_out--;
    }
    
    I2C_GenerateSTART(I2C1,ENABLE);
    
    
    ;
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT))        //开始位
    {
        if(time_out <= 0)
            return i2c_read_error_show(3);
        
        time_out--;
    }
    
    time_out = I2C_TIME_OUT;
    
    I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS,I2C_Direction_Receiver);
    while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ))        //输入EEROM地址位
    {
        if(time_out <= 0)
            return i2c_read_error_show(4);
        
        time_out--;
    }
    uint8_t i = 0;
    while(i != bity_num)
    {
      time_out = I2C_TIME_OUT;
        *(pbuffer + i) = I2C_ReceiveData(I2C1);
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED))        
      {
            if(time_out <= 0)
                return i2c_read_error_show(5);
            
            time_out--;
      }
      i++;
        if(i == bity_num)  I2C_AcknowledgeConfig(I2C1,DISABLE);
  }
    I2C_GenerateSTOP(I2C1, ENABLE );
    I2C_AcknowledgeConfig(I2C1,ENABLE); 
    
    return 0;
    
    
}  
    
    
    


是不是时序的问题啊,我好像没有看到你写开始信号、应答信号这些呢,拉高拉低时钟线和数据线呢?

【相关推荐】



  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7765739
  • 这篇博客也不错, 你可以看下STM32中I2C总线上数据的读、写。
  • 除此之外, 这篇博客: STM32 软件模拟IIC/I2C 完成寻址、读、写、按页写等操作中的 iic.h 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    #ifndef __IIC_H
    #define __IIC_H
    
    #include "firmware.h"
    
    #define IIC_SCL PFout(1)  //模拟输出时钟脉冲
    #define IIC_SDA PFout(0)  //数据线定义输出
    #define IIC_WP  PFout(2)  //数据写保护引脚
    
    #define READ_SDA PFin(0)  //数据线定义输入
    
    #define Page_Size 16     //一页存储的字节数,具体看相应器件的datasheet
    
    void IIC_SDA_IN(void);   //IO定义输入输出配置
    void IIC_SDA_OUT(void);
    	
    void IIC_Init(void);
    void IIC_Start(void);
    void IIC_Stop(void);
    u8 IIC_Wait_Ack(void);
    void IIC_Ack(void);
    void IIC_NAck(void);
    void IIC_Write_Byte(u8 txd);
    u8 IIC_Read_Byte(void);
    u8 Write_Device_Addr(u8 addr);
    void Search_Device_Addr(void);
    u8 Device_Read_One_Byte(u8 IC_Addr,u8 Addr);
    void Device_Write_One_Byte(u8 IC_Addr,u8 Addr,u8 data);
    void Device_Read_Bytes(u8 IC_Addr,u8 Addr,u8 *buf,u8 len);
    void Device_Write_Bytes(u8 IC_Addr,u8 Addr,u8 *buf,u8 len);
    void Device_Page_Write(u8 IC_Addr,u8 Addr,u8 *buf,u8 len);
    
    #endif
    
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

其他配置有没有?

STM32软件模拟实现IIC写入和读取AT24C02(STM32CubeMx配置)
可以参考下


STM32基础(12)IIC读写AT24C02(EEPROM)_stm32 iic按照地址读写数据_神奇的大喵的博客-CSDN博客 原理IIC介绍I2C(Inter-Integrated Circuit)总线是由 PHILIPS 公司开发的两线式串行总线,用于连接微控制器及其外围设备。它是同步通信的一种特殊形式,由于管脚少、硬件实现简单、可扩展性强等特点,被广泛的使用在各大集成芯片内。主机:启动数据传送并产生时钟信号的设备从机:被主机寻址的器件主模式:用 I2CNDAT 支持自动字节计数的模式;位 I2CRM,I2CSTT,I2CSTP控制数据的接收和发送从模式:发送和接收操作都是由 I2C 模块自动控制的发_stm32 iic按照地址读写数据 https://blog.csdn.net/qq_37443229/article/details/121499067

结合GPT给出回答如下请题主参考
很抱歉,根据您提供的信息,无法准确判断问题的原因。建议您检查以下几个方面:

  1. IIC的硬件连接是否正确,包括SDA、SCL等信号线是否正确连接。

  2. IIC发送的地址和数据是否正确,可以使用示波器等工具查看IIC信号是否正确。

  3. IIC的时序是否正确,包括起始信号、停止信号、确认信号等是否正确。

  4. 如果IIC从设备没有回应数据,可能是从设备没有正确配置或工作,需要确认从设备是否正常工作。

建议您逐步排查问题,可以使用调试工具查看变量的值,以及注意错误信息的输出。祝您顺利解决问题。