您的位置:首页技术文栏单片机C51
内容搜索:
阅读内容
背景:#EDF0F5 #FAFBE6 #FFF2E2 #FDE6E0 #F3FFE1 #DAFAF3 #EAEAEF 默认  

I2C驱动程序( C51 )

[日期:2008-04-14 ] [来源:东哥单片机学习网(www.picavr.com) 作者:佚名] [字体: (投递新闻)
来源:网上转载     作者:佚名

//****************************I2C驱动程序****************************//
void Set_SCL(uchar i)                  //定义MAX6959时钟线为PA^7
{if(i)   PORTA |=0x80;
 else    PORTA &=0x7f;
}
 
void Set_SDA(uchar i)                  //定义MAX6959数据线为PA^6
{if(i)   PORTA |=0x40;
 else    PORTA &=0xbf;
}

void Start()                           //I2C总线的开始条件
{Set_SDA(1);                        //SDA=1;
 Set_SCL(1);                        //SCL=1;
 delay(100);                        //等待时钟信号变高
 Set_SDA(0);                        //SDA=0;
 delay(100);
 Set_SCL(0);                        // SCL=0;
}

void Stop()                            //I2C总线结束条件
{Set_SDA(0);                        //SDA=0;
 delay(100);
 Set_SCL(1);                        //SCL=1;
 delay(100);                        //等待时钟信号变低
 Set_SDA(1);                        //SDA=1;
 delay(100);
 Set_SCL(0);                        //SCL=0;
}

void Ack()                             //I2C总线应答
{Set_SDA(0);                        //SDA=0;
 delay(50);
 Set_SCL(1);                        //SCL=1;
 delay(100);
 Set_SCL(0);                        //SCL=0;
 delay(50);
 Set_SDA(1);                        //SDA=1;
}

void Nack()                            //I2C总线应答非
{Set_SDA(1);                        //SDA=1;
 delay(50);
 Set_SCL(1);                        //SCL=1;
 delay(100);
 Set_SCL(0);                        //SCL=0;
 delay(50);
 Set_SDA(0);                        //SDA=0;
}

void Check_Ack()                       //I2C总线应答检查
{Set_SDA(1);                        //SDA=1;
 Set_SCL(1);                        //SCL=1;
 Ack_Flag=0;                        //清除应答标志;
 DDRA&=0xbf;                         //设置SDA为输入
 if(!((PINA & 0x40)>>6))
   {delay(50);
    Set_SCL(0);                        //SCL=0;
    delay(100);}
 else
   {Ack_Flag=1;                        //收到应答;
    delay(50);
    Set_SCL(0);                        //SCL=0;
    delay(100);}
 DDRA |=0xff;                         //重新设置SDA为输出 
}

void Write_Bit0()                      //写1bit数据:0   
{Set_SDA(0);                        //SDA=0;
 Set_SCL(1);                        //SCL=1;
 delay(100);
 Set_SCL(0);                        //SCL=0;
}

void Write_Bit1()                      //写1bit数据:1      
{Set_SDA(1);                        //SDA=1;
 Set_SCL(1);                        //SCL=1;
 delay(100);
 Set_SCL(0);                        //SCL=0;
 Set_SDA(0);                        //SDA=0;
}

void Write_Byte(uchar Data)            //写一字节数据Data 
{uchar i;
 for(i=0;i<8;i++)
  {if(Data & 0x80)  Write_Bit1();      //传输位从高位到低位,先传最高位
   else             Write_Bit0();
   Data <<=1;}                         //数据左移            
}

uchar Read_Byte()                      //读一字节数据:返回值即读的数据          
{uchar Read_Data=0xff;             // Read_Data为读入的数据,初始值为0xff
 uchar j;
 for (j=0;j<8;j++)
  {Set_SDA(1);   
   Set_SCL(1);   
   DDRA &=0xbf;   
   if((PINA & 0x40)==0)
     {Read_Data <<=1;
      Read_Data=(Read_Data & 0xfe);                
      Set_SCL(0);}
   else
    {Read_Data <<=1;
     Read_Data =( Read_Data  | 0x01);
     Set_SCL(0);}}
 DDRA |=0x40;               
 return(Read_Data);              
}

//***************************写一字节数据****************************//
//向从地址为Slave的IIC器件的Address地址写一字节数据Data
void Write_1byte(uchar Slave,uchar Address,uchar Data)
{Start();                         //开始
 Write_Byte(Slave);                 //写I2C器件地址
 do Check_Ack();                 //检查应答位
 while(Ack_Flag==1);
 Write_Byte(Address);                  //送寄存器地址
 do Check_Ack();                 //检查应答位
 while(Ack_Flag==1);
 Write_Byte(Data);                 //写入一字节数据
 do Check_Ack();                       //检查应答位
 while(Ack_Flag==1);
 Stop();                               //停止
}

//***************************写两字节数据****************************//
//向从地址为Slave的IIC器件的Address地址开始写两字节数据Data0,Data1
void Write_2byte(uchar Slave,uchar Address,uchar Data0,uchar Data1)
{Start();                         //开始
 Write_Byte(Slave);                 //写I2C器件地址
 do Check_Ack();                 //检查应答位
 while(Ack_Flag==1);                 
 Write_Byte(Address);                  //送寄存器地址
 do Check_Ack();                 //检查应答位
 while(Ack_Flag==1);
 Write_Byte(Data0);
 do Check_Ack();                  //检查应答位
 while(Ack_Flag==1);
 Write_Byte(Data1);
 do Check_Ack();                 //检查应答位
 while(Ack_Flag==1);
 Stop();                         //停止信号
}

//***************************读一字节数据****************************//
//从从地址为Slave的IIC器件的Address地址处读一字节数据
uchar Read_1byte(uchar Slave,uchar Address)
{uchar data0,x;
 do{
    Start();                     //开始信号
    Write_Byte(Slave);             //写I2C器件地址
    Check_Ack();                 //检查应答位
   }while(Ack_Flag);             
 do{
    Write_Byte(Address);         //写寄存器地址
    Check_Ack();                 //检查应答位
   }while(Ack_Flag);                  
 do{
    Start();                     //开始
    Write_Byte(Slave+1);         //写I2C器件地址(+1表示为读操作)
    Check_Ack();                 //检查应答位
   }while(Ack_Flag);
 data0=Read_Byte();                 //读1字节
 Nack();                         //读完发送一个Not Ack应答
 Stop();                         //停止
 return data0;                        //返回读取数据
}

 

阅读:
录入:JETTA

推荐 】 【 打印
本文评论
      全部评论
发表评论


点评: 字数
姓名:
站长推荐