野火电子论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 7331|回复: 2

求大佬解答 I2C 基本流程程序错误

[复制链接]
发表于 2022-7-21 20:10:26 | 显示全部楼层 |阅读模式

我参照  stm32f10x_I2C.h 的说明配置和编写主模式下的单字节读写函数。我通过函数的返回值得知运行结果写入正确,读取错误。
读取数据固定为0xa0,和E2PROM 设备地址一样,我不知道是巧合还是其他的情况,所以请大佬帮忙看看,我的程序到底错在哪里。
在这里先谢谢为我解答的大佬



/***************   I2C读取E2PROM  **************/

include "IIC_Config.h"


void IIC_Init(void){
       
       
        GPIO_InitTypeDef GPIO_InitStruct;
        I2C_InitTypeDef I2C_InitStruct;
       
       
        RCC_APB1PeriphClockCmd(GPIO_IIC_CLK,ENABLE);
        RCC_APB2PeriphClockCmd(GPIO_CLK,ENABLE);
       
        GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;
        GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStruct.GPIO_Pin = IIC_SCL_PIN;
        GPIO_Init(IIC_SCL_PORT,&GPIO_InitStruct);
       
        GPIO_InitStruct.GPIO_Pin = IIC_SDA_PIN;
        GPIO_Init(IIC_SDA_PORT,&GPIO_InitStruct);
       
        I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
        I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_16_9;
        I2C_InitStruct.I2C_Mode =I2C_Mode_I2C;
        I2C_InitStruct.I2C_OwnAddress1 = I2C_OWN_ADDR;
        I2C_InitStruct.I2C_ClockSpeed = 400000;
        I2C_Init(I2C1,&I2C_InitStruct);
       
        I2C_Cmd(I2C1,ENABLE);
       
       
}



uint8_t IIC_Write_Byte(uint8_t ADDR_STA,uint8_t data){
       
               
        I2C_GenerateSTART(I2Cx,ENABLE);   //   产生START条件
  while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));     //检测 EV5 事件
       
        I2C_Send7bitAddress(I2Cx,E2PROM_ADDR,I2C_Direction_Transmitter);     //  发送7 bit E2PROM地址
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));    //检测 EV6 事件

        I2C_SendData(I2Cx,ADDR_STA);           //发送写入数据地址
        while(!I2C_CheckEvent (I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTING));   //  检测 EV8 事件
       
        I2C_SendData(I2Cx,data);         //   写入数据
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTED));   //检测 EV8-2事件
       
        I2C_GenerateSTOP(I2Cx,ENABLE);  //  产生STOP条件
       
        return data;
       
}



u8 IIC_Read_Byte(uint8_t ADDR_STA){
       
        uint8_t TEMP;
       
        while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY));      //判忙标志位检查,BUSY_FLAG
       
        I2C_GenerateSTART(I2Cx,ENABLE);   //   产生START条件
       while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_MODE_SELECT));     //检测 EV5 事件
       
        I2C_Send7bitAddress(I2Cx,E2PROM_ADDR,I2C_Direction_Transmitter);     //  发送7 bit E2PROM地址
        while(!I2C_CheckEvent(I2Cx,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));    //检测 EV6 事件

        I2C_SendData(I2Cx,ADDR_STA);           //发送写入数据地址
        while(!I2C_CheckEvent (I2Cx,I2C_EVENT_MASTER_BYTE_TRANSMITTING));   //  检测 EV8 事件
       
       
        I2C_GenerateSTART(I2C1,ENABLE);           //  产生START条件        
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT));   //检测 EV5 事件
       
       
        I2C_SendData(I2C1,E2PROM_ADDR);    //发送 E2PROM 地址数据
        while(!I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ));   //检测 EV6 事件
       
       
        while(!I2C_CheckEvent(I2C1,I2C_CheckEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED| I2C_FLAG_BTF )));  //  EV7 和  BTF(字节发送完毕)标志位
        TEMP = I2C_ReceiveData(I2C1);      // 读取数据

       
        I2C_AcknowledgeConfig(I2C1,DISABLE);   //开启不应答模式
       
       
        I2C_GenerateSTOP(I2C1,ENABLE);    //  产生STOP条件
       
       
        I2C_AcknowledgeConfig(I2C1,ENABLE);    //重新开启应答模式,避免影响后续通信
        return TEMP;
       
}

=============================== I2C读取E2PROM头文件============================================       

#ifndef _IIC_CONFIG_H_
#define _IIC_CONFIG_H_

#include "stm32f10x.h"


#define  GPIO_IIC_CLK     RCC_APB1Periph_I2C1      
#define  GPIO_CLK         RCC_APB2Periph_GPIOB

#define  IIC_SCL_PORT     GPIOB      
#define  IIC_SCL_PIN      GPIO_Pin_6
#define  IIC_SDA_PORT     GPIOB      
#define  IIC_SDA_PIN      GPIO_Pin_7

#define  I2Cx             I2C1
#define  E2PROM_ADDR      0XA0
#define  I2C_OWN_ADDR     0X09


#define  Standard_Speed   100000
#define  Fast_Speed       400000






void IIC_Init(void);
uint8_t  IIC_Write_Byte(uint8_t ADDR_STA,uint8_t data);
u8 IIC_Read_Byte(uint8_t ADDR_STA);


#endif  /*IIC_CONFIG_H*/

***************************************************************************/

/*****************主函数*****************************************/

#include "SysTick.h"
#include "IIC_Config.h"
#include "MUSART.h"

uint8_t pData;
uint8_t qData;


int main(){
       
        MUSART_INIT(115200);
        IIC_Init();
        printf("\r\n 这是一个I2C外设(AT24C02)读写测试例程 \r\n");

       
        qData = IIC_Write_Byte(5,0x54);
        printf("写入数据:0x%02x \n\r",qData);
       
        pData= IIC_Read_Byte(5);
        printf("读取数据为:0x%x \n\r",pData);
       
        if(qData == pData){
               
                printf("读写成功");
        }
        else{
               
                printf("读写失败");
        }
        while(1);       
}



***********************************************************************************/






野火论坛202207212009081048..png
野火论坛202207212008546839..png
回复

使用道具 举报

发表于 2022-7-25 11:57:44 | 显示全部楼层
什么板子的?试过例程正常吗
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-25 15:29:07 | 显示全部楼层
LF_laffy 发表于 2022-7-25 11:57
什么板子的?试过例程正常吗

普中玄武的板子,除了几个灯其他的和野火基本一致,应该是各大厂商原理图共享了,
野火的标准例程通过了。
我联系安富莱和普中的售后,根本不管,就管板子提供商提供的标准例程的基础代码讲解。
普中的只有模拟I2C,那个例程c语言讲解基本没什么意义,看c语言基本都能自己分析出来,其他的动不动就是 “不在售后范围” ,这种售后有和没有几乎没区别,不知道野火的售后是什么样子。
安富莱让我使用逻辑分析仪抓时序。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

联系站长|手机版|野火电子官网|野火淘宝店铺|野火电子论坛 ( 粤ICP备14069197号 ) 大学生ARM嵌入式2群

GMT+8, 2024-11-23 21:51 , Processed in 0.029549 second(s), 26 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表