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

📄 i2c.lst

📁 继电器和直流小电机正反转控制 ZLG7290键盘与显示控制芯片的控制和使用
💻 LST
字号:
C51 COMPILER V6.12  I2C                                                                    11/06/2008 08:54:19 PAGE 1   


C51 COMPILER V6.12, COMPILATION OF MODULE I2C
OBJECT MODULE PLACED IN .\I2C.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE .\I2C.c DEBUG OBJECTEXTEND

stmt 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 V6.12  I2C                                                                    11/06/2008 08:54:19 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 V6.12  I2C                                                                    11/06/2008 08:54:19 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 V6.12  I2C                                                                    11/06/2008 08:54:19 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 V6.12  I2C                                                                    11/06/2008 08:54:19 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 V6.12  I2C                                                                    11/06/2008 08:54:19 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        =    466    ----
   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 + -