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

📄 i2c.lst

📁 软件模拟I2C程序,对I2C器件进行读写操作
💻 LST
字号:
C51 COMPILER V7.20   I2C                                                                   07/26/2008 21:59:38 PAGE 1   


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

line level    source

   1          /*****************************************/
   2          /* Copyright (c) 2005, 通信工程学院      */
   3          /* All rights reserved.                  */
   4          /* 作    者:戴 佳                                           */
   5          /*****************************************/
   6          
   7          //#include "I2C.h"
   8          #include <reg52.h>                      // 引用标准库的头文件
   9          #include <intrins.h>
  10          #define uchar unsigned char 
  11          #define uint unsigned int 
  12          
  13          
  14          sbit SDA = P3^2;                        // 串行数据
  15          sbit SCL = P3^3;                        // 串行时钟 原为sbit SCL = P1^0;
  16          
  17          uchar idata SLAdd;              // 从器件地址
  18          uchar idata sbuf[8];            // 数据发送缓冲区
  19          uchar idata rbuf[8];            // 数据接收缓冲区
  20          bit   bdata NACK;               // 器件坏或错误标志位
  21          bit   bdata nackFlag;           // 非应答标志位
  22          
  23          
  24          /* 延时约5微秒,对于12M时钟 */
  25          void delay5us()
  26          {
  27   1              uint i;
  28   1              for (i=0;i<5;i++)
  29   1                      _nop_();        
  30   1      }
  31          
  32          /* 起始条件子函数 */
  33          void start(void)
  34          {
  35   1              SDA = 1;                        // 启动I2C总线
  36   1              SCL = 1;
  37   1              delay5us();
  38   1              SDA = 0;
  39   1              delay5us();
  40   1              SCL = 0;
  41   1      }
  42          
  43          /* 停止条件子函数 */
  44          void stop(void)
  45          {
  46   1              SDA = 0;                        // 停止I2C总线数据传送
  47   1              SCL = 1;
  48   1              delay5us();
  49   1              SDA = 1;
  50   1              delay5us();
  51   1              SCL = 0;
  52   1      }
  53          
  54          /* 发送应答子函数 */
  55          void ack(void)
C51 COMPILER V7.20   I2C                                                                   07/26/2008 21:59:38 PAGE 2   

  56          {
  57   1              SDA = 0;                        // 发送应答位
  58   1              SCL = 1;
  59   1              delay5us();
  60   1              SDA = 1;
  61   1              SCL = 0;
  62   1      }
  63          
  64          /* 发送非应答子函数 */
  65          void n_ack(void)
  66          {
  67   1              SDA = 1;                        // 发送非应答位
  68   1              SCL = 1;
  69   1              delay5us();
  70   1              SDA = 0;
  71   1              SCL = 0;
  72   1      }
  73          
  74          /* 应答位检查子函数 */
  75          void checkack(void)
  76          { 
  77   1              SDA = 1;                // 应答位检查(将p1.0设置成输入,必须先向端口写1)
  78   1              SCL = 1;
  79   1              nackFlag = 0;
  80   1              if(SDA == 1)            // 若SDA=1表明非应答,置位非应答标志F0
  81   1                      nackFlag = 1;
  82   1              SCL = 0;
  83   1      }
  84          
  85          /* 发送一个字节数据子函数 */
  86          void sendbyte(uchar idata *ch)
  87          { 
  88   1              uchar idata n = 8;  
  89   1              uchar idata temp;
  90   1              temp = *ch;
  91   1              while(n--)
  92   1              { 
  93   2                      if((temp&0x80) == 0x80)    // 若要发送的数据最高位为1则发送位1
  94   2                      {
  95   3                              SDA = 1;    // 传送位1
  96   3                              SCL = 1;
  97   3                              delay5us();
  98   3                              SDA = 0;
  99   3                              SCL = 0;    
 100   3                      }
 101   2                      else
 102   2                      {  
 103   3                              SDA = 0;    // 否则传送位0
 104   3                              SCL = 1;
 105   3                              delay5us();
 106   3                              SCL = 0;  
 107   3                      }
 108   2                      temp = temp<<1;    // 数据左移一位
 109   2              }
 110   1      }
 111          
 112          
 113          /* 接收一字节子程序 */
 114          void recbyte(uchar idata *ch)
 115          {
 116   1              uchar idata n=8;    // 从SDA线上读取一位数据字节,共8位
 117   1              uchar idata temp = 0;
C51 COMPILER V7.20   I2C                                                                   07/26/2008 21:59:38 PAGE 3   

 118   1                      
 119   1              while(n--)
 120   1              {   
 121   2              SDA = 1;
 122   2                      SCL = 1;
 123   2                      temp = temp<<1;    // 左移一位
 124   2                      if(SDA == 1)
 125   2                              temp = temp|0x01;    // 若接收到的位为1,则数据的最后一位置1
 126   2                      else 
 127   2                              temp = temp&0xfe;    // 否则数据的最后一位置0
 128   2                      SCL=0;
 129   2              }
 130   1              *ch = temp;
 131   1      }
 132          
 133          /* 发送n字节数据子程序 */
 134          void sendnbyte(uchar idata *sla, uchar n)
 135          {          
 136   1              uchar idata *p;
 137   1              start();                                // 发送启动信号
 138   1              sendbyte(sla);                  // 发送从器件地址字节
 139   1              checkack();                     // 检查应答位
 140   1          if(nackFlag == 1)
 141   1              { 
 142   2                      NACK = 1;
 143   2                      return;                 // 若非应答表明器件错误或已坏,置错误标志位NACK
 144   2              }
 145   1              p = sbuf;
 146   1              while(n--)
 147   1              { 
 148   2                      sendbyte(p);
 149   2                      checkack();     // 检查应答位
 150   2                      if (nackFlag == 1)
 151   2                      {
 152   3                              NACK=1;
 153   3                              return;         // 若非应答表明器件错误或已坏,置错误标志位NACK
 154   3                      }
 155   2                      p++;
 156   2              }
 157   1              stop();                         // 全部发完则停止
 158   1      }
 159          
 160          /* 接收n字节数据子程序 */
 161          void recnbyte(uchar idata *sla, uchar n)
 162          { 
 163   1              uchar idata *p;
 164   1              start();                        // 发送启动信号
 165   1              sendbyte(sla);          // 发送从器件地址字节
 166   1              checkack();                     // 检查应答位
 167   1              if(nackFlag == 1)
 168   1              {
 169   2                      NACK = 1;
 170   2                      return;
 171   2              }
 172   1              p = rbuf;                       // 接收字节存放在rbuf中
 173   1              while(n--)
 174   1              { 
 175   2                      recbyte (p);
 176   2                      ack();                  // 收到一个字节后发送一个应答位
 177   2                      p++;
 178   2              }
 179   1              n_ack();                // 收到最后一个字节后发送一个非应答位
C51 COMPILER V7.20   I2C                                                                   07/26/2008 21:59:38 PAGE 4   

 180   1              stop();
 181   1      }
 182          
 183          /* 主函数,模拟实现I2C总线的数据收发 */
 184          void main(void)
 185          {
 186   1      unsigned long int i,numbyte;
 187   1      
 188   1              numbyte = 8;
 189   1      
 190   1              /* 需发送的8字节数据 */
 191   1              for (i=0;i<numbyte;i++)
 192   1                      sbuf[i] = i+0x11;   //?
 193   1       
 194   1              SLAdd = 0xac;           // 从器件地址
 195   1              
 196   1              sendnbyte(&SLAdd,numbyte);      // 向从器件发送存放在sbuf中的8字节数据
 197   1      
 198   1              for (i=0;i<10000;i++)
 199   1                      delay5us();
 200   1      //     SLAdd++;
 201   1              recnbyte(&SLAdd,numbyte);       // 由从器件接收8字节数据,存放在rbuf中
 202   1      
 203   1              while(1);
 204   1      }
 205          
 206          
 207          
 208          
 209          


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    413    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =   ----       8
   IDATA SIZE       =     17       4
   BIT SIZE         =      2    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

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