打印

那个大师帮我看这个程序

[复制链接]
1405|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
abc1724|  楼主 | 2014-11-19 11:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
问题:能实现,按键加1,范围在000---255,但是断电后,数据没有保存在AT24c02中;
           以前我用这个i2c总线写Pcf8591是没有问题的。我怀疑是i2c的问题。请大师帮帮我啊
          弄了好几天,就是弄不出来





/**********************************************************************
功能:按键按一下,数值加1(0--255),数码管显示数值,并通过I2C总线把
数值存在,AT24c02.断电后能读存储值。



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

#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8, 0x80,0x90};   //0到9的代码
sbit scl=P0^6;        //i2C时钟线
sbit sda=P0^5;        //不I2c数据线
sbit key=P3^0;        //定义P3.0为按键
/****************************************************************
    名称:        显示延时函数
        功能: 显示延时,以防扫描过快
        输入参数:无
        输出参数:无        
*****************************************************************/
void delay(uchar x)
{
        int n,m;
        for(n=x;n>0;n--)
          for(m=110;m>0;m--);

}
/********************************************************************
        名称:iic延时函数
        功能:使iic正常工作
        输入参数:t
        输出参数:无                
********************************************************************/
void delay_iic( )
{
   ;;;;
}
/******************************************************************
        名称:iic_csh
        功能:释放总线
        输入参数:无
        输出参数:无                       
*********************************************************************/
void iic_csh()
{
   sda=1;
   delay_iic( ) ;
   scl=1;
   delay_iic( ) ;

}
/********************************************************************
        名称:        iic启动信号
        功能:  使iic正常工作
        输入参数:无
        输出参数:无
*********************************************************************/
void iic_start()
{
  sda=1;
  delay_iic( ) ;

  scl=1;
  delay_iic( ) ;

  sda=0;
  delay_iic( ) ;

  }
/**********************************************************************
        名称:iic_stop
        功能: iic        停止信号
        输入参数:无
        输出参数:无

*************************************************************************/
void iic_stop()
{
   sda=0;
   delay_iic( ) ;

   scl=1;
   delay_iic( ) ;

   sda=1;
   delay_iic( ) ;



}
/************************************************************************
    名称:        iic_yd()   应答程序
        功能: 使iic正常工作
        输入参数:无
        输出参数:无
*************************************************************************/
void iic_yd()
{
   uchar cc;
   scl=1;
   delay_iic( ) ;
   while((sda==1)&&(cc<255))
   cc++;
   scl=0;
   delay_iic( ) ;


}
/**************************************************************************
        名称:iic_write(char y)       
        功能: 写数据
        输入参数:y
        输出参数:无                

***************************************************************************/
void  iic_write(uchar y)
{
          uchar i,temp;
          temp=y;
          
          for(i=0;i<8;i++)         //发送一个字节
          {
                    temp=temp<<1;                //左移一位
                  
                  scl=0;                 //低电平其间,允许SDA变化
                  delay_iic( ) ;

                  sda=CY;
                  delay_iic( ) ;

                  scl=1;           //高电平其间,保持数据稳定
                  delay_iic( ) ;
                  
          
          }
           scl=0;                  //释放sda,准备接收应答信号
           delay_iic( ) ;
           sda=1;                 //
           delay_iic( ) ;
            
}
/*********************************************************************
        名称:uchar iic_read()       
        功能: 读数据
        输入参数:y
        输出参数:dat         
***********************************************************************/
uchar iic_read()
{
   uchar bb,k;
   scl=1;
   delay_iic( );

   for(bb=0;bb<8;bb++)           //读一个字节
   {
              scl=1;                //低电平期间,使数sda数据可以改变
           delay_iic( );
           k=k<<1;
           k=k|sda;         //        读取一位数据
           scl=0;
           delay_iic( );
                                                  
   }
   delay_iic( );
        return k;
}
/***************************************************
    名称:void write_add(uchar address,uchar date)       
        功能:向EPROOm写入地址和数据
        输入参数:address,date
        输出参数:无

***************************************************/
void write_add(uchar address,uchar date)
{

  iic_start();
  iic_write(0xa0);
  iic_yd( );

   iic_write(address);        //写片内地址字节
   iic_yd();                                //应答

   iic_write(date);                //写数据
   iic_yd();                   //应答

   iic_stop();           //停止信号



}
/**************************************************
    名称:uchar read_add(uchar address)       
        功能:向EPROOm读出数据
        输入参数:address
        输出参数:date
**************************************************/
uchar read_add(uchar address)
{
  uchar date ;
  iic_start();                  // 启动信号

  iic_write(0xa0);          //写控制地址字节
  iic_yd();                          //应答

  iic_write(address);
  iic_yd();                        //应答

  iic_start();                //重启启动信号

  iic_write(0xa1)        ; //写址址控制字节
  iic_yd();                   //应答

  date=iic_read();          //读数据
  iic_stop();                 //停止信号

  return date;                 //返回数值


}
/***************************************************
   名称:void display(uchar shu)       
        功能:显示读出来的值
        输入参数:shu
        输出参数:无        
*****************************************************/
void display(uchar shu)
{

                  
        P1=0x01;  //个位显示
        P0=table[shu%10];
        delay(5);
        P1=0x00;

        P1=0x02; //十位显示
        P0=table[shu/10%10];
        delay(5);
        P1=0x00;

        P1=0x04;  //百位显示
        P0=table[shu/100];
        delay(5);
        P1=0x00;

}

/****************************************************************************
                     主函数
*****************************************************************************/
void main()
{
        uchar ii;
        iic_csh();
       
        ii=read_add(2);           //进入程序,先读eeprom

         display(ii);          //把读出来的ii值,显示出来

        while(1)
        {
         
         
                 if(key==0) //判断是否有按键按下
                {
              delay(10);  //延时一下  ,消斗
                          if(key==0)        //再判断一下
                      ii++;                  //自加
                         while(!key);
                        if(ii==255)          //起过100重置
                          ii=0;
                  write_add(2,ii);  //把数据存储在3的位置,
                }
       
                  display(ii);  //显示数值
        }



}


相关帖子

沙发
ayb_ice| | 2014-11-19 11:30 | 只看该作者
读要发送应答信号,最后一个字节读要发非应答信号

使用特权

评论回复
评分
参与人数 1威望 +1 收起 理由
abc1724 + 1 赞一个!
板凳
ayb_ice| | 2014-11-19 11:34 | 只看该作者
另外信号时序不严格

每个BIT发送(接收)完成后SCL应为低电平

bit i2c_send(U8 byte)
{
        SDA_OUTPUT();

        U32 d = byte;
        for(U32 i=0; i<8; i++){
                if(d & (0x80 >> i)){                // arm
                        SDA_1();
                }else{
                        SDA_0();
                }
                i2c_delay_da();

                SCL_1();
                i2c_delay_ck1();

                SCL_0();
                i2c_delay_ck0();
        }



U8 i2c_receive(bit ack)
{
    SDA_INPUT();
    U32 temp = 0;
        for(U32 i=0; i<8; i++){
        SCL_1();
        i2c_delay_ck1();
                temp <<= 1;
        if(SDA_IN()){
                        temp++;
                }
        SCL_0();
        i2c_delay_ck0();
    }

使用特权

评论回复
地板
tokuhou| | 2014-11-19 11:37 | 只看该作者
看好数据手册,单片机时钟不一样,频率高了的话,延时要做好,读写速度不要超过器件能随的最大速率

使用特权

评论回复
5
tokuhou| | 2014-11-19 11:37 | 只看该作者
确认好单片机的时钟

使用特权

评论回复
6
mugua521| | 2014-11-19 14:22 | 只看该作者
MARK,火速围观中,学习。。。。

使用特权

评论回复
7
弥勒开怀笑| | 2014-11-19 16:38 | 只看该作者

使用特权

评论回复
8
abc1724|  楼主 | 2014-11-22 00:06 | 只看该作者
ayb_ice 发表于 2014-11-19 11:30
读要发送应答信号,最后一个字节读要发非应答信号

看到了,谢谢了

使用特权

评论回复
9
abc1724|  楼主 | 2014-11-22 00:07 | 只看该作者
tokuhou 发表于 2014-11-19 11:37
看好数据手册,单片机时钟不一样,频率高了的话,延时要做好,读写速度不要超过器件能随的最大速率 ...

嗯,谢了

使用特权

评论回复
10
tokuhou| | 2014-11-22 14:34 | 只看该作者
abc1724 发表于 2014-11-22 00:07
嗯,谢了

是不是读写时序延时的问题?

使用特权

评论回复
11
abc1724|  楼主 | 2014-11-22 17:18 | 只看该作者
tokuhou 发表于 2014-11-22 14:34
是不是读写时序延时的问题?

那个也有问题,还有硬件有问题

使用特权

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

本版积分规则

11

主题

29

帖子

1

粉丝