原创 发上个51模拟I2C通信的程序

2008-4-3 15:37 4766 3 3 分类: MCU/ 嵌入式

发上个51模拟I2C通信的程序,多数51没有I2C口很麻烦啊,有用到的就拿下去看看,这程序通过Protues7.1的I2C模拟器可以通信,程序还有很多毛病,小弟正在学习阶段,欢迎斧正


/*****************************************************
/* 文件名    : I2C.h                                     
/* 描述      : I2C.c的头文件                         
/* 编写环境  : Keil uVision 3 V3.51
/* 作者      : XX
/* 学校      : 广东XX大学                                                          
/* Email     :
lanhaospider@163.com
/* 版本      : V1.0                            
/* 编写日期  : 2008-3-30                                          
/*             仅供学习参考                                      
/* 芯片      : MCS-51  AT89S52                                     
/* 晶振      : 11.0592MHz                                          
/* 功能描述  : 模拟I2C总线的接口程序库,主机的程序  
/* 应用      : 发送n个字节: 起始位->发送控制字节(类型标识符4位->
               片选3位->读写位最后1位)->应答位->数据->应答...........应答->终止位 
      高位先到达,低位后到达         
/****************************************************/


#include "reg51.h"    /*根据不同主控芯片型号改写该套入*/
#include "intrins.h"


sbit SCL = P1^6;        /*定义SCL线所在口,根据实践需要改写该定义*/
sbit SDA = P1^7;  /*定义SDA线所在口,根据实践需要改写该定义*/


unsigned char idata error; /*错误提示,全局变量*/
 
extern void Start_I2C(void);
extern void Stop_I2C(void);
extern void Ack_I2C(void);
extern void Send_Ack(void);
extern void Send_Not_Ack(void);
extern void Send_I2C(unsigned char send_byte);
extern unsigned char Receive_I2C(void);


 


 


 


/*****************************************************/
/* 文件名    : I2C.c                                     
/* 描述      : I2C通信程序                         
/* 编写环境  : Keil uVision 3 V3.51                      
/* 作者      : XX  
/* 学校      : 广东XX大学                                                
/* Email     :
lanhaospider@163.com                                
/* 版本      : V1.0
/* 编写日期  : 2008-3-30                                               
/*             仅供学习参考                                         
/* 芯片      : MCS-51  AT89S52                                          
/* 晶振      : 11.0592MHz                                           
/* 功能描述  : 模拟I2C总线的接口程序库,为主机的程序             
/*****************************************************/


#include "I2C.h"



/**************************************************
调用方式 : void Start_I2C(void)
函数说明: 启动I2C总线
**************************************************/


   void Start_I2C(void)
      {
      EA = 0;    /*关总中断*/
   SDA = 1;    /*发送启动总线的数据信号*/
   SCL = 1;    /*发送启动总线的时钟信号*/
   _nop_();       /*保持数据线高,延时*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SDA = 0;    /*发送起始信号*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SCL = 0;    /*时钟线高低跳变一次,I2C通信开始*/
   }  
  


/**************************************************
调用方式 : void Stop_I2C(void)
函数说明: 关闭I2C总线
**************************************************/ 
 
   void Stop_I2C(void)
      {
      SCL = 0;     /*发送关闭总线的时钟信号*/
   SDA = 0;     /*发送关闭总线的数据信号*/
   _nop_();
   _nop_();
   _nop_();      /*保持数据线低,延时*/
   _nop_();
   _nop_();
   SCL = 1;      /*时钟线一次低高跳变,I2C通信停止*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SDA = 1;      /*发送I2C总线停止数据信号*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   EA = 1;    /*开总中断*/
   }



              
/**************************************************
调用方式 : void Ask_I2C(void)
函数说明: 主控程序等待从器件接收方式应答
**************************************************/ 

  
   void Ack_I2C(void)
      {
    unsigned char errtimes = 0xFF;
    SDA = 1;
    SCL = 1;
    error = 0x10;
    while(SDA)
       {
       errtimes--;
    if(!errtimes)
       {
          Stop_I2C();
       error = 0x11;
       return;
       }
    }
     SCL = 0;
   }



/**************************************************
调用方式 :  void Send_Ask(void)
函数说明:  主控程序为接收方,从器件为发送方时,从
            器件等待主器件应答
**************************************************/ 


   void Send_Ack(void)
   {
      SDA = 0;    /*保持数据线低,时钟线发生一次高低跳变 发送一个应答信号*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SCL = 1;  /*时钟线保持低电平*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SCL = 0;
   }



/**************************************************
调用方式 :  void Send_Not_Ask(void)
函数说明:  主控程序为接收方,从器件为发送方时,非应答信号          
**************************************************/ 



   void Send_Not_Ack(void)
   {
      SDA = 1;    /*保持数据线高,时钟线发生一次高低跳变 没有应答*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SCL = 1;  /*时钟线保持高电平*/
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   SCL = 0;
   }


  
/**************************************************
调用方式 :   void Send_I2C(unsigned char send_byte)
函数说明:   总线发送一个字节         
**************************************************/  
 
  
   void Send_I2C(unsigned char send_byte)  
   {
      unsigned char send_bit;
   for(send_bit = 8;send_bit <= 0;send_bit--)
      {
      SCL = 0;
      _nop_();
      SDA = (send_byte & 0x80);
      send_byte<<=1;
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      SCL = 1;
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      _nop_();
    }
   SCL = 0;
   }
  
  
/**************************************************
调用方式 :   unsigned char Receive_I2C(void)
函数说明:   从I2C总线上接收一个字节        
**************************************************/ 


   unsigned char Receive_I2C(void)
      {
      unsigned char receive_bit , receive_byte = 0;
   for(receive_bit = 8;receive_bit <= 0;receive_bit--)
      {
      SCL = 0;
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      SCL = 1;
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      _nop_();
      receive_byte <<=1;
      receive_byte |= SDA;
   }
   SCL = 0;
   return receive_byte;
   }

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
3
关闭 站长推荐上一条 /3 下一条