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

📄 i2c.lst

📁 利用键盘显示专用驱动芯片7290
💻 LST
字号:
C51 COMPILER V7.50   I2C                                                                   07/20/2007 15:38:41 PAGE 1   


C51 COMPILER V7.50, COMPILATION OF MODULE I2C
OBJECT MODULE PLACED IN .\I2C.obj
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE F:\0217\新建文件夹2\I2C.c BROWSE INTVECTOR(0X8000) DEBUG OBJECTEXTEND PRINT
                    -(.\I2C.lst) OBJECT(.\I2C.obj)

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            
  13          unsigned char data I2C_Delay_t; 
  14           
  15          /* 
  16          宏定义:I2C_Delay() 
  17          功能:延时,模拟I2C总线专用 
  18          */ 
  19          #define I2C_Delay()\ 
  20          {\ 
  21            I2C_Delay_t = (I2C_DELAY_VALUE);\ 
  22            while ( --I2C_Delay_t != 0 );\ 
  23          } 
  24           
  25          /* 
  26          函数:I2C_Init() 
  27          功能:I2C总线初始化,使总线处于空闲状态 
  28          说明:在main()函数的开始处,通常应当要执行一次本函数 
  29          */ 
  30          void I2C_Init() 
  31          { 
  32   1        I2C_SCL = 1; 
  33   1       I2C_Delay(); 
  34   1        I2C_SDA = 1; 
  35   1       I2C_Delay(); 
  36   1      } 
  37           
  38          /* 
  39          函数:I2C_Start() 
  40          功能:产生I2C总线的起始状态 
  41          说明: 
  42           SCL处于高电平期间,当SDA出现下降沿时启动I2C总线 
  43            不论SDA 和SCL处于什么电平状态,本函数总能正确产生起始状态 
  44            本函数也可以用来产生重复起始状态 
  45            本函数执行后,I2C总线处于忙状态 
  46          */ 
  47          void I2C_Start() 
  48          { 
  49   1        I2C_SDA = 1; 
  50   1       I2C_Delay(); 
  51   1        I2C_SCL = 1; 
  52   1       I2C_Delay(); 
  53   1        I2C_SDA = 0; 
  54   1       I2C_Delay(); 
C51 COMPILER V7.50   I2C                                                                   07/20/2007 15:38:41 PAGE 2   

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

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

 179          说明: 
 180            本函数能够很好地适应所有常见的I2C器件,不论其是否有子地址 
 181            当从机没有子地址时,参数SubAddr任意,而SubMod应当为0 
 182          */ 
 183          bit I2C_Puts 
 184          ( 
 185            unsigned char SlaveAddr, 
 186            unsigned int SubAddr, 
 187            unsigned char SubMod, 
 188            char *dat, 
 189            unsigned int Size 
 190          ) 
 191          { 
 192   1       
 193   1      //定义临时变量 
 194   1        unsigned char i; 
 195   1        char a[3]; 
 196   1      //检查长度 
 197   1        if ( Size == 0 ) return 0; 
 198   1      //准备从机地址 
 199   1        a[0] = (SlaveAddr << 1); 
 200   1      //检查子地址模式 
 201   1        if ( SubMod > 2 ) SubMod = 2; 
 202   1      //确定子地址 
 203   1        switch ( SubMod ) 
 204   1       { 
 205   2        case 0: 
 206   2         break; 
 207   2        case 1: 
 208   2        a[1] = (char)(SubAddr); 
 209   2         break; 
 210   2        case 2: 
 211   2        a[1] = (char)(SubAddr >> 8); 
 212   2        a[2] = (char)(SubAddr); 
 213   2         break; 
 214   2        default: 
 215   2         break; 
 216   2       } 
 217   1      //发送从机地址,接着发送子地址(如果有子地址的话) 
 218   1       SubMod++; 
 219   1       I2C_Start(); 
 220   1        for ( i=0; i<SubMod; i++ ) 
 221   1       { 
 222   2        I2C_Write(a[i]); 
 223   2         if ( I2C_GetAck() ) 
 224   2        { 
 225   3         I2C_Stop(); 
 226   3          return 1; 
 227   3        } 
 228   2       } 
 229   1      //发送数据 
 230   1        do 
 231   1       { 
 232   2        I2C_Write(*dat++); 
 233   2         if ( I2C_GetAck() ) break; 
 234   2       } while ( --Size != 0 ); 
 235   1      //发送完毕,停止I2C总线,并返回结果 
 236   1       I2C_Stop(); 
 237   1       
 238   1        if ( Size == 0 ) 
 239   1       { 
 240   2         return 0; 
C51 COMPILER V7.50   I2C                                                                   07/20/2007 15:38:41 PAGE 5   

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

 303   3         { 
 304   4          I2C_Stop(); 
 305   4           return 1; 
 306   4         } 
 307   3        } 
 308   2       } 
 309   1      //这里的I2C_Start()对于有子地址的从机是重复起始状态 
 310   1      //对于无子地址的从机则是正常的起始状态 
 311   1       I2C_Start(); 
 312   1      //发送从机地址 
 313   1       I2C_Write(a[0]+1); 
 314   1        if ( I2C_GetAck() ) 
 315   1       { 
 316   2        I2C_Stop(); 
 317   2         return 1; 
 318   2       } 
 319   1      //接收数据 
 320   1        for (;;) 
 321   1       { 
 322   2        *dat++ = I2C_Read(); 
 323   2         if ( --Size == 0 ) 
 324   2        { 
 325   3         I2C_PutAck(1); 
 326   3          break; 
 327   3       
 328   3        } 
 329   2        I2C_PutAck(0); 
 330   2       } 
 331   1      //接收完毕,停止I2C总线,并返回结果 
 332   1       I2C_Stop(); 
 333   1        return 0; 
 334   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 + -