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

📄 i2c.lst

📁 正弦波发生电路如果其他会员下载一次您上载的源码
💻 LST
字号:
C51 COMPILER V8.09   I2C                                                                   11/28/2004 05:44:22 PAGE 1   


C51 COMPILER V8.09, 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                  I2C.c
   3                  标准80C51单片机模拟I2C总线的主机程序
   4                  Copyright (c) 2005,广州周立功单片机发展有限公司
   5                  All rights reserved.
   6                  本程序仅供学习参考,不提供任何可靠性方面的担保;请勿用于商业目的
   7          */
   8          
   9          #include "I2C.h"
  10          
  11          //定义延时变量,用于宏I2C_Delay()
  12          unsigned char data I2C_Delay_t;
  13          
  14          /*
  15          宏定义:I2C_Delay()
  16          功能:延时,模拟I2C总线专用
  17          */
  18          #define I2C_Delay()\
  19          {\
  20                  I2C_Delay_t = (I2C_DELAY_VALUE);\
  21                  while ( --I2C_Delay_t != 0 );\
  22          }
  23          
  24          /*
  25          函数:I2C_Init()
  26          功能:I2C总线初始化,使总线处于空闲状态
  27          说明:在main()函数的开始处,通常应当要执行一次本函数
  28          */
  29          void I2C_Init()
  30          {
  31   1              I2C_SCL = 1;
  32   1              I2C_Delay();
  33   1              I2C_SDA = 1;
  34   1              I2C_Delay();
  35   1      }
  36          
  37          /*
  38          函数:I2C_Start()
  39          功能:产生I2C总线的起始状态
  40          说明:
  41                  SCL处于高电平期间,当SDA出现下降沿时启动I2C总线
  42                  不论SDA和SCL处于什么电平状态,本函数总能正确产生起始状态
  43                  本函数也可以用来产生重复起始状态
  44                  本函数执行后,I2C总线处于忙状态
  45          */
  46          void I2C_Start()
  47          {
  48   1              I2C_SDA = 1;
  49   1              I2C_Delay();
  50   1              I2C_SCL = 1;
  51   1              I2C_Delay();
  52   1              I2C_SDA = 0;
  53   1              I2C_Delay();
  54   1              I2C_SCL = 0;
  55   1              I2C_Delay();
C51 COMPILER V8.09   I2C                                                                   11/28/2004 05:44:22 PAGE 2   

  56   1      }
  57          
  58          /*
  59          函数:I2C_Write()
  60          功能:向I2C总线写1个字节的数据
  61          参数:
  62                  dat:要写到总线上的数据
  63          */
  64          void I2C_Write(char dat)
  65          {
  66   1              unsigned char t = 8;
  67   1              do
  68   1              {
  69   2                      I2C_SDA = (bit)(dat & 0x80);
  70   2                      dat <<= 1;
  71   2                      I2C_SCL = 1;
  72   2                      I2C_Delay();
  73   2                      I2C_SCL = 0;
  74   2                      I2C_Delay();
  75   2              } while ( --t != 0 );
  76   1      }
  77          
  78          /*
  79          函数:I2C_Read()
  80          功能:从从机读取1个字节的数据
  81          返回:读取的一个字节数据
  82          */
  83          char I2C_Read()
  84          {
  85   1              char dat;
  86   1              unsigned char t = 8;
  87   1              I2C_SDA = 1;    //在读取数据之前,要把SDA拉高
  88   1              do
  89   1              {
  90   2                      I2C_SCL = 1;
  91   2                      I2C_Delay();
  92   2                      dat <<= 1;
  93   2                      if ( I2C_SDA ) dat |= 0x01;
  94   2                      I2C_SCL = 0;
  95   2                      I2C_Delay();
  96   2              } while ( --t != 0 );
  97   1              return dat;
  98   1      }
  99          
 100          /*
 101          函数:I2C_GetAck()
 102          功能:读取从机应答位
 103          返回:
 104                  0:从机应答
 105                  1:从机非应答
 106          说明:
 107                  从机在收到每个字节的数据后,要产生应答位
 108                  从机在收到最后1个字节的数据后,一般要产生非应答位
 109          */
 110          bit I2C_GetAck()
 111          {
 112   1              bit ack;
 113   1              I2C_SDA = 1;
 114   1              I2C_Delay();
 115   1              I2C_SCL = 1;
 116   1              I2C_Delay();
 117   1              ack = I2C_SDA;
C51 COMPILER V8.09   I2C                                                                   11/28/2004 05:44:22 PAGE 3   

 118   1              I2C_SCL = 0;
 119   1              I2C_Delay();
 120   1              return ack;
 121   1      }
 122          
 123          /*
 124          函数:I2C_PutAck()
 125          功能:主机产生应答位或非应答位
 126          参数:
 127                  ack=0:主机产生应答位
 128                  ack=1:主机产生非应答位
 129          说明:
 130                  主机在接收完每一个字节的数据后,都应当产生应答位
 131                  主机在接收完最后一个字节的数据后,应当产生非应答位
 132          */
 133          void I2C_PutAck(bit ack)
 134          {
 135   1              I2C_SDA = ack;
 136   1              I2C_Delay();
 137   1              I2C_SCL = 1;
 138   1              I2C_Delay();
 139   1              I2C_SCL = 0;
 140   1              I2C_Delay();
 141   1      }
 142          
 143          /*
 144          函数:I2C_Stop()
 145          功能:产生I2C总线的停止状态
 146          说明:
 147                  SCL处于高电平期间,当SDA出现上升沿时停止I2C总线
 148                  不论SDA和SCL处于什么电平状态,本函数总能正确产生停止状态
 149                  本函数执行后,I2C总线处于空闲状态
 150          */
 151          void I2C_Stop()
 152          {
 153   1              unsigned int t = I2C_STOP_WAIT_VALUE;
 154   1              I2C_SDA = 0;
 155   1              I2C_Delay();
 156   1              I2C_SCL = 1;
 157   1              I2C_Delay();
 158   1              I2C_SDA = 1;
 159   1              I2C_Delay();
 160   1              while ( --t != 0 );             //在下一次产生Start之前,要加一定的延时
 161   1      }
 162          
 163          /*
 164          函数:I2C_Puts()
 165          功能:I2C总线综合发送函数,向从机发送多个字节的数据
 166          参数:
 167                  SlaveAddr:从机地址(7位纯地址,不含读写位)
 168                  SubAddr:从机的子地址
 169                  SubMod:子地址模式,0-无子地址,1-单字节子地址,2-双字节子地址
 170                  *dat:要发送的数据
 171                  Size:数据的字节数
 172          返回:
 173                  0:发送成功
 174                  1:在发送过程中出现异常
 175          说明:
 176                  本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址
 177                  当从机没有子地址时,参数SubAddr任意,而SubMod应当为0
 178          */
 179          bit I2C_Puts
C51 COMPILER V8.09   I2C                                                                   11/28/2004 05:44:22 PAGE 4   

 180          (
 181                  unsigned char SlaveAddr,
 182                  unsigned int SubAddr,
 183                  unsigned char SubMod,
 184                  char *dat,
 185                  unsigned int Size
 186          )
 187          {
 188   1      //定义临时变量
 189   1              unsigned char i;
 190   1              char a[3];
 191   1      //检查长度
 192   1              if ( Size == 0 ) return 0;
 193   1      //准备从机地址
 194   1              a[0] = (SlaveAddr << 1);
 195   1      //检查子地址模式
 196   1              if ( SubMod > 2 ) SubMod = 2;
 197   1      //确定子地址
 198   1              switch ( SubMod )
 199   1              {
 200   2              case 0:
 201   2                      break;
 202   2              case 1:
 203   2                      a[1] = (char)(SubAddr);
 204   2                      break;
 205   2              case 2:
 206   2                      a[1] = (char)(SubAddr >> 8);
 207   2                      a[2] = (char)(SubAddr);
 208   2                      break;
 209   2              default:
 210   2                      break;
 211   2              }
 212   1      //发送从机地址,接着发送子地址(如果有子地址的话)
 213   1              SubMod++;
 214   1              I2C_Start();
 215   1              for ( i=0; i<SubMod; i++ )
 216   1              {
 217   2                      I2C_Write(a[i]);
 218   2                      if ( I2C_GetAck() )
 219   2                      {
 220   3                              I2C_Stop();
 221   3                              return 1;
 222   3                      }
 223   2              }
 224   1      //发送数据
 225   1              do
 226   1              {
 227   2                      I2C_Write(*dat++);
 228   2                      if ( I2C_GetAck() ) break;
 229   2              } while ( --Size != 0 );
 230   1      //发送完毕,停止I2C总线,并返回结果
 231   1              I2C_Stop();
 232   1              if ( Size == 0 )
 233   1              {
 234   2                      return 0;
 235   2              }
 236   1              else
 237   1              {
 238   2                      return 1;
 239   2              }
 240   1      }
 241          
C51 COMPILER V8.09   I2C                                                                   11/28/2004 05:44:22 PAGE 5   

 242          /*
 243          函数:I2C_Gets()
 244          功能:I2C总线综合接收函数,从从机接收多个字节的数据
 245          参数:
 246                  SlaveAddr:从机地址(7位纯地址,不含读写位)
 247                  SubAddr:从机的子地址
 248                  SubMod:子地址模式,0-无子地址,1-单字节子地址,2-双字节子地址
 249                  *dat:保存接收到的数据
 250                  Size:数据的字节数
 251          返回:
 252                  0:接收成功
 253                  1:在接收过程中出现异常
 254          说明:
 255                  本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址
 256                  当从机没有子地址时,参数SubAddr任意,而SubMod应当为0
 257          */
 258          bit I2C_Gets
 259          (
 260                  unsigned char SlaveAddr,
 261                  unsigned int SubAddr,
 262                  unsigned char SubMod,
 263                  char *dat,
 264                  unsigned int Size
 265          )
 266          {
 267   1      //定义临时变量
 268   1              unsigned char i;
 269   1              char a[3];
 270   1      //检查长度
 271   1              if ( Size == 0 ) return 0;
 272   1      //准备从机地址
 273   1              a[0] = (SlaveAddr << 1);
 274   1      //检查子地址模式
 275   1              if ( SubMod > 2 ) SubMod = 2;
 276   1      //如果是有子地址的从机,则要先发送从机地址和子地址
 277   1              if ( SubMod != 0 )
 278   1              {
 279   2              //确定子地址
 280   2                      if ( SubMod == 1 )
 281   2                      {
 282   3                              a[1] = (char)(SubAddr);
 283   3                      }
 284   2                      else
 285   2                      {
 286   3                              a[1] = (char)(SubAddr >> 8);
 287   3                              a[2] = (char)(SubAddr);
 288   3                      }
 289   2              //发送从机地址,接着发送子地址
 290   2                      SubMod++;
 291   2                      I2C_Start();
 292   2                      for ( i=0; i<SubMod; i++ )
 293   2                      {
 294   3                              I2C_Write(a[i]);
 295   3                              if ( I2C_GetAck() )
 296   3                              {
 297   4                                      I2C_Stop();
 298   4                                      return 1;
 299   4                              }
 300   3                      }
 301   2              }
 302   1      //这里的I2C_Start()对于有子地址的从机是重复起始状态
 303   1      //对于无子地址的从机则是正常的起始状态
C51 COMPILER V8.09   I2C                                                                   11/28/2004 05:44:22 PAGE 6   

 304   1              I2C_Start();
 305   1      //发送从机地址
 306   1              I2C_Write(a[0]+1);
 307   1              if ( I2C_GetAck() )
 308   1              {
 309   2                      I2C_Stop();
 310   2                      return 1;
 311   2              }
 312   1      //接收数据
 313   1              for (;;)
 314   1              {
 315   2                      *dat++ = I2C_Read();
 316   2                      if ( --Size == 0 )
 317   2                      {
 318   3                              I2C_PutAck(1);
 319   3                              break;
 320   3                      }
 321   2                      I2C_PutAck(0);
 322   2              }
 323   1      //接收完毕,停止I2C总线,并返回结果
 324   1              I2C_Stop();
 325   1              return 0;
 326   1      }


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    449    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =      1      24
   IDATA SIZE       =   ----    ----
   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 + -