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

📄 upsd_i2c.lst

📁 Demo for I2C Master and Slave
💻 LST
📖 第 1 页 / 共 5 页
字号:
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 1   


C51 COMPILER V7.20, COMPILATION OF MODULE UPSD_I2C
OBJECT MODULE PLACED IN uPSD_I2C.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE uPSD_I2C.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          /*------------------------------------------------------------------------
   2          uPSD_I2C.c
   3          
   4          Version:
   5          July 2004 Version 1.0 - Initial release.
   6          
   7          Dependencies:
   8          FREQ_OSC (from upsd_hardware.h) - used in the calculation that
   9          determines the prescaler setting for the I2C bus frequncy.
  10          
  11          Description:
  12          The uPSD I2C device driver is intended to provide a standard interrupt I/O
  13          set of functions for the I2C unit inside the uPSD3200 MCU.  See the
  14          functions below for their respective descriptions.
  15          
  16          Important Notes:
  17          ----------------
  18          - See comments in the upsd_i2c_init() function regarding S2SETUP.
  19          
  20          Known Issues - Slave Mode only:
  21          1. This code has only been tested with a START-ADDR-DATA-STOP sequence.
  22          It is not known if it works with a START-ADDR-DATA-ReSTART sequence.
  23          
  24          2. The ADDR bit in S2CON is not set (assuming there is an address match) 
  25          by H/W when a START-ADDRESS is received on the I2C bus and the uPSD32xx
  26          was in idle mode.  When there is an address match and AA=1, the uPSD32xx
  27          does generate an ACK on the 9th SCL clock.  The processor is also brought
  28          out of idle mode and code execution vectors to the I2C interrupt
  29          service routine (ISR).
  30          
  31          Since the ADDR bit is not set indicating that a START-ADDR was received,
  32          the I2C interrupt will not be processed appropriately.  The ADDR bit is
  33          set appropriately if the uPSD was not in idle mode when a START-ADDR is
  34          received on the I2C bus.
  35          
  36          Solution:
  37          To get around this issue, a S/W flag (i2c_processing) is reset (0) in the
  38          I2C init function.  It is also reset in the ISR when a STOP or NACK is 
  39          received from the master.  It is set in the ISR when the ADDR bit is 
  40          detected as set or if i2c_processing was reset.
  41          
  42          The interrupt service routine (ISR), upon seeing the ADRR bit set or the 
  43          i2c_processing flag reset, processes the interrupt as a START-ADDRESS 
  44          was received.  This solution works well as demonstrated by this example 
  45          code.  
  46          
  47          Limitation of Solution:
  48          This solution has only been tested with a START-ADDR-DATA-STOP sequence.
  49          It is not known if it will work with a START-ADDR-DATA-ReSTART sequence.
  50          
  51          Note:
  52          This demo includes an option to enable or disable compilation of the code
  53          that places the uPSD32xx in idle mode between I2C transfers and between each 
  54          I2C interrupt while in slave mode.  It also turns the DK3200 LEDs, LED ONE 
  55          and LED TWO, on when in idle mode.  See the #define and #if used with 
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 2   

  56          IDLE_MODE_DEMO.  The code that is conditionally compiled with 
  57          IDLE_MODE_DEMO for toggling the LEDs is only for demonstration purposes and
  58          would not normally be included when idle mode is used.
  59          
  60          
  61          Copyright (c) 2004 ST Microelectronics
  62          
  63          This example demo code is provided as is and has no warranty,
  64          implied or otherwise.  You are free to use/modify any of the provided
  65          code at your own risk in your applications with the expressed limitation
  66          of liability (see below) so long as your product using the code contains
  67          at least one uPSD product (device).
  68          
  69          LIMITATION OF LIABILITY:   NEITHER STMicroelectronics NOR ITS VENDORS OR 
  70          AGENTS SHALL BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA,
  71          INTERRUPTION OF BUSINESS, NOR FOR INDIRECT, SPECIAL, INCIDENTAL OR
  72          CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER THIS AGREEMENT OR
  73          OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  74          -------------------------------------------------------------------------*/
  75          
  76          #pragma CODE                                                                                    
  77          #include "upsd3200.h"
  78          #include "upsd_hardware.h"
  79          #include "upsd_i2c.h"
  80          
  81          #define IDLE_MODE_DEMO 0        //0 = don't compile for slave idle mode demo code
  82                                                                  //1 = compile slave idle mode demo code
  83                                                                  //Note: This define is also in upsd_i2c.c file.
  84                                                                  //      This setting must be 0 for Master Mode to
  85                                                                  //       to work.
  86          /*-------------------------------------------------------------------------
  87          Declaration of local variable
  88          -------------------------------------------------------------------------*/
  89          unsigned char* i2c_xmit_buf;                                                    // message transmit buffer address pointer
  90          unsigned char* i2c_rcv_buf;                                                             // message receive buffer address pointer
  91          unsigned char dummybyte;                                                                // dummy byte 
  92          static unsigned char i2c_data_len,i2c_data_index;               // the length and pointer of data buffer 
  93          bit i2c_master, i2c_xmitr;                                                      // callable status flag bits
  94                                                                                                                          // indicate the status of I2C device, Master or Slave, Transmit or receive
  95          static unsigned char i2c_state, slave_addressed;                // the current state of I2C operation
  96          static unsigned int toggle;
  97          
  98          bit     i2c_processing;                                                                         // used to indicate if an I2C transaction is
  99                                                                                                                          //  currently being processed. (0=no, 1=yes)
 100          #if IDLE_MODE_DEMO
              extern PSD_REGS PSD8xx_reg;                                                             // needed for toggling of LED ONE and LED TWO
              #endif
 103          
 104          /*-------------------------------------------------------------------------
 105          upsd_i2c_Timeout(Channel)
 106          
 107          This function is used to indicate if the current I2C operation is overtime.
 108          
 109          operation       - unsigned char         
 110                                  - current I2C operation (I2C_MX/I2C_MR/I2C_SX/I2C_SR).
 111          Max_time        - unsigned int  
 112                                  - the wait time.
 113          return value:
 114          0:      No overtime
 115          1:      Overtime 
 116          -------------------------------------------------------------------------*/
 117          unsigned char upsd_i2c_Timeout(unsigned char operation,unsigned int Max_time)
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 3   

 118          {
 119   1              toggle=0;
 120   1              while(i2c_state==operation)
 121   1              {
 122   2      
 123   2      #if IDLE_MODE_DEMO                                      // Only here for idle mode demonstration in slave mode.
                      EA = 0;                                                         // Disable interrupts.
                      if ((i2c_state == I2C_SR) || (i2c_state == I2C_SX))
                      {
                              ET0 = 0;                                                // disable timer 0 int. so only I2C int brings uPSD out of idle mode
                              PSD8xx_reg.DATAOUT_B&=0xFC;             // PB0 & PB1 = 0 - (LEDs on)
              
                              EA = 1;
              
                              PCON |= 0x01;                                   // puts uPSD in idle mode
                              PSD8xx_reg.DATAOUT_B|=0x03;             // PB0 & PB1 = 1 - (LEDs off)
                              ET0 = 1;                                                // enable timer 0 interrupt
                      }
              #endif
 137   2      
 138   2                      toggle++;
 139   2                      if(toggle>=Max_time)return (1);
 140   2              }
 141   1              return (0);
 142   1      }
 143          
 144          /*-------------------------------------------------------------------------
 145          upsd_i2c_Busycheck(unsigned int Max_time)
 146          
 147          This function is used to detect I2C bus and wait the I2C bus free.
 148          
 149          return value:
 150          0:      I2C bus is free
 151          1:      I2C bus is busy and overtime 
 152          -------------------------------------------------------------------------*/
 153          unsigned char upsd_i2c_Busycheck(unsigned int Max_time)
 154          {
 155   1              unsigned int count;
 156   1              count=0;
 157   1              while ((S2STA & BBUSY) != 0)
 158   1              {
 159   2                      count++;
 160   2                      if(count>=Max_time)return (1);
 161   2              }
 162   1              return (0);
 163   1      }
 164          
 165          /*-------------------------------------------------------------------------
 166          unsigned char upsd_i2c_init (unsigned int Bus_Freq,
 167                                                                   unsigned char Slave_Addr) 
 168          
 169          Important Note:  See comments below regarding the setting for S2SETUP.
 170          
 171          This function is used to initialize the I2C device with indicated 
 172          own device address and Bus Freqency. Must be called before other I2C driver 
 173          function.
 174          
 175          Slave_Addr      - unsigned char         
 176                                  - Slave address of I2C device.
 177          Bus_Freq        - unsigned int  
 178                                  - I2C bus frequency.
 179          
C51 COMPILER V7.20   UPSD_I2C                                                              07/21/2004 16:31:42 PAGE 4   

 180          return value:
 181          0:      initiate successfully 
 182          1:      Error entry parameter
 183          -------------------------------------------------------------------------*/
 184          unsigned char upsd_i2c_init (unsigned int Bus_Freq,
 185                                                           unsigned char Slave_Addr)
 186          {
 187   1          // The following table is mid points of the I2C divisor so that rounding will occur
 188   1          unsigned int code table[10] = {20,27,45,90,180,360,720,1440,0xffff};
 189   1          unsigned char prescaler;
 190   1              unsigned int MCU_Freq_mem, divider;
 191   1      
 192   1              if ((Bus_Freq > 833) || (Bus_Freq < 6))  return (1);    // Bad Requested range
 193   1      
 194   1          MCU_Freq_mem = (unsigned int) FREQ_OSC;                             // Caclualte divider needed
 195   1              MCU_Freq_mem = MCU_Freq_mem >> 1;                                               // Divide Freq_osc by 2
 196   1              divider =  MCU_Freq_mem / Bus_Freq;                      
 197   1          
 198   1          prescaler = 0;
 199   1          while (divider > table[prescaler]) prescaler++;     // Use table to calc best fit prescaler
 200   1          if (prescaler > 7) return(1);                                               // Past max range - bad bus freq
 201   1      

⌨️ 快捷键说明

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