当前位置: 代码迷 >> 单片机 >> 好手帮忙看看STM32模拟I2C为什么接收不到数据
  详细解决方案

好手帮忙看看STM32模拟I2C为什么接收不到数据

热度:135   发布时间:2016-04-28 14:51:26.0
高手帮忙看看STM32模拟I2C为什么接收不到数据?

两个问题:
1,这个读取SDA和SCL状态是读ODR还是读IDR呢?
#define I2C_SDA_State GPIOB->ODR&GPIO_Pin_6//SDA状态
#define I2C_SCL_State GPIOB->ODR&GPIO_Pin_7//SCL状态

2,字节接收部分中,I2C_SDA_State一直为低,所以ReData|=0x01一直不执行,读出来的全部是0。大家看看哪里有问题啊?

if(I2C_SDA_State) //读SDA引脚状态
  {
   ReData|=0x01; //如果SDA为高则将SDA上的数据存入ReData
  }   



引脚定义部分:
#define SDA_1 GPIO_SetBits(GPIOB,GPIO_Pin_6)//SDA置1
#define SDA_0 GPIO_ResetBits(GPIOB,GPIO_Pin_6)//SDA置0
#define SCL_1 GPIO_SetBits(GPIOB,GPIO_Pin_7)//SCL置1
#define SCL_0 GPIO_ResetBits(GPIOB,GPIO_Pin_7)//SCL置0
#define I2C_SDA_State GPIOB->ODR&GPIO_Pin_6//SDA状态
#define I2C_SCL_State GPIOB->ODR&GPIO_Pin_7//SCL状态

I2C接收字节部分:
u8 I2C_ReceiveByte(void)//接收一个字节
{
 u8 i,ReData;
 SDA_1;//接收方释放SDA总线
 SCL_0;//让从机准备好数据  
 ReData=0;
 for(i=0;i<8;i++)
 {  
  SCL_1;//SCL=1使数据有效 ,SCL为高期间SDA需保持稳定
  I2C_delay(); 
  ReData<<=1;
  if(I2C_SDA_State) //读SDA引脚状态
  {
   ReData|=0x01; //如果SDA为高则将SDA上的数据存入ReData
  }   
  SCL_0;//准备好再次接收数据,SCL为低才允许SDA变化  
  I2C_delay();//等待数据准备好         
 }
 return ReData;
 }
------解决思路----------------------
一时看不出什么问题,直接给你贴一个我用过的






//iic.h

//for EEPROM

#ifndef _IIC_H_
#define _IIC_H_

#include "macro.h"
#include <stdint.h>
#include "DrvGPIO.h"
#include <stdlib.h>

//定义页长度
#define PAGELEN 32

//定义地址位数,如果是16位地址,移除下面定义
//#define ADDRESS_8BITS


#define SDA1 E_GPA,10
#define SCL1 E_GPA,11

void delay(void);
void delay_ms(unsigned long ms);
void I2C_Start();
void I2C_Stop();
bool Test_Ack();
void SendData(uint8_t buffer);

bool I2C_WriteNByte(uint8_t sla,uint16_t addr,uint8_t *s,uint16_t n);
bool I2C_ReadNByte(uint8_t sla,uint16_t addr,uint8_t *p,uint16_t n);
bool ReadPByte(uint8_t sla,uint16_t addr,uint8_t *p,uint16_t n);
bool WritePByte(uint8_t sla,uint16_t addr,uint8_t *p,uint16_t n);
uint32_t geteepsize(void);

#endif









//FileName:
//Device:
//Interface:
//BaseFile:
//Description: HY3116的驱动(iic接口)


#include "iic.h"
#include "global.h"

#define _nop_() __NOP()

void SDA_H(void)
{
DrvGPIO_SetBit(SDA1);
}
void SDA_L(void)
{
DrvGPIO_ClrBit(SDA1);
}
void SCL_H(void)
{
DrvGPIO_SetBit(SCL1);
}
void SCL_L(void)
{
DrvGPIO_ClrBit(SCL1);
}
uint8_t GetSDA(void)
{
return DrvGPIO_GetBit(SDA1);
}
void delay(void)
{
  uint8_t i;
  for(i=100;i>0;i--){__NOP();}
}

//不精确
void delay_ms(uint32_t ms)
{
uint8_t i;
while(ms>0)
{
for(i=0;i<125;i++)
{
__NOP();
}
ms--;
}
}


/*********************************************************
**名称:I2C_Start
**功能:启动I2C
**输入:无
**返回:无
*********************************************************/
void I2C_Start()
{
    SDA_H();
    delay();
    SCL_H();
    delay();
    SDA_L();
    delay();
    SCL_L();
}

/**********************************************************
**名称:I2C_Stop
**功能:停止I2C
**输入:无
**返回:无
**********************************************************/
void I2C_Stop()
{
    SDA_L();
    delay();
delay();
    SCL_H();
    delay();
delay();
    SDA_H();
    delay();
delay();
}




/**********************************************************
**名称:Ack
**功能:应答信号
**输入:无
**返回:无
**********************************************************/
void Ack()
{
    SDA_L();
    delay();
    SCL_H();
    delay();
    SCL_L();
    delay();
    SDA_H();
    delay();
}



/********************************************************
**名称:NoAck
**功能:发送非应答信号
**输入:无
**返回:无
********************************************************/
void NoAck()
{
    SDA_H();
    delay();
delay();
    SCL_H();
    delay();
delay();
    SCL_L();