⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upsd_i2c.lst

📁 Demo for I2C Master and Slave
💻 LST
📖 第 1 页 / 共 5 页
字号:
 412          
 413          This function is used to receive data from master, only for Slave.
 414          
 415          Data_Ptr        - unsigned char*
 416                                  - address pointer of receive buffer
 417          N_Ptr           - unsigned char*
 418                                  - the length of data buffer received from master.
 419           
 420          return value:
 421          
 422          I2C_TIME_OUT    9                       //Indicate I2C overtime.
 423          I2C_SR_END              11                      //Indicate a receiving has been finished in Slave model
 424          I2C_NACK                13                      //Indicate I2C no acknowledge
 425          I2C_BUSLOST             14                      //Indicate I2C bus lost
 426          I2C_SX_APP              15                      //Indicate I2C Slave is required to transmit data to master
 427          I2C_BUSY                16                      //Indicate I2C bus is busy
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 8   

 428          -------------------------------------------------------------------------*/
 429          unsigned char upsd_i2c_Slave_Recv(unsigned char* Data_Ptr,
 430                                                                            unsigned char* N_Ptr)
 431          {
 432   1              EA=0;
 433   1              i2c_rcv_buf=Data_Ptr;
 434   1              i2c_master = 0;  
 435   1              i2c_xmitr = 0;                                  // set up for Slave transmitter
 436   1              i2c_data_index=0;
 437   1              i2c_state=I2C_SR;
 438   1              slave_addressed = 0;            
 439   1              S2CON|=AA;
 440   1      
 441   1      //      idle_mode = 0;                                  // indicate not in idle mode
 442   1      
 443   1      #if IDLE_MODE_DEMO                                  // only here for idle mode demonstration purposes
                      ET0 = 0;                                                // disable timer 0 int. so only I2C int brings uPSD out of idle mode
              //      idle_mode = 1;                                  // indicate in idle mode (I2C init function and ISR clears this flag)
                      PSD8xx_reg.DATAOUT_B&=0xFC;             // PB0 & PB1 = 0 - (LEDs on)
              #endif
 448   1      
 449   1              EA=1;
 450   1      
 451   1      #if IDLE_MODE_DEMO                                  // only here for idle mode demonstration purposes
                      PCON |= 0x01;                                   // puts uPSD in idle mode
                      PSD8xx_reg.DATAOUT_B|=0x03;             // PB0 & PB1 = 1 - (LEDs off)
                      ET0 = 1;                                                // enable timer 0 interrupt
              #endif
 456   1      
 457   1              if(upsd_i2c_Timeout(I2C_SR,1000)==1){
 458   2                      EA=0;
 459   2                      i2c_state=I2C_TIME_OUT;
 460   2                      return(i2c_state); 
 461   2              }                                                                               //Slave receive timeout
 462   1              else {
 463   2                      EA=0;                   
 464   2                      *N_Ptr=i2c_data_index-1;
 465   2                      return(i2c_state);
 466   2              }                                                                                       // Return I2C current state
 467   1      }
 468          /*------------------------------------------------------------------------       
 469          I2C Interrupt Service Routine
 470          ------------------------------------------------------------------------*/ 
 471          
 472          void i2c_isr (void) interrupt I2C_VECTOR using 2 {
 473   1      
 474   1              dummybyte=S2STA;                                                                                        // Clear INTR flag
 475   1              toggle = 0;                                                                                                     // Reset timeout counter
 476   1              //------Master transmit operation--------------------------------------------
 477   1              if (i2c_master & i2c_xmitr)                                                                     // mstr transmitter mode
 478   1              {
 479   2                      S2CON &= ~STA;                                                                                  // clear STA
 480   2                      if ((S2STA & BLOST) !=0)                                                                // if bus lost, read dummybyte to turn to Slave mode
 481   2                      {
 482   3                              S2DAT=dummy;
 483   3                              i2c_state=I2C_BUSLOST;                                                          // Indicate the bus lost
 484   3                              return;
 485   3                      }       
 486   2                      else if ((S2STA & _ACKREP) !=0)
 487   2                      {
 488   3                              S2CON |=STO;
 489   3                              S2DAT=dummy;                                                                            // if no ACK, send STOP condition to Bus
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 9   

 490   3                              i2c_state=I2C_NACK;                                                                     // Indicate no ACK
 491   3                              return;                                                                         
 492   3                      }
 493   2                      if((i2c_data_index)<(i2c_data_len-1))
 494   2                      {
 495   3                              S2DAT = i2c_xmit_buf[i2c_data_index];                           // send data from Master
 496   3                              i2c_data_index++;                                                                       // increment data-pointer
 497   3                      }
 498   2                      else if((i2c_data_index)==(i2c_data_len-1))
 499   2                      {   
 500   3                              S2CON |= STO;                                                                           // set STO (stop bit) for last data byte to send
 501   3                              S2DAT = i2c_xmit_buf[i2c_data_index];                           // send data from Master
 502   3                              i2c_data_index++;                                                       
 503   3                      }
 504   2                      else if((i2c_data_index)==(i2c_data_len))
 505   2                      {
 506   3                              S2DAT=dummy;
 507   3                              i2c_state=I2C_MX_END;                                                           // Indicate the operation has completed
 508   3                      }
 509   2              }
 510   1              //------Master receive operation--------------------------------------------
 511   1              if (i2c_master & ~i2c_xmitr)                                                            // master receive mode
 512   1              {
 513   2                      S2CON &= ~STA;                                                                                  // clear STA
 514   2                      if(i2c_data_index<i2c_data_len)
 515   2                      {
 516   3                              if((S2CON&AA)==0)
 517   3                              {
 518   4                                      S2DAT=dummy;                                                                    //
 519   4                                      if ((dummybyte & _ACKREP) !=0)
 520   4                                      {
 521   5                                              S2CON |=STO;
 522   5                                              i2c_data_index=0;
 523   5                                              S2DAT=dummy;
 524   5                                              i2c_state=I2C_NACK;                                                     // indicate no ACK
 525   5                                              return;                                                                         
 526   5                                      }
 527   4                                      else if(i2c_data_len == 1)
 528   4                                      {
 529   5                                              S2CON&=~AA;
 530   5                                              i2c_data_index ++;
 531   5                                              return;
 532   5                                      }
 533   4                                      else
 534   4                                      {
 535   5                                              S2CON |= AA;                                                            // enable ACK
 536   5                                              i2c_data_index ++;
 537   5                                              return;
 538   5                                      }
 539   4                              }               
 540   3                              else
 541   3                              {
 542   4                                                                                                                                      // Begin receiving data
 543   4                                      i2c_rcv_buf[i2c_data_index-1] = S2DAT;                  // receive data
 544   4                                      i2c_data_index++;                                                               // increment data-pointer
 545   4                                      if(i2c_data_index==i2c_data_len){S2CON&=~AA;}
 546   4                              }
 547   3                      }
 548   2                      else if(i2c_data_index==i2c_data_len)                                   // End the reception of data
 549   2                      {
 550   3                              S2CON |=STO;
 551   3                              i2c_rcv_buf[i2c_data_index-1] = S2DAT;
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 10  

 552   3                              i2c_state=I2C_MR_END;                                                           // indicate operation has completed
 553   3                      }
 554   2              }
 555   1              //------Slave operation--------------------------------------------
 556   1              if(i2c_master==0)
 557   1              { 
 558   2                      if(((S2CON&ADDR)!=0)||!i2c_processing)  // if ADDR bit is set or if coming out of idle
 559   2                      {                                                                           //   mode, then a START and address match detected.
 560   3                              i2c_processing = 1;                                     // indicate processing I2C transaction
 561   3                              S2CON&=~ADDR;                                                                           //Clear ADDR flag
 562   3                              slave_addressed = 1;
 563   3                              if(dummybyte & TX_MODE)
 564   3                              {
 565   4                                      i2c_state=I2C_SX_APP;                                                   // indicate Slave is required to transmit data to master
 566   4                                      S2CON &= ~AA;                                                               // disable ACK
 567   4                                      }
 568   3                              else
 569   3                              {
 570   4                                      S2DAT=dummy;                                                                    // Write dummy
 571   4                                      i2c_xmitr=0;                                                                    // set up for Slave receive
 572   4                                      S2CON |=AA;                                                                     // enable ACK to prepare receive data
 573   4                                      i2c_data_index=0;
 574   4                                      i2c_state=I2C_SR;                                                               // indicate Slave is receiving
 575   4                              }
 576   3                      }
 577   2                      else
 578   2                      {
 579   3                              if(slave_addressed != 1)
 580   3                              {
 581   4                                      return;
 582   4                              }
 583   3                              else if(i2c_xmitr==1)                                                           //Slave transmit data                             
 584   3                              {
 585   4                                      if(((dummybyte&STOP)!=0)||((dummybyte&_ACKREP)!=0)) //if STOP or NACK received, then master
 586   4                                                                                                                                              // is done reading data from slave.
 587   4                                      {       
 588   5                                              S2DAT=dummy;
 589   5                                              i2c_state=I2C_SX_END;                                           // indicate Slave transmitted all data
 590   5      
 591   5                                              i2c_processing = 0;                                             // indicate not processing I2C transaction
 592   5      
 593   5                                      }
 594   4                                      else
 595   4                                      {
 596   5                                              S2DAT = i2c_xmit_buf[i2c_data_index];           // Send data
 597   5                                              i2c_data_index++;                                                       // Increment data-pointer
 598   5                                      }
 599   4                              }
 600   3                              else if(i2c_xmitr==0)                                                           // Slave receive data mode
 601   3                              {
 602   4                              if((dummybyte & STOP)!=0)
 603   4                                      {
 604   5                                              S2DAT = dummy;                                          // STOP bit received while in slave receiver mode
 605   5                                              S2CON &= ~ENI;                                          // This disable/enable I2C is needed for transfers
 606   5                                              S2CON |= ENI;                                           //  from master without data (START-ADDR-WRITE-STOP).
 607   5                                                                                                                      // This type of transfer is used by a master as a
 608   5                                                                                                                      //  type of device detect.  If the slave ACKS, then
 609   5                                                                                                                      //  the device is detected by the master.
 610   5                                              i2c_state = I2C_SR_END;                         // Indicate the data has been received completely 
 611   5      
 612   5                                              i2c_processing = 0;                             // indicate not processing I2C transaction
 613   5      
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 11  

 614   5                                              S2CON &= ~AA;                                           // Disable ACK.
 615   5      
 616   5                                      }
 617   4                                      i2c_rcv_buf[i2c_data_index] = S2DAT;                    // Get data byte from Master
 618   4                                      i2c_data_index++;                                                               // increment data-pointer
 619   4                              }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -