VIIC_C51.LST
上传用户:ids068
上传日期:2013-04-04
资源大小:639k
文件大小:14k
源码类别:

USB编程

开发平台:

C/C++

  1. C51 COMPILER V7.06   VIIC_C51                                                              07/02/2003 09:29:12 PAGE 1   
  2. C51 COMPILER V7.06, COMPILATION OF MODULE VIIC_C51
  3. OBJECT MODULE PLACED IN VIIC_C51.OBJ
  4. COMPILER INVOKED BY: C:KEILC51BINC51.EXE VIIC_C51.c OPTIMIZE(2,SPEED) BROWSE DEBUG OBJECTEXTEND
  5. stmt level    source
  6.    1          /********************************************************************
  7.    2                                 VIIC_C51.C
  8.    3            此程序是I2C操作平台(主方式的软件平台)的底层的C子程序,如发送数据
  9.    4          及接收数据,应答位发送,并提供了几个直接面对器件的操作函数,它很方便的
  10.    5          与用户程序连接并扩展.....  
  11.    6            
  12.    7              注意:函数是采用软件延时的方法产生SCL脉冲,固对高晶振频率要作 
  13.    8          一定的修改....(本例是1us机器周期,即晶振频率要小于12MHZ)
  14.    9          
  15.   10          ********************************************************************/
  16.   11            
  17.   12            
  18.   13                        
  19.   14          #include <reg52.h>          /*头文件的包含*/
  20.   15          #include <intrins.h>
  21.   16          
  22.   17          #define  uchar unsigned char /*宏定义*/
  23.   18          #define  uint  unsigned int
  24.   19          
  25.   20          #define  _Nop()  _nop_()        /*定义空指令*/
  26.   21          
  27.   22          /* 常,变量定义区 */
  28.   23           
  29.   24                                                           /*端口位定义*/
  30.   25          sbit SDA=P1^7;            /*模拟I2C数据传送位*/
  31.   26          sbit SCL=P1^6;            /*模拟I2C时钟控制位*/
  32.   27          
  33.   28                                                           /*状态标志*/
  34.   29          bit ack;                 /*应答标志位*/
  35.   30             
  36.   31          
  37.   32          
  38.   33          
  39.   34          
  40.   35          
  41.   36          /*******************************************************************
  42.   37                               起动总线函数               
  43.   38          函数原型: void  Start_I2c();  
  44.   39          功能:       启动I2C总线,即发送I2C起始条件.
  45.   40            
  46.   41          ********************************************************************/
  47.   42          void Start_I2c()
  48.   43          {
  49.   44   1        SDA=1;   /*发送起始条件的数据信号*/
  50.   45   1        _Nop();
  51.   46   1        SCL=1;
  52.   47   1        _Nop();    /*起始条件建立时间大于4.7us,延时*/
  53.   48   1        _Nop();
  54.   49   1        _Nop();
  55.   50   1        _Nop();
  56.   51   1        _Nop();    
  57.   52   1        SDA=0;   /*发送起始信号*/
  58.   53   1        _Nop();    /* 起始条件锁定时间大于4μs*/
  59.   54   1        _Nop();
  60.   55   1        _Nop();
  61. C51 COMPILER V7.06   VIIC_C51                                                              07/02/2003 09:29:12 PAGE 2   
  62.   56   1        _Nop();
  63.   57   1        _Nop();       
  64.   58   1        SCL=0;   /*钳住I2C总线,准备发送或接收数据 */
  65.   59   1        _Nop();
  66.   60   1        _Nop();
  67.   61   1      }
  68.   62          
  69.   63          
  70.   64          
  71.   65          
  72.   66          /*******************************************************************
  73.   67                                结束总线函数               
  74.   68          函数原型: void  Stop_I2c();  
  75.   69          功能:       结束I2C总线,即发送I2C结束条件.
  76.   70            
  77.   71          ********************************************************************/
  78.   72          void Stop_I2c()
  79.   73          {
  80.   74   1        SDA=0;  /*发送结束条件的数据信号*/
  81.   75   1        _Nop();   /*发送结束条件的时钟信号*/
  82.   76   1        SCL=1;  /*结束条件建立时间大于4μs*/
  83.   77   1        _Nop();
  84.   78   1        _Nop();
  85.   79   1        _Nop();
  86.   80   1        _Nop();
  87.   81   1        _Nop();
  88.   82   1        SDA=1;  /*发送I2C总线结束信号*/
  89.   83   1        _Nop();
  90.   84   1        _Nop();
  91.   85   1        _Nop();
  92.   86   1        _Nop();
  93.   87   1      }
  94.   88          
  95.   89          
  96.   90          
  97.   91          
  98.   92          /*******************************************************************
  99.   93                           字节数据传送函数               
  100.   94          函数原型: void  SendByte(uchar c);
  101.   95          功能:  将数据c发送出去,可以是地址,也可以是数据,发完后等待应答,并对
  102.   96               此状态位进行操作.(不应答或非应答都使ack=0 假)     
  103.   97               发送数据正常,ack=1; ack=0表示被控器无应答或损坏。
  104.   98          ********************************************************************/
  105.   99          void  SendByte(uchar c)
  106.  100          {
  107.  101   1       uchar BitCnt;
  108.  102   1       
  109.  103   1       for(BitCnt=0;BitCnt<8;BitCnt++)  /*要传送的数据长度为8位*/
  110.  104   1          {
  111.  105   2           if((c<<BitCnt)&0x80)SDA=1;   /*判断发送位*/
  112.  106   2             else  SDA=0;                
  113.  107   2           _Nop();
  114.  108   2           SCL=1;               /*置时钟线为高,通知被控器开始接收数据位*/
  115.  109   2            _Nop(); 
  116.  110   2            _Nop();               /*保证时钟高电平周期大于4μs*/
  117.  111   2            _Nop();
  118.  112   2            _Nop();
  119.  113   2            _Nop();         
  120.  114   2           SCL=0; 
  121.  115   2          }
  122.  116   1          
  123.  117   1          _Nop();
  124. C51 COMPILER V7.06   VIIC_C51                                                              07/02/2003 09:29:12 PAGE 3   
  125.  118   1          _Nop();
  126.  119   1          SDA=1;               /*8位发送完后释放数据线,准备接收应答位*/
  127.  120   1          _Nop();
  128.  121   1          _Nop();   
  129.  122   1          SCL=1;
  130.  123   1          _Nop();
  131.  124   1          _Nop();
  132.  125   1          _Nop();
  133.  126   1          if(SDA==1)ack=0;     
  134.  127   1             else ack=1;        /*判断是否接收到应答信号*/
  135.  128   1          SCL=0;
  136.  129   1          _Nop();
  137.  130   1          _Nop();
  138.  131   1      }
  139.  132          
  140.  133          
  141.  134          
  142.  135          
  143.  136          
  144.  137          
  145.  138          /*******************************************************************
  146.  139                           字节数据传送函数               
  147.  140          函数原型: uchar  RcvByte();
  148.  141          功能:  用来接收从器件传来的数据,并判断总线错误(不发应答信号),
  149.  142               发完后请用应答函数。  
  150.  143          ********************************************************************/   
  151.  144          uchar  RcvByte()
  152.  145          {
  153.  146   1        uchar retc;
  154.  147   1        uchar BitCnt;
  155.  148   1        
  156.  149   1        retc=0; 
  157.  150   1        SDA=1;             /*置数据线为输入方式*/
  158.  151   1        for(BitCnt=0;BitCnt<8;BitCnt++)
  159.  152   1            {
  160.  153   2              _Nop();           
  161.  154   2              SCL=0;       /*置时钟线为低,准备接收数据位*/
  162.  155   2              _Nop();
  163.  156   2              _Nop();         /*时钟低电平周期大于4.7μs*/
  164.  157   2              _Nop();
  165.  158   2              _Nop();
  166.  159   2              _Nop();
  167.  160   2              SCL=1;       /*置时钟线为高使数据线上数据有效*/
  168.  161   2              _Nop();
  169.  162   2              _Nop();
  170.  163   2              retc=retc<<1;
  171.  164   2              if(SDA==1)retc=retc+1; /*读数据位,接收的数据位放入retc中 */
  172.  165   2              _Nop();
  173.  166   2              _Nop(); 
  174.  167   2            }
  175.  168   1        SCL=0;    
  176.  169   1        _Nop();
  177.  170   1        _Nop();
  178.  171   1        return(retc);
  179.  172   1      }
  180.  173          
  181.  174          
  182.  175          
  183.  176          
  184.  177          /********************************************************************
  185.  178                               应答子函数
  186.  179          原型:  void Ack_I2c(bit a);
  187. C51 COMPILER V7.06   VIIC_C51                                                              07/02/2003 09:29:12 PAGE 4   
  188.  180           
  189.  181          功能:主控器进行应答信号,(可以是应答或非应答信号)
  190.  182          ********************************************************************/
  191.  183          void Ack_I2c(bit a)
  192.  184          {
  193.  185   1        
  194.  186   1        if(a==0)SDA=0;     /*在此发出应答或非应答信号 */
  195.  187   1              else SDA=1;
  196.  188   1        _Nop();
  197.  189   1        _Nop();
  198.  190   1        _Nop();      
  199.  191   1        SCL=1;
  200.  192   1          _Nop();
  201.  193   1          _Nop();              /*时钟低电平周期大于4μs*/
  202.  194   1          _Nop();
  203.  195   1          _Nop();
  204.  196   1          _Nop();  
  205.  197   1       SCL=0;                /*清时钟线,钳住I2C总线以便继续接收*/
  206.  198   1          _Nop();
  207.  199   1          _Nop();    
  208.  200   1      }
  209.  201          
  210.  202          
  211.  203          
  212.  204          
  213.  205          
  214.  206          
  215.  207          /*******************************************************************
  216.  208                              向无子地址器件发送字节数据函数               
  217.  209          函数原型: bit  ISendByte(uchar sla,ucahr c);  
  218.  210          功能:     从启动总线到发送地址,数据,结束总线的全过程,从器件地址sla.
  219.  211                     如果返回1表示操作成功,否则操作有误。
  220.  212          注意:    使用前必须已结束总线。
  221.  213          ********************************************************************/
  222.  214          bit ISendByte(uchar sla,uchar c)
  223.  215          {
  224.  216   1         Start_I2c();               /*启动总线*/
  225.  217   1         SendByte(sla);            /*发送器件地址*/
  226.  218   1           if(ack==0)return(0);
  227.  219   1         SendByte(c);               /*发送数据*/
  228.  220   1           if(ack==0)return(0);
  229.  221   1        Stop_I2c();                 /*结束总线*/ 
  230.  222   1        return(1);
  231.  223   1      }
  232.  224          
  233.  225          
  234.  226          
  235.  227          
  236.  228          /*******************************************************************
  237.  229                              向有子地址器件发送多字节数据函数               
  238.  230          函数原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
  239.  231          功能:     从启动总线到发送地址,子地址,数据,结束总线的全过程,从器件
  240.  232                    地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
  241.  233                     如果返回1表示操作成功,否则操作有误。
  242.  234          注意:    使用前必须已结束总线。
  243.  235          ********************************************************************/
  244.  236          bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no)
  245.  237          {
  246.  238   1         uchar i;
  247.  239   1      
  248.  240   1         Start_I2c();               /*启动总线*/
  249.  241   1         SendByte(sla);            /*发送器件地址*/
  250. C51 COMPILER V7.06   VIIC_C51                                                              07/02/2003 09:29:12 PAGE 5   
  251.  242   1           if(ack==0)return(0);
  252.  243   1         SendByte(suba);            /*发送器件子地址*/
  253.  244   1           if(ack==0)return(0);
  254.  245   1      
  255.  246   1         for(i=0;i<no;i++)
  256.  247   1          {   
  257.  248   2           SendByte(*s);               /*发送数据*/
  258.  249   2             if(ack==0)return(0);
  259.  250   2           s++;
  260.  251   2          } 
  261.  252   1       Stop_I2c();                 /*结束总线*/ 
  262.  253   1        return(1);
  263.  254   1      }
  264.  255          
  265.  256          
  266.  257          
  267.  258          
  268.  259          
  269.  260          
  270.  261          /*******************************************************************
  271.  262                              向无子地址器件读字节数据函数               
  272.  263          函数原型: bit  IRcvByte(uchar sla,ucahr *c);  
  273.  264          功能:     从启动总线到发送地址,读数据,结束总线的全过程,从器件地
  274.  265                    址sla,返回值在c.
  275.  266                     如果返回1表示操作成功,否则操作有误。
  276.  267          注意:    使用前必须已结束总线。
  277.  268          ********************************************************************/
  278.  269          bit IRcvByte(uchar sla,uchar *c)
  279.  270          {
  280.  271   1         Start_I2c();                /*启动总线*/
  281.  272   1         SendByte(sla+1);           /*发送器件地址*/
  282.  273   1           if(ack==0)return(0);
  283.  274   1         *c=RcvByte();               /*读取数据*/
  284.  275   1           Ack_I2c(1);               /*发送非就答位*/
  285.  276   1        Stop_I2c();                  /*结束总线*/ 
  286.  277   1        return(1);
  287.  278   1      }
  288.  279          
  289.  280          
  290.  281          
  291.  282          /*******************************************************************
  292.  283                              向有子地址器件读取多字节数据函数               
  293.  284          函数原型: bit  ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);  
  294.  285          功能:     从启动总线到发送地址,子地址,读数据,结束总线的全过程,从器件
  295.  286                    地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
  296.  287                     如果返回1表示操作成功,否则操作有误。
  297.  288          注意:    使用前必须已结束总线。
  298.  289          ********************************************************************/
  299.  290          bit IRcvStr(uchar sla,uchar suba,uchar *s,uchar no)
  300.  291          {
  301.  292   1         uchar i;
  302.  293   1      
  303.  294   1         Start_I2c();               /*启动总线*/
  304.  295   1         SendByte(sla);            /*发送器件地址*/
  305.  296   1           if(ack==0)return(0);
  306.  297   1         SendByte(suba);            /*发送器件子地址*/
  307.  298   1           if(ack==0)return(0);
  308.  299   1      
  309.  300   1         Start_I2c();
  310.  301   1         SendByte(sla+1);
  311.  302   1            if(ack==0)return(0);
  312.  303   1      
  313. C51 COMPILER V7.06   VIIC_C51                                                              07/02/2003 09:29:12 PAGE 6   
  314.  304   1         for(i=0;i<no-1;i++)
  315.  305   1          {   
  316.  306   2           *s=RcvByte();               /*发送数据*/
  317.  307   2            Ack_I2c(0);                /*发送就答位*/  
  318.  308   2           s++;
  319.  309   2          } 
  320.  310   1         *s=RcvByte();
  321.  311   1          Ack_I2c(1);                 /*发送非应位*/
  322.  312   1       Stop_I2c();                    /*结束总线*/ 
  323.  313   1        return(1);
  324.  314   1      }
  325.  315          
  326.  316          
  327.  317          
  328.  318          
  329.  319          
  330.  320          
  331.  321                                  /*    完毕      */
  332.  322          
  333.  323          
  334.  324          
  335.  325          
  336. MODULE INFORMATION:   STATIC OVERLAYABLE
  337.    CODE SIZE        =    465    ----
  338.    CONSTANT SIZE    =   ----    ----
  339.    XDATA SIZE       =   ----    ----
  340.    PDATA SIZE       =   ----    ----
  341.    DATA SIZE        =   ----      24
  342.    IDATA SIZE       =   ----    ----
  343.    BIT SIZE         =      1       1
  344. END OF MODULE INFORMATION.
  345. C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)