OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6146|回复: 8

AT24C02接收到的数据总是255

[复制链接]

2

主题

3

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-6-23
在线时间
2 小时
发表于 2016-6-23 14:24:51 | 显示全部楼层 |阅读模式
1金钱
原子大神求救啊。我在EEPROM中地址为0的地方写进数字16,可是读出来却是255.这说明EEPROM在传数据的时候根本没有拉低电平,这是怎么回事啊?下面附有我的程序#include "IIC.h"//*******************************IIC总线*********************************//
#include "systick.h"
void IIC_init()
{
        GPIO_InitTypeDef GPIO_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
        GPIO_InitStructure.GPIO_Pin = IIC_SCL|IIC_SDA;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB,&GPIO_InitStructure);

        IIC_SCL_H;
        IIC_SDA_H;
}

void IIC_SDA_OUT()
{
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Pin = IIC_SDA;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void IIC_SDA_IN()
{
        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.GPIO_Pin = IIC_SDA;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
        GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void IIC_Start()
{
        IIC_SDA_OUT();
        IIC_SDA_H;
        IIC_SCL_H;
        delay_us(5);
        IIC_SDA_L;
        delay_us(6);
        IIC_SCL_L;
}

void IIC_Stop()
{
        IIC_SDA_OUT();
        IIC_SCL_L;
        IIC_SDA_L;
        IIC_SCL_H;
        delay_us(6);
        IIC_SDA_H;
        delay_us(6);

}

void IIC_Ack()                   //主机应答
{
        IIC_SCL_L;
        IIC_SDA_OUT();
        IIC_SDA_L;
        delay_us(2);
        IIC_SCL_H;
        delay_us(5);
        IIC_SCL_L;

}

void IIC_NAck()                   //主机非应答
{
        IIC_SCL_L;
        IIC_SDA_OUT();
        IIC_SDA_H;
        delay_us(2);
        IIC_SCL_H;
        delay_us(5);
        IIC_SCL_L;
}

u8 IIC_Wait_Ack()                  //主机等待从机应答         失败:1    成功:0
{
        u8 temptime=0;
        IIC_SDA_IN();
        IIC_SDA_H;
        delay_us(1);                                                  
        IIC_SCL_H;        
        delay_us(1);

        while(GPIO_ReadInputDataBit(GPIO_IIC, IIC_SDA))
        {
                temptime++;
                if(temptime>250)
                {
                        IIC_Stop();
                        return 1;        
                }
        }               
        IIC_SCL_L;
        return 0;        
}


void IIC_Send_Byte(u8 txd)
{
        u8 i=0;
        IIC_SDA_OUT();
        IIC_SCL_L;
        for(i=0;i<8;i++)
        {
                if(txd&0X80>0)
                        IIC_SDA_H;
                else
                        IIC_SDA_L;
                txd<<=1;
                IIC_SCL_H;
                delay_us(2);
                IIC_SCL_L;
                delay_us(2);

        }
}

u8 IIC_Read_Byte(u8 Ack)
{
        u8 i=0;
        u8 receive=0;
        IIC_SDA_IN();
        for(i=0;i<8;i++)
        {        
                 IIC_SCL_L;
                delay_us(2);
                 IIC_SCL_H;
                receive<<=1;
                if(GPIO_ReadInputDataBit(GPIO_IIC, IIC_SDA))
                        receive++;
                delay_us(1);
        }

        if(Ack==0)
                IIC_NAck();
        else
                IIC_Ack();        
        return receive;
}
//******************************AT24C02写入读出**********************//
#include "AT24Cxx.h"


u8 AT24Cxx_ReadOneByte(u16 addr)
{
        u8 temp=0;
        IIC_Start();
        if(EE_TYPE>AT24C16)
        {
                IIC_Send_Byte(0xA0);
                IIC_Wait_Ack();
                IIC_Send_Byte(addr>>8);
               
        }
        else
        {
                IIC_Send_Byte(0xA0+((addr/256)<<1));
               
        }
        IIC_Wait_Ack();
        IIC_Send_Byte(addr%256);
        IIC_Wait_Ack();
        
        IIC_Start();
        IIC_Send_Byte(0xA1);
        IIC_Wait_Ack();
        temp=IIC_Read_Byte(0);
        IIC_NAck();
        IIC_Stop();
        
        return temp;
        
}

u8 AT24Cxx_ReadTwoByte(u16 addr)
{
        u16 temp=0;
        IIC_Start();
        if(EE_TYPE>AT24C16)
        {
                IIC_Send_Byte(0xA0);
                IIC_Wait_Ack();
                IIC_Send_Byte(addr>>8);
               
        }
        else
        {
                IIC_Send_Byte(0xA0+((addr/256)<<1));

        }
        IIC_Wait_Ack();
        IIC_Send_Byte(addr%256);
        IIC_Wait_Ack();
        
        IIC_Start();
        IIC_Send_Byte(0xA1);
        IIC_Wait_Ack();
        temp=IIC_Read_Byte(1);
        temp<<=8;
        temp|=IIC_Read_Byte(0);
        IIC_Stop();
        return temp;        
}

void AT24Cxx_WriteOneByte(u16 addr,u8 dt)
{
        IIC_Start();
        if(EE_TYPE>AT24C16)
        {
                IIC_Send_Byte(0xA0);
                IIC_Wait_Ack();
                IIC_Send_Byte(addr>>8);
               
        }
        else
        {
                IIC_Send_Byte(0xA0+((addr/256)<<1));

        }
        IIC_Wait_Ack();
        IIC_Send_Byte(addr%256);
        IIC_Wait_Ack();
        IIC_Send_Byte(dt);
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(10);
}

void AT24Cxx_WriteTwoByte(u16 addr,u16 dt)
{
        IIC_Start();
        if(EE_TYPE>AT24C16)
        {
                IIC_Send_Byte(0xA0);
                IIC_Wait_Ack();
                IIC_Send_Byte(addr>>8);
               
        }
        else
        {
                IIC_Send_Byte(0xA0+((addr/256)<<1));

        }
        IIC_Wait_Ack();
        IIC_Send_Byte(addr%256);
        IIC_Wait_Ack();
        IIC_Send_Byte(dt>>8);
        IIC_Wait_Ack();
        IIC_Send_Byte(dt&0x0ff);
        IIC_Wait_Ack();
        IIC_Stop();
        delay_ms(10);
}

//****************************printf****************************//
#include "printf.h"
int fputc(int ch,FILE *p)
        {
         USART_SendData(USART1,(u8)ch);
         while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET);
         return ch;
        }

void printf_init()
         {        GPIO_InitTypeDef GPIO_InitStructure;
                 USART_InitTypeDef USART_InitStructure;
                NVIC_InitTypeDef NVIC_InitStructure;
               
                SystemInit();
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
                RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
               
                GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;                                        //tx
                GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
                GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP ;
                GPIO_Init(GPIOA,&GPIO_InitStructure);
               
                GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;                                //rx        
                GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING  ;
                GPIO_Init(GPIOA,&GPIO_InitStructure);

                USART_InitStructure.USART_BaudRate = 9600;
                USART_InitStructure.USART_WordLength = USART_WordLength_8b;
                USART_InitStructure.USART_StopBits = USART_StopBits_1;
                USART_InitStructure.USART_Parity = USART_Parity_No;
                USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None ;
                USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
                USART_Init(USART1, &USART_InitStructure);
               
                USART_Cmd(USART1, ENABLE);
                USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
                USART_ClearFlag(USART1,USART_FLAG_TC);

                NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
                NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
                NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =0;
                NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;
                NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
                NVIC_Init(&NVIC_InitStructure)        ;
}

//******************************main**************************//
#include "systick.h"
#include "public.h"
#include "printf.h"
#include "AT24Cxx.h"


int main()
{
        u8 wdate=16;
        u8 value=0;
        printf_init();
        IIC_init();
        delay_ms(1);


        AT24Cxx_WriteOneByte(0,wdate);
        printf("写入的是:%d\r\n",wdate);
        value=AT24Cxx_ReadOneByte(0);
        printf("读出的是:%d\r\n",value);
        while(1);
}        

最佳答案

查看完整内容[请看2#楼]

特别感谢各位回复,问题已解决。可能因为是板子不同,我的的却是推挽输出。我的问题出在编程上面:写入一个字节中的if(txd&0X80>0)这个条件是错的,正确的是if((txd&0X80)>0). 好坑啊。。。小小问题三四天才解决
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

3

帖子

0

精华

新手入门

积分
17
金钱
17
注册时间
2016-6-23
在线时间
2 小时
 楼主| 发表于 2016-6-23 14:24:52 | 显示全部楼层
特别感谢各位回复,问题已解决。可能因为是板子不同,我的的却是推挽输出。我的问题出在编程上面:写入一个字节中的if(txd&0X80>0)这个条件是错的,正确的是if((txd&0X80)>0).
好坑啊。。。小小问题三四天才解决
回复

使用道具 举报

58

主题

6293

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11442
金钱
11442
注册时间
2014-4-1
在线时间
1290 小时
发表于 2016-6-23 16:56:24 | 显示全部楼层

说明EEPROM在传数据的时候根本没有拉低电平

这句话片面了,
也可能读的过程出错了。


回复

使用道具 举报

20

主题

297

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1828
金钱
1828
注册时间
2013-7-29
在线时间
276 小时
发表于 2016-6-23 19:46:35 | 显示全部楼层
你这是时序不对
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2016-6-23 20:43:25 | 显示全部楼层
I2C的 SDA ,SCL端口应该设置为开漏模式:【这是最关键的!!!】

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  

看看我原来用过的I2C的驱动代码:
#define SCL_H         GPIOB->BSRR = GPIO_Pin_6
#define SCL_L         GPIOB->BRR  = GPIO_Pin_6
   
#define SDA_H         GPIOB->BSRR = GPIO_Pin_7
#define SDA_L         GPIOB->BRR  = GPIO_Pin_7

#define SCL_read      GPIOB->IDR  & GPIO_Pin_6
#define SDA_read      GPIOB->IDR  & GPIO_Pin_7
u8 I2C_Start(void)
{       
        SDA_H;
        SCL_H;
        I2C_delay();
        if(!SDA_read)return FALSE;        //SDA&#207;&#223;&#206;aμíμ&#231;&#198;&#189;&#212;ò×ü&#207;&#223;&#195;|,í&#203;3&#246;
        SDA_L;
        I2C_delay();
        if(SDA_read) return FALSE;        //SDA&#207;&#223;&#206;a&#184;&#223;μ&#231;&#198;&#189;&#212;ò×ü&#207;&#223;3&#246;′í,í&#203;3&#246;
        SDA_L;
        I2C_delay();
        return TRUE;
}

void I2C_Stop(void)
{
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SDA_H;
        I2C_delay();
}

void I2C_Ack(void)
{       
        SCL_L;
        I2C_delay();
        SDA_L;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
}

void I2C_NoAck(void)
{       
        SCL_L;
        I2C_delay();
        SDA_H;
        I2C_delay();
        SCL_H;
        I2C_delay();
        SCL_L;
        I2C_delay();
}

u8 I2C_WaitAck(void)          //·μ&#187;&#216;&#206;a:=1óDACK,=0&#206;TACK
{
        SCL_L;
        I2C_delay();
        SDA_H;                       
        I2C_delay();
        SCL_H;
        I2C_delay();
        if(SDA_read)
        {
      SCL_L;
      return FALSE;
        }
        SCL_L;
        return TRUE;
}

void I2C_SendByte(u8 SendByte) //êy&#190;Y′ó&#184;&#223;&#206;&#187;μ&#189;μí&#206;&#187;//
{
    u8 i=8;
    while(i--)
    {
        SCL_L;
        I2C_delay();
      if(SendByte&0x80)
        SDA_H;  
      else
        SDA_L;   
        SendByte<<=1;
        I2C_delay();
                SCL_H;
        I2C_delay();
    }
    SCL_L;
}

u8 I2C_ReceiveByte(void)  //êy&#190;Y′ó&#184;&#223;&#206;&#187;μ&#189;μí&#206;&#187;//
{
    u8 i=8;
    u8 ReceiveByte=0;

    SDA_H;                               
    while(i--)
    {
      ReceiveByte<<=1;      
      SCL_L;
      I2C_delay();
          SCL_H;
      I2C_delay();       
      if(SDA_read)
      {
        ReceiveByte|=0x01;
      }
    }
    SCL_L;
    return ReceiveByte;
}


回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2016-6-23 20:46:16 | 显示全部楼层
void I2C_delay(void)
{       
   u16 i=500; //这里可以优化速?
   while(i)
   {
     i--;
   }
}


//写入1字节数据       待写入数据    待写入地址       器件类型(24c16等)
u8 I2C_WriteByte(u8 SendByte, u16 WriteAddress, u8 DeviceAddress)
{               
    if(!I2C_Start())return FALSE;
    I2C_SendByte(((WriteAddress & 0x0700) >>7) | DeviceAddress & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
    I2C_SendByte((u8)(WriteAddress & 0x00FF));   //设置低起始地址      
    I2C_WaitAck();       
    I2C_SendByte(SendByte);
    I2C_WaitAck();   
    I2C_Stop();
          //注意:因为这里要等待EEPROM写完,可以采用查询或延时方式(10ms)
    //Systick_Delay_1ms(10);
    OSTimeDly(20);
    return TRUE;
}

//读出1串数据         存放读出数据  待读出长度      待读出地址       器件类型(24c16或SD2403)       
u8 I2C_ReadByte(u8* pBuffer,   u8 length,     u16 ReadAddress,  u8 DeviceAddress)
{               
    if(!I2C_Start())return FALSE;
    I2C_SendByte(((ReadAddress & 0x0700) >>7) | DeviceAddress & 0xFFFE);//设置高起始地址+器件地址
    if(!I2C_WaitAck()){I2C_Stop(); return FALSE;}
    I2C_SendByte((u8)(ReadAddress & 0x00FF));   //设置低起始地址      
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(((ReadAddress & 0x0700) >>7) | DeviceAddress | 0x0001);
    I2C_WaitAck();
    while(length)
    {
      *pBuffer = I2C_ReceiveByte();
      if(length == 1)I2C_NoAck();
      else I2C_Ack();
      pBuffer++;
      length--;
    }
    I2C_Stop();
    return TRUE;
}

回复

使用道具 举报

21

主题

243

帖子

0

精华

初级会员

Rank: 2

积分
137
金钱
137
注册时间
2015-3-12
在线时间
166 小时
发表于 2016-6-24 06:44:56 来自手机 | 显示全部楼层
4楼说的对,检查程序问题。我曾经也遇到过。你直接复制原子哥的程序试试
回复

使用道具 举报

15

主题

172

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1276
金钱
1276
注册时间
2016-5-31
在线时间
499 小时
发表于 2016-6-24 08:50:59 | 显示全部楼层
使用I2C总线,SDA ,SCL端口应该设置为开漏模式,
别忘记在SDA,SCL总线上,连接上拉电阻(4.7K, 10K都可以)。

回复

使用道具 举报

3

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
82
金钱
82
注册时间
2017-1-10
在线时间
19 小时
发表于 2017-7-14 11:15:07 | 显示全部楼层
你好,能给一下头文件吗,我最近也在搞这个,一团糟
回复

使用道具 举报

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

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-1-6 00:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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