微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 51单片机控制at24c02的问题

51单片机控制at24c02的问题

时间:10-02 整理:3721RD 点击:
问题:能显示,不能存储是怎么回事啊,我用I2c写pcf8591,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的代码
uchar flag;
sbit scl=P0^6;
sbit sda=P0^5;
sbit key=P3^0;
/***********************************************
名称:i2c_delay()
功能:延时
输入:无
输出:无
*************************************************************/
void i2c_delay()
{
  ; ; ; ;
}
/*********************************************************
              显示延时程序
*******************************************************/
void display_dealy(uchar time)
{
   uchar x,y;
   for(x=time;x>0;x--)
     for(y=100;y>0;y--)        ;

}
/************************************************************
名称:i2c_init()
功能:释放时钟和数据线
输入:无
输出:无
************************************************************/
void i2c_init()
{
  sda=1;
  i2c_delay();
  scl=1;
  i2c_delay();
}
/***********************************************************
名称:i2c_start()
功能:使i2c正常工作
输入:无
输出:无
***********************************************************/
void i2c_start()
{
sda=1;                  //把sda拉高
i2c_delay();  //
scl=1;                  //把数据
i2c_delay();
sda=0;
i2c_delay();
//scl=0;
//i2c_delay();
}
/***********************************************************
名称:i2c_stop()
功能:使i2c正常工作
输入:无
输出:无
***********************************************************/
void i2c_stop()
{
   sda=0;
   i2c_delay();
   scl=1;
   i2c_delay();
   sda=1;
   i2c_delay();
}
/***********************************************************
名称:i2c_ack
功能:使i2c正常工作
输入:无
输出:无
***********************************************************/
void i2c_ack()
{
  sda=0;
  scl=1;
  i2c_delay();
  scl=0;   //应答后把装scl拉低
  sda=1;  //释放总线

}
/***********************************************************
名称:i2c_nack
功能:使i2c正常工作
输入:无
输出:无
***********************************************************/
void i2c_nack()
{
   sda=1;
   scl=1;
   i2c_delay();
   sda=0;
   scl=0;  //把scl纸拉低
}
/***********************************************************
名称:i2c_test_ack
功能:使i2c正常工作
输入:无
输出:无
***********************************************************/
void i2c_test_ack()
{
   scl=1;
   i2c_delay();
   if(sda==1)
     flag=1;  //表示非应答
         scl=0;//把时钟线拉低
}
/***********************************************************
名称:i2c_sendbyte(uchar date)
功能:写数据和命令
输入:date
输出:无
***********************************************************/
void i2c_sendbyte(uchar date)
{
         uchar i,temp;
         
         temp=date;
         for(i=0;i<8;i++)
         {
                   scl=0;
                  i2c_delay();
                  temp=temp<<1;
                  sda=CY;
                  i2c_delay();
                  scl=1;
                  i2c_delay();
         }
         scl=0;
         i2c_delay();
         sda=1;
         i2c_delay();
  }
/***********************************************************
名称:i2c_readbyte()
功能:写数据和命令
输入:date
输出:无
***********************************************************/
uchar i2c_readbyte()
{
        uchar j,x,k;
        for(j=0;j<8;j++)
        {
           scl=0;          //使sda数据发生变化
           i2c_delay();
           x=x<<1;         //把数据左移
           k=sda;           //把sda的值赋给k
           x=x|k;        // 把数据相与
           scl=1;         //使数据操持稳定
           i2c_delay();
        }
        scl=0;
        sda=1;          //释放总线
        scl=1;
        return x;
}
/***********************************************************
名称:i2c_add( uchar address,uchar date  )
功能:写命令与数据
输入:address,date
输出:无
***********************************************************/
void i2c_add(uchar address,uchar date )
{
     i2c_start();          //启动i2c总线
         i2c_sendbyte(0xa0);  //发送芯片近制字节
         i2c_ack();                        //从机响应,为0
         i2c_sendbyte(address);        //发送内存地址字节
         i2c_ack();                         //        从机响应,为0
         i2c_sendbyte(date);  //发送数据字节
         i2c_ack();                   //从机响应,为0
         i2c_stop();        //停止i2c总线

}
/***********************************************************
名称:i2c_readadd( )
功能:写命令与数据
输入:address
输出: y
***********************************************************/
uchar i2c_readadd(uchar address)
{
     uchar y;          //用于存储数据
         i2c_start();          //开启i2c总线
         i2c_sendbyte(0xa0);  //发送芯片控制位
         i2c_ack();                  //从机给个应答,为0
         i2c_sendbyte(address);        //发送存储地址
         i2c_ack();                                //从机给个应答,为0
         i2c_start();                  //重启i2c总线,做好接收准备
         
         i2c_sendbyte(0xa1); //发送读信号
         i2c_ack();                   //从机给个应答为0
         y=i2c_readbyte();          //读取存储器中的值
         i2c_nack();           //主机发送个非应答的信号,为1
         i2c_stop();        //停止数据总线
         return y;                //返回数据
}
/***************************************************
名称:void display(uchar n)
功能:显示数值
输入:n
输出:无
*******************************************************/
void display(uchar n )
{
        P1=0x01;                //个位
        P0=table[n%10];
        display_dealy(5);
        P1=0x00;
        P1=0x02;          //十位
        P0=table[n/10%10];
        display_dealy(5);
        P1=0x00;
        P1=0x04;   //百位
        P0=table[n/100];
        display_dealy(5);
        P1=0x00;

}
void main()
{
   uchar ii;
   i2c_init();
   ii=i2c_readadd(2);          //读取存储器的值
   if(ii==255)         //大过255把数值清0
   ii=0;
   display(ii);         //显示读出来的值
   while(1)
   {
            if(key==0)                  //判断是否有按键 按下
         {
                 display_dealy(30);         //        消抖动
                if(key==0)          //再确认一下有没有按键 按下
                {
                  ii++ ;          //自加1
                  while(!key);          //等待按键松开
                 }
                  if(ii==255)  //当加到255时,把值清0;
                  ii=0;
                }
         i2c_add(2,ii );         //把数据写进存储器
         display(ii);        //显示数值
         
         }
          
   }
         

uchar i2c_readbyte()这个函数里应该是scl下降沿读数据,你的是上升沿,还是写

  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. bit write=0;
  5. sbit sda=P1^0;
  6. sbit scl=P1^1;
  7. sbit d1=P2^4;
  8. sbit d2=P2^5;
  9. sbit d3=P2^6;
  10. sbit d4=P2^7;
  11. uchar code aa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
  12. uchar sec,tcnt;
  13. void delay()
  14. {
  15.         ;
  16.         ;
  17. }
  18. void delayms(uint x)
  19. {
  20.         uint i,j;
  21.         for(i=x;i>0;i--)
  22.                 for(j=110;j>0;j--);
  23. }
  24. void start()
  25. {
  26.         sda=1;
  27.         delay();
  28.         scl=1;
  29.         delay();
  30.         sda=0;
  31.         delay();

  32. }
  33. void stop()
  34. {
  35.         sda=0;
  36.         delay();
  37.         scl=1;
  38.         delay();
  39.         sda=1;
  40.         delay();
  41. }
  42. void respons()
  43. {
  44.         uchar i;
  45.         scl=1;
  46.         delay();
  47.         while((sda==1)&&(i<255))
  48.         i++;
  49.         scl=0;
  50.         delay();
  51. }
  52. void init()
  53. {
  54.         sda=1;
  55.         delay();
  56.         scl=1;
  57.         delay();

  58. //        TMOD=0x01;
  59. //        ET0=1;
  60. //        EA=1;
  61. //        TH0=(65536-50000)/256;
  62. //        TL0=(65536-50000)%256;
  63. }
  64. void write_byte(uchar date)
  65. {
  66.         uchar i,temp;
  67.         temp=date;
  68.         for(i=0;i<8;i++)
  69.         {
  70.                 temp=temp<<1;
  71.                 scl=0;
  72.                 delay();
  73.                 sda=CY;
  74.                 delay();
  75.                 scl=1;
  76.                 delay();
  77.         }
  78.         scl=0;
  79.         delay();
  80.         sda=1;
  81.         delay();
  82. }
  83. uchar read_byte()
  84. {
  85.         uchar i,k;
  86.         scl=0;
  87.         delay();
  88.         sda=1;
  89.         delay();
  90.         for(i=0;i<8;i++)
  91.         {
  92.                 scl=1;
  93.                 delay();
  94.                 k=(k<<1)|sda;
  95.                 scl=0;
  96.                 delay();
  97.         }
  98.         return k;
  99. }
  100. void write_add(uchar address,uchar date)
  101. {
  102.         start();
  103.         write_byte(0xa0);
  104.         respons();
  105.         write_byte(address);
  106.         respons();
  107.         write_byte(date);
  108.         respons();
  109.         stop();
  110. }
  111.         uchar date;
  112. uchar read_add(uchar address)
  113. {
  114.         start();
  115.         write_byte(0xa0);
  116.         respons();
  117.         write_byte(address);
  118.         respons();
  119.         start();
  120.         write_byte(0xa1);
  121.         respons();
  122.         date=read_byte();
  123.         stop();
  124.         return date;
  125. }
  126. void display(uchar bai_c,uchar sh_c,uchar ge_c)
  127. {
  128.         d1=0;
  129.         d1=1;
  130.         P0=aa[bai_c];
  131.         delayms(5);
  132.         d1=0;

  133.         d2=0;
  134.         d2=1;
  135.         P0=aa[sh_c];
  136.         delayms(5);
  137.         d2=0;

  138.         d3=0;
  139.         d3=1;
  140.         P0=aa[ge_c];
  141.         delayms(5);
  142.         d3=0;

  143.         d4=0;
  144. }
  145. void main()
  146. {       
  147.         init();
  148.         sec=read_add(2);
  149.         if(sec>100)
  150.         sec=0;
  151.         TMOD=0x01;
  152.         ET0=1;
  153.         EA=1;
  154.         TH0=(65536-50000)/256;
  155.         TL0=(65536-50000)%256;
  156.         TR0=1;

  157.         while(1)
  158.         {
  159.                 display(sec/100,sec/10%10,sec%10);
  160.                 if(write==1)
  161.                 {
  162.                         write=0;
  163.                         write_add(2,sec);
  164.                 }
  165.         }

  166. }
  167. void t0() interrupt 1
  168. {
  169.         TH0=(65536-50000)/256;
  170.         TL0=(65536-50000)%256;
  171.         tcnt++;
  172.         if(tcnt==20)
  173.         {
  174.                 tcnt=0;
  175.                 sec++;
  176.                 write=1;
  177.                 if(sec==500)
  178.                 sec=0;
  179.         }
  180. }

复制代码

这是我以前学习51时候好使的一个程序,把IO口改一下,好使之后可以加其他的程序比如1602等

#include"i2c.h"
void delay_i2c(uint x)
{
   while(x--);
}
void init_i2c()
{
   scl=1;sda=1;
}
void i2c_start()
{
   sda=1;delay_i2c(1);
   scl=1;delay_i2c(1);
   sda=0;delay_i2c(1);
}
void i2c_stop()
{
   sda=0;delay_i2c(1);
   scl=1;delay_i2c(1);
   sda=1;delay_i2c(1);
}
void i2c_ACK()
{
   uchar i;
   scl=0;delay_i2c(1);
   scl=1;delay_i2c(1);
   while((sda==1)&&(i<254))
   {i++;}
   scl=0;delay_i2c(1);
}
void write_byte(uchar date)
{
   uchar temp;
   uchar i;
   temp=date;
   for(i=0;i<8;i++)
   {
      temp=temp<<1;
          scl=0;delay_i2c(1);
          sda=CY;delay_i2c(1);
          scl=1;delay_i2c(1);
   }
   scl=0;delay_i2c(1);
   sda=1;delay_i2c(1);
}
uchar read_byte()
{
   uchar i,k=0;
   scl=0;delay_i2c(1);
   sda=1;
   for(i=0;i<8;i++)
   {
      scl=1;delay_i2c(1);
          k=k<<1|sda;
          delay_i2c(1);
          scl=0;delay_i2c(1);
   }
  return k;
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top