haichao_xjtu的个人空间 https://blog.eetop.cn/506772 [收藏] [复制] [分享] [RSS]

空间首页 动态 记录 日志 相册 主题 分享 留言板 个人资料

日志

利用8051实现I2C主机功能

已有 2928 次阅读| 2011-6-13 20:25

根据I2C协议,本人写的符合协议的代码,已经在8051上面挂了一个I2C从机,测试通过,使用逻辑分析仪来分析数据,结果表明符合,符合协议内容。。贴出代码,供大家交流,共同进步。。。
适合于普通模式,主机的时钟频率大概在120K左右。。
因为是C语言,对时间的控制不是很精确。。。

 #include "reg51.h"
#include "intrins.h"
sbit SCL= P1^7;             
sbit SDA= P1^6;             
void Start_I2C(void)
{
SDA=1;                      
SCL=1;                      
_nop_();                    
_nop_();    
_nop_();
_nop_();

SDA=0;                      
_nop_();                   
 _nop_();  
_nop_();
_nop_();  
_nop_();
SCL=0;                     
}
 
void Stop_I2C (void)
{                     
SDA=0;                      
SCL=1;                      
_nop_();                   
_nop_();  
_nop_();
_nop_();
_nop_();

SDA=1;                      
_nop_();                    
_nop_();    
_nop_();
_nop_();
_nop_();
}
 
bit SendAck(void)
{
SDA=0;                 
_nop_();                
_nop_();  
_nop_();
_nop_();
_nop_();

SCL=1;
_nop_();                  
_nop_();    
_nop_();
_nop_();
_nop_();
SCL=0;
return(1);
}
 
bit DetectAck(void) 
unsigned char errtime = 255;  
 SDA = 1; 
 SCL = 1; 
_nop_(); 
_nop_();
_nop_(); 
_nop_(); 
 while(SDA) 
 { 
     errtime--; 
     if(errtime==0) 
        { 
          Stop_I2C(); 
          return(0); 
         } 
 } 
 SCL = 0; 
_nop_(); 
 return(1); 

void Send_I2C (unsigned char ch)
{
   
unsigned char i;
for (i=0;i<8;i++)
    {
    SCL=0;               
   _nop_();
  _nop_();
    SDA=(ch&0x80);
    ch<<=1;
    _nop_();            
   _nop_(); 
_nop_(); 

     SCL=1;
    _nop_();             
    _nop_();
    _nop_();
    _nop_();
   
    }
SCL=0;
}
 
 unsigned char  Receive_I2C(void)
{
unsigned char i,data_in=0;
SDA=1;
for (i=0;i<8;i++)
    {
    data_in<<=1;
    SCL=0;
    _nop_();             
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_(); 
_nop_();
     SCL=1;              
        
    _nop_();
    _nop_();
    _nop_();
    data_in|=SDA;
    }
SCL=0;
return data_in;
}

void write(unsigned char regaddress,unsigned char data0)
{
   Start_I2C();
    Send_I2C(0x98);
     if(DetectAck())
      {
          Send_I2C(regaddress);
          if(DetectAck())
          {
                   Send_I2C(data0);
           if(DetectAck())
                   Stop_I2C();
         }
        else 
      Stop_I2C();
          } 
     else 
   Stop_I2C();
}

void read(unsigned char regaddress)
{
        Start_I2C();
       Send_I2C(0x98);
    if(DetectAck())
         {
           Send_I2C(regaddress);
          if(DetectAck())
          {
         Start_I2C();
           Send_I2C(0x99);
          if(DetectAck())
          {
                  P2=Receive_I2C();
                  Stop_I2C();
              }
        else   Stop_I2C();
             } 
       else  Stop_I2C();
     }
    else 
     Stop_I2C();
}

void   write_read(unsigned char regaddress,unsigned char data0)
{
       write(regaddress, data0);
  read(regaddress);
     
}

void   doublebyte_write_read(unsigned char baseaddress,unsigned char data1,unsigned char data2)
{
       Start_I2C();
    Send_I2C(0x98);
    if(DetectAck())
    {
     Send_I2C(baseaddress);
     if(DetectAck())
     {
        Send_I2C(data1);
    if(DetectAck())
      {  
         Send_I2C(data2);
          if(DetectAck())
              Stop_I2C();
          else  Stop_I2C();
          } 
    else     Stop_I2C();
     }
    else Stop_I2C();
  }
  else
        Stop_I2C();
 
   Start_I2C();
      Send_I2C(0x98);
    if(DetectAck())
         {
        Send_I2C(baseaddress);
       if(DetectAck())
           {
         Start_I2C();
           Send_I2C(0x99);
         if(DetectAck())
           {
                P2=Receive_I2C();
          SendAck();
          P2=Receive_I2C();
                Stop_I2C();
               }
           else Stop_I2C();
               } 
      else Stop_I2C();  
      }
      else      Stop_I2C();
}
void main()
{   
    write_read(0x2D,0xD2);
    write_read(0x2E,0xE2);
    read(0x3C);
   write_read(0x3C,0xCC);
   read(0x01);
   read(0x02);
   doublebyte_write_read(0x01,0x11,0x22); 

 }



点赞

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 注册

  • 关注TA
  • 加好友
  • 联系TA
  • 0

    周排名
  • 0

    月排名
  • 0

    总排名
  • 0

    关注
  • 1

    粉丝
  • 0

    好友
  • 0

    获赞
  • 0

    评论
  • 408

    访问数
关闭

站长推荐 上一条 /1 下一条

小黑屋| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-4-28 08:42 , Processed in 0.022431 second(s), 13 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
返回顶部