求助PIC18F14K50硬件I2C读写AT24C02问题。

2020-02-06 10:11发布

本帖最后由 liulangmao 于 2013-5-9 22:41 编辑

     目前总线上波形已经接近AT24C02数据手册上写和读的波形了,个人感觉读取应该是没有问题的,只是写入不能成功。调试期间有一将数据写入到了24C02且读了出来,另有一次是在板子重新上电时读出来,其余读出来都不对。
PCB.jpg (470.79 KB, 下载次数: 0) 下载附件 2013-5-9 22:27 上传
PCB图,中间图红星是去掉的电阻。
再不行就只能用模拟的方法了。

部分源代码

  1. void I2C_HD_Init(void)
  2. {
  3.         //MSSP状态寄存器(I2C模式)
  4.         SSPSTAT                                =        0x80;        //压摆率控制位,使用100KHz标准速率,SMBus 选择位,不开启
  5.         SSPADD                                =         0x1D;        //(Fosc/100000)/4 - 1;        //100KHz总线频率 12MHz/100KHz/4-1 = 0x1D;
  6.         SSPCON1                                =        0x28;        //I2C 主模式,时钟 = FOSC/(4 * (SSPADD + 1)),同步串口使能位,开启
  7.         SSPCON2                                =        0x00;        //Clear Control Bits
  8.         DDRBbits.RB4                =        1;                                                //开启SDA和SCL为输入
  9.         DDRBbits.RB6                =        1;         

  10.         PIE1bits.SSPIE                =        1;
  11.        
  12. }

  13. //----------------------------------------I2C写入数据--------------------------------------------
  14. void I2C_HD_Write(void)
  15. {
  16.         SSPCON2bits.SEN        =        1;                        // 1:在SDA 和SCL 引脚上发起启动条件。由硬件自动清零。
  17.         while ( SSPCON2bits.SEN );                //

  18.         SSPBUF        =        0xAE;                                //AT24C02地址1010,A2-A0:111,写入 0.
  19.         while(SSPSTATbits.BF);                        // SSPBUF为空.
  20.        
  21.         SSPCON2bits.ACKDT        =        1;
  22.         SSPCON2bits.ACKEN        =        1;
  23.         while(SSPCON2bits.ACKEN);                //        NotAckI2C1()
  24.                
  25.         Delay_us(1);
  26.                
  27.         SSPBUF        =        0x0F;                                //地址.
  28.         while(SSPSTATbits.BF);                        // SSPBUF为空.
  29.        
  30.         SSPCON2bits.ACKDT        =        1;
  31.         SSPCON2bits.ACKEN        =        1;
  32.         while(SSPCON2bits.ACKEN);                //        NotAckI2C1()
  33.                
  34.         Delay_us(1);
  35.                                
  36.         SSPBUF        =        0x7C;                                //数据124.
  37.         while(SSPSTATbits.BF);                        // SSPBUF为空.

  38.         while(SSPCON2bits.ACKSTAT)                // 收到应答说明器件写操作成功,否则一直查询 。
  39.         {
  40.                 SSPBUF        =        0xAE;                                //AT24C02地址1010,A2-A0:111,写入 0.
  41.                 while(SSPSTATbits.BF);                        // SSPBUF为空.
  42.         }
  43.        
  44. //        Delay_us(1);
  45.        
  46.         SSPCON2bits.ACKDT        =        1;
  47.         SSPCON2bits.ACKEN        =        1;
  48.         while(SSPCON2bits.ACKEN);                //        NotAckI2C1()
  49.                
  50.         //Delay_us(1);
  51.        
  52.         SSPCON2bits.PEN=1;
  53.         while(SSPCON2bits.PEN);                //StopI2C2()  
  54.                
  55.         Delay_us(1);
  56.        
  57. }


  58. //----------------------------------------I2C读取--------------------------------------------
  59. void I2C_HD_Read(void)
  60. {
  61.         SSPCON2bits.SEN        =        1;                        // 1:在SDA 和SCL 引脚上发起启动条件。由硬件自动清零。
  62.         while ( SSPCON2bits.SEN );                //

  63.         SSPBUF        =        0xAE;                                //AT24C02地址1010,A2-A0:111,寻址使用伪写 1.
  64.         while(SSPSTATbits.BF);                        // SSPBUF为空.
  65.                
  66. //        Delay_us(1);
  67.        
  68.         SSPCON2bits.ACKDT        =        1;
  69.         SSPCON2bits.ACKEN        =        1;
  70.         while(SSPCON2bits.ACKEN);                //        NotAckI2C1()
  71.                
  72.         Delay_us(1);
  73.        
  74.         SSPBUF        =        0x0F;                                //地址.
  75.         while(SSPSTATbits.BF);                        // SSPBUF为空.
  76.                
  77.        
  78.         SSPCON2bits.ACKDT        =        1;
  79.         SSPCON2bits.ACKEN        =        1;
  80.         while(SSPCON2bits.ACKEN);                //        NotAckI2C1()

  81.         Delay_us(1);

  82.         SSPCON2bits.SEN        =        1;                        // 1:在SDA 和SCL 引脚上发起启动条件。由硬件自动清零。
  83.         while ( SSPCON2bits.SEN );                //
  84.        
  85.         SSPBUF        =        0xAF;                                //AT24C02地址1010,A2-A0:111,读取 1.
  86.         while(SSPSTATbits.BF);                        // SSPBUF为空.
  87.        
  88.         SSPCON2bits.ACKDT        =        1;
  89.         SSPCON2bits.ACKEN        =        1;
  90.         while(SSPCON2bits.ACKEN);                //        NotAckI2C1()
  91.                
  92.         Delay_us(1);
  93.        
  94.         SSPCON2bits.RCEN        =        1;                //使能接受。
  95.         while(!SSPSTATbits.BF);                        // SSPBUF为满.
  96.        
  97.         SSPCON2bits.ACKDT        =        0;
  98.         SSPCON2bits.ACKEN        =        1;
  99.         while(SSPCON2bits.ACKEN);                //        AckI2C1()
  100.                
  101. //        Delay_us(1);
  102.                
  103.         SSPCON2bits.PEN=1;
  104.         while(SSPCON2bits.PEN);                //StopI2C2()  
  105.        
  106.         Buff_Number        =        SSPBUF;                                //数据123.
  107. }


  108. void interrupt Isr(void)
  109. {
  110.         if(TMR0IF        ==        1)
  111.         {
  112.                 TMR0IF        =        0;
  113.                 LED        =        ~LED;
  114.                 if(LED == 1)
  115.                 {
  116.                         I2C_HD_Write();
  117.                         I2C_HD_Read();
  118.                         Cont_Number = Buff_Number;
  119.                 }
  120.                 else
  121.                 {
  122.                         Cont_Number = 12345;
  123.                 }
  124.                 TMR0H        =        Timer0_RH;
  125.                 TMR0L        =        Timer0_RL;
  126.         }
  127.        
  128.         if(SSPIF        ==        1)
  129.         {
  130.         SSPIF = 0;                                                //清中断。
  131.         }
  132. }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
16条回答
northseawind
2020-02-07 07:19

        while ( SSPCON2bits.SEN );                //

        SSPCON2bits.ACKDT        =        1;
        SSPCON2bits.ACKEN        =        1;

        SSPBUF        =        0xAE;                                //AT24C02地址1010,A2-A0:111,写入 0.
        while(SSPSTATbits.BF);                        // SSPBUF为空.
        while(SSPCON2bits.ACKEN);                //        NotAckI2C1()
               
        Delay_us(1);

感觉有应先改寄存器状态再发送

一周热门 更多>