软件模拟I2C总线操作。 (转)

本文介绍了一种使用软件模拟I2C总线的方法,适用于MCS51系列单片机,通过定义数据线SDA和脉冲线SCL实现简单的主从通信。文章提供了C51语言编写的模拟I2C总线的函数,并解释了其工作原理。
AI助手已提取文章相关产品:
软件模拟I2C总线操作。 (转)[@more@]

  在单片机应用中,I2C(I方C)总线一种简单,双向的二线制同步串行总线,它只需要两根串行线,脉冲线,就可以在总线与连接的器件之间传送信息, 它不外乎有以下几个特点:
a.每个连接到总线上的器件都可以进行唯一的寻址,还可建立起简单的主从关系,主器件既可作为发送器,也可作为接收器.
b.它带竞争电路和仲裁电路,可以接收多个主器件发送的数据,而这些数据不会产混乱.
c.同步脉冲可以允许器件可以通过总线以不同的波特率进行通信.
d.因为只有两根线,连接简单,方便.
  对于MCS51系列来讲,内部并没I2C总线接口,在这种情况下,可以采用软件模拟的方法来写出I2C总线的操作,下面我的程序就在开始处定义哪个引脚作为数据线SDA,哪个引脚作为脉冲线,请看我的程序(C51写的,总共有8个函数来模拟I2C总线):
Common.h File
#pragma  LA db SB OE CD OT(SPEED,6)
//LA indicate LARGE Compling Mode-All local and global variables are located in external-ram.
//DB indicate DEbug
//SB indicate SYMBOL
//OE indicate objectEXTEND
//CD indicate CODE  //Generate ASM Code
//OT indicate OPTIMIZATION
#include
#include
#include
#include
#pragma REGPARMS
#pragma SAVE
#define BOOL bit
#define BYTE unsigned char
#define UINT unsigned int
#define ULONG unsigned long
#define HIGH 1
#define LOW 0
#define TRUE 1
#define FALSE 0
#define MAXLONGS  2147483647
#define MINLONGS  -2147483648
#define MAXINTS  32767
#define MININTS  -32768
#define MAXLONGU  4294967295
#define MAXINTU  65535
#define BLOCKLOW 0x0000 //The start-address in AT24C64 is 0x0000
#define BLOCKSIZE 0x20 //Each block is 32 bytes
#define BLOCKNUM  0xC8 //At best 200,Only Save the newest 200 records.
#define BLOCKHIGH 0x18FF//The end-address in AT24C64 is 0x18FF
#define OSC  24000000 //Osillcator Frequency
#define BAUDRATE  9600
#define OTV  256-OSC/12/BAUDRATE/32 //character O represents Obtain,character T represents Timer,character V represents Value
//IMPORTANT ANNOUNCEMENT:I use a word 0x1FFC,0x1FFD to save the next block's address and 0x1FFE,0x1FFF to save the block's no.
sbit GUN=0x85;//PIN P05
sbit SCL=0xFF;  //Undefined bit-address,which will be defined in function:DEFI2C
sbit SDA=0xFF;  //Undefined bit-address,which will be defined in function:DEFI2C
sbit SHKL=0xFF;  //Undefined bit-address,which will be defined in function:DEFI2C
sbit SHKH=0xFF;  //Undefined bit-address,which will be defined in function:DEFI2C
sbit KH0=0xFF;  //Undefined bit-address,which will be defined in function:DEFI2C
sbit KH1=0xFF;  //Undefined bit-address,which will be defined in function:DEFI2C
sbit KH2=0xFF;  //Undefined bit-address,which will be defined in function:DEFI2C
extern void DEFI2C(char *name) //To define which pin is SDA and which pin is SCL
extern void I2CInit()  //Initialization For I2C Bus
extern void I2CStart()  //Start I2C Bus
extern void I2CStop();  //Stop  I2C Bus
extern bit  I2CClock(); //return SDA while SCL is HIGH
extern void I2CDelay(); //Delay
extern void I2CAck();  //Answer
extern bit  I2CSend(BYTE I2CData);//Send data with I2C Bus
extern BYTE I2CReceive();  //Receive data

Common.c
void DEFI2C(char *name)
{
  //Todo:add your codes here....
  //Announcement:If you question me why use the function DEFI2C?
  //Well,the function will be used to define which PIN is SCL and which PIN is SDA,especially there are more than 1 I2C
  //equipment in your circuit.In this sitiuation,we write a function for defining I2C Bus named DEFI2C....
}
void I2CStart()
{
  SCL=HIGH;
  I2CDelay();
  SDA=LOW;
  I2CDelay();
  SCL=LOW;
  I2CDelay();
}
void I2CStop()
{
  SDA=LOW;
  I2CDelay();
  SCL=HIGH;
  I2CDelay();
  SDA=HIGH;
  I2CDelay();
  SCL=LOW;
  I2CDelay();
}
void I2CInit()
{
  SCL=LOW;
  I2CStop();
}
bit I2CClock() //return SDA while SCL is HIGH
{
  bit sample;
  SCL=HIGH;
  I2CDelay();
  sample=SDA;
  SCL=LOW;
  I2CDelay();
  return sample;
}
bit I2CSend(BYTE I2CData)
{
  BYTE i;
  for(i=0;i<8;i++)
  {
  SDA=(bit)(((I2CData) & 0x80) / 0x80) ;
  I2CData=I2CData << 1;
  I2CClock();
  }
  SDA=HIGH;
  return (~I2CClock());
}
void I2CAck()
{
  SDA=LOW;
  I2CClock();
  SDA=HIGH;
}
void I2CDelay()
{
  BYTE ll;
  for(ll=0;ll<100;ll++)
  {
  ;
  }
}
BYTE I2CReceive()
{
  BYTE I2CData=0;
  BYTE kk;
  for(kk=0;kk<8;kk++)
  {
  I2CData*=2;
  if(I2CClock())
  {
  I2CData++;
  }
  }
  return I2CData;
}


上面的代码是用软件来模拟I2C总线,在对特定I2C器件进行操作时,一定要和该器件的时序对应起来才可以,本人从事单片机开发不久,上述程序是去年在北京时写的,如有错误还请各位硬件大侠,前辈给予指教.


来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10752043/viewspace-993456/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/10752043/viewspace-993456/

您可能感兴趣的与本文相关内容

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值