打印

I2C发送接收数据都不行,用的是24C02

[复制链接]
1710|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
joypark159|  楼主 | 2013-8-5 11:42 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
I2c, IO, pi, gp, GPIO
本帖最后由 joypark159 于 2013-8-5 11:52 编辑

调试好几天了,都没搞定是什么问题,求高手帮忙

#include <stm32f10x.h>
#include <stm32f10x_I2C.h>

#define SData GPIO_Pin_7   //PB7;     //I2C  数据
#define SCLK GPIO_Pin_6    //PB6;     //I2C 时钟

#define SCL(x)        x ? GPIO_SetBits(GPIOB,  SCLK)  : GPIO_ResetBits(GPIOB , SCLK)
#define        SDA(x)  x ? GPIO_SetBits(GPIOB , SData) : GPIO_ResetBits(GPIOB , SData)
#define AT24C02 0xa0  
extern delay(int);
volatile u32 ack;

uint8_t SendDat[2] = {0x01,0x03};
uint8_t RecvDat[2];

void AT24C02_SDA_IO_SET(unsigned char io_set) //SDA输入输出设置
{
    if(io_set==0)
  {
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  GPIO_InitStructure.GPIO_Pin = SData;          //24C02 SDA 作为输出
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  }
else if(io_set==1)
  {
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
  GPIO_InitStructure.GPIO_Pin = SData;          //24C02 SDA作为输入
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //ÉÏÀ­ÊäÈë
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  }
else
  {;}
}

//////////////////启动///////////////
void Start_I2c(void)
{

  SDA(1);  //SDA=1; 发送起始条件的数据应答
  delay(5);
  SCL(1);          //SCL=1;
  delay(10);
  
  SDA(0);  //SDA=0;       ·发送起始信号
  delay(10);      
  SCL(0);          //SCL=0;       准备发送或接收数据
  delay(5);
}

/////////////////停止/////////////////
void Stop_I2c(void)
{
        
  SDA(0);  //SDA=0;   //·发送结束条件的数据信号
  delay(5);      
  SCL(1)        ; //SCL=1;
  delay(10);
  SDA(1);  //SDA=1;发送结束信号
  delay(10);
        SCL(0);
}
///////////////////////发送数据///////////////////
void SendByte(uint8_t data)
{
        u32 BitCnt;
        AT24C02_SDA_IO_SET(0);
        for(BitCnt=0;BitCnt<8;BitCnt++)  //数据长度8
        {
                if((data<<BitCnt) & 0x80)
                        SDA(1);  //SDA=1;判断发送位
                else
                        SDA(0); // SDA=0               
                delay(5);
                SCL(1);      //SCL=1 通知控制器开始接收数据
                delay(10);  
                SCL(0);             //SCL = 0
        }
        delay(5);  
        SDA(1);
        delay(5);  
        SCL(1);   //SCL=1
        delay(5);
        
        if(GPIO_ReadOutputDataBit(GPIOB ,SData)==1)
                ack=0;     
        else
                ack=1;     //判断是否接收到应答信号
        SCL(0);   //SCL=0;
        delay(5);        
}

//////////////接收数据////////////////            
uint8_t RcvByte(void)
{
  uint8_t retc;
  uint8_t BitCnt;
  AT24C02_SDA_IO_SET(1);
  retc=0;
  SDA(1); //SDA=1 设数据线为输入模式
        delay(10);
  for(BitCnt=0;BitCnt<8;BitCnt++)
  {   
                delay(1);           
                SCL(0);    //SCL=0 准备接收数据
                delay(5);   
                SCL(1);    //SCL=1 接收数据
                delay(5);
                retc=retc<<1;
                if(GPIO_ReadInputDataBit(GPIOB , SData))
                        retc=retc+1; // SDA == 1读取数据,存入在retc 中
                delay(10);
        }
        SCL(0);
        delay(5);
        return(retc);
}

/********************************************************************
                   应答
********************************************************************/

void Ack_I2c(uint8_t a)
{

  if(a==0)
                SDA(0);  //SDA=0有应答或没应答
  else
                SDA(1);  //SDA=1;
  delay(5);   

  SCL(1);   //SCL=1;         
  delay(5);        

  SCL(0)        ;   //SCL=0; 清时钟线
  delay(5);

}

//AT2402功能函数

     ////////////////发送多字节数据  ///           
uint8_t ISendStr(uint8_t sla,uint8_t suba,uint8_t *s,uint8_t no)
{
        uint8_t i;

        Start_I2c();               /*启动总线*/
        SendByte(sla);             /*·发送器件地址·*/
   if(ack==0)
                 return(0);
        SendByte(suba);            /*·发送器件子地址·*/
   if(ack==0)
                 return(0);

        for(i=0;i<no;i++)
        {   
                SendByte(*s);            /*发送数据Ý*/
                if(ack==0)
                        return(0);
                s++;
        }
        Stop_I2c();                /*结束总线*/

        return(1);
}


//////////////////////////´接收多字节数据///

uint8_t IRcvStr(uint8_t sla,uint8_t suba,uint8_t *s,uint8_t no)
{
        uint8_t i;

        Start_I2c();                  /*启动总线*/
        SendByte(sla);                /*·发送器件地址*/
   if(ack==0)
                 return(0);
        SendByte(suba);               /*·发送器件子地址·*/
   if(ack==0)
                 return(0);

        Start_I2c();                 /*重启动总线*/
        SendByte(sla+1);
  if(ack==0)
                return(0);
        for(i=0;i<no-1;i++)
        {   
                *s=RcvByte();               /*·发送数据*/
                Ack_I2c(0);                /*·数据应答*/  
                s++;
        }
        *s=RcvByte();
        Ack_I2c(1);                   /*发送非应答位*/
        Stop_I2c();                   /*结束总线*/
        return(1);
}

void I2C_EEPROM()
{
        
        while(1)
        {
                ISendStr(AT24C02,1,&SendDat[0],2);
                delay(100);
                IRcvStr(AT24C02,1,&RecvDat[0],2);
                if(RecvDat[0]==0x01&&RecvDat[1]==0x03)
                {
                        GPIO_ResetBits(GPIOB,GPIO_Pin_4);
                }
                else
                {
                        GPIO_ResetBits(GPIOB,GPIO_Pin_3);
                }
        }
}
沙发
outstanding| | 2013-8-5 11:43 | 只看该作者
网上有很多例子啊,直接移植,然后只需改一下管脚就可以吧。

使用特权

评论回复
板凳
joypark159|  楼主 | 2013-8-5 11:53 | 只看该作者
outstanding 发表于 2013-8-5 11:43
网上有很多例子啊,直接移植,然后只需改一下管脚就可以吧。

能给我个实用的例子链接么,我找了很多,有的都不能用

使用特权

评论回复
地板
outstanding| | 2013-8-5 14:01 | 只看该作者
joypark159 发表于 2013-8-5 11:53
能给我个实用的例子链接么,我找了很多,有的都不能用

参考 http://www.amobbs.com/forum.php?mod=viewthread&tid=3453570&highlight=STM32%2B%2BI2C
https://bbs.21ic.com/icview-184741-1-1.html

像这种比较常规的,肯定有人写过,像STM32 网上的例子都是满天飞。楼主再搜搜。希望对你有帮助。有空我把我以前写过的整理一下。:lol

使用特权

评论回复
5
joypark159|  楼主 | 2013-8-5 14:53 | 只看该作者
outstanding 发表于 2013-8-5 14:01
参考 http://www.amobbs.com/forum.php?mod=viewthread&tid=3453570&highlight=STM32%2B%2BI2C
http://bb ...

这个例程我也有看过,但是这个要怎么应用,
while(1)
        {
                I2C_FRAM_BufferWrite(SendDat,0xa0,2);
                delay(100);
                I2C_FRAM_BufferRead(RecvDat,0xa0,2);
                if(RecvDat[0]==0x01&&RecvDat[1]==0x03)
                {
                        GPIO_ResetBits(GPIOB,GPIO_Pin_4);
                }
                else
                {
                        GPIO_ResetBits(GPIOB,GPIO_Pin_3);
                }
        }
这样可以?

使用特权

评论回复
6
zbaifzl314| | 2013-8-17 16:49 | 只看该作者
路过!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

8

主题

30

帖子

0

粉丝