專注電子技術(shù)學習與研究
當前位置:單片機教程網(wǎng) >> MCU設(shè)計實例 >> 瀏覽文章

AVR單片機驅(qū)動24c02的C51程序

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2012年02月10日   【字體:
*******************************************************************/
 //24c02-- SCL接PD4 , SDA接PD5 。單片機PA口接8路指示燈,開始時 72個花樣燈
 //表示將程序?qū)懭?4c02,過10秒后, 再從24c02中讀出,顯示在指示燈上
#include <iom16v.h>
#define _BV(k) (1<<k)
#define uchar unsigned char
#define uint unsigned int
#define  SCL   PD4                   //I2總線時鐘線
#define  SDA   PD5                   //I2總線數(shù)據(jù)線 
#define SCL_L  PORTD &=~_BV(SCL) 
#define SCL_H  PORTD |= _BV(SCL)     
#define SDA_L  PORTD &=~_BV(SDA)     
#define SDA_H  PORTD |= _BV(SDA)     
#define SDA_IN  DDRD&=~_BV(SDA)     //設(shè)數(shù)據(jù)線位輸入
#define SDA_OUT DDRD|= _BV(SDA) //設(shè)數(shù)據(jù)線位輸出
#define SDA_RD    (PIND&_BV(SDA))    //讀電平
#define  FREQ  1                     //芯片工作頻率
#define  Slave  0xa0
uchar  temp=0xff;
uchar  display[72]={ 0};
uchar const IN_data[72]={
0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,
    0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,
    0xFE,0xFC,0xF8,0xF0,0xE0,0xC0,0x80,0x00,
    0x80,0xC0,0xE0,0xF0,0xF8,0xFC,0xFE,0xFF,
    0xFC,0xF9,0xF3,0xE7,0xCF,0x9F,0x3F,
    0x9F,0xCF,0xE7,0xF3,0xF9,0xFC,0xFF,
    0xE7,0xDB,0xBD,0x7E,0xBD,0xDB,0xE7,0xFF,
    0xE7,0xC3,0x81,0x00,0x81,0xC3,0xE7,0xFF,
    0xAA,0x55,0x18,0xFF,0xF0,0x0F,
    0x00,0xFF,0x00,0xFF};
/********************************************************
*                                                       *
* N*ms延時函數(shù)                                          *
*                                                       *
********************************************************/    
void delayms(uint n)        
   { 
      uint i=0,j ; 
      for (i=0 ;i<n ;i++) 
      for(j=0;j<250*FREQ;j++) ;
   }
 
/********************************************************
*                                                       *
* y*us延時函數(shù)                                          *
*                                                       *
********************************************************/   
void  delay(uint y)
  { 
  int j;
     for(j=0;j<250*FREQ;j++) ;
  }
/**********************************************************

 起始信號

 在 SCL 高電平期間 SDA 發(fā)生負跳變
 
**********************************************************/
void I2C_start(void)
{   
    SDA_H; 
    SCL_H; 
delay(5);
    SDA_L;
    delay(5);
    SCL_L; 
}
/**********************************************************

  停止信號
  
  在 SCL 高電平期間 SDA 發(fā)生正跳變
  
**********************************************************/
void I2C_stop(void)
{       
    SDA_L; 
    SCL_H; 
    delay(5);
    SDA_H; 
    delay(5);
SCL_L; 
delay(5);
}

/**********************************************************

把一個字節(jié)數(shù)據(jù)輸入器件,并以收到應(yīng)答信號為止

發(fā)送一個字節(jié)子程序

**********************************************************/
void I2C_Send(uchar W_data)
{   
    uchar i;
for(i=0;i<8;i++)
    {   
      if((W_data&0x80)) 
      SDA_H;                 
      else 
      SDA_L; 
 SCL_H; 
 delay(5);
 SCL_L; 
 delay(5);
      W_data <<=1;
    }
}

/**********************************************************

**********************************************************/
void  Wait_Ack(void) 
{           
   SDA_IN;                   //置SDA為輸入
   SDA_H;
   delay(5);
   do
   {
      SCL_L;
      SDA_H;
      delay(50);
 SCL_H;
 delay(50);       
   } 
   while(SDA_RD);        
   SDA_L;
   SCL_L;
   SDA_OUT;                //置SDA為輸出           
}  
/**********************************************************

讀一個字節(jié)子程序

**********************************************************/
uchar I2C_REV(void)
{   
   uchar i;
   
   SDA_H;                 //開上拉
   SDA_IN;                //置SDA為輸入
   delay(5);
for(i=0;i<8;i++)
   { 
      SCL_H;
 delay(5);
   temp<<=1;
   if(SDA_RD)
 temp=(temp | 0x01);
 else
 temp=(temp & 0xfe);
 SCL_L; 
   }
   SDA_OUT;                //置SDA為輸出  
   return(temp);
}

/**********************************************************

  發(fā)送應(yīng)答位子函數(shù)

  在 SDA 低電平期間 SCL 發(fā)生一個正脈沖

**********************************************************/
void  I2C_Ack(void)
{
   SCL_L; delay(4);
   SDA_L; delay(4);
   SCL_H; delay(4);
   SCL_L; delay(4);
   SDA_H; delay(4);
}

/**********************************************************

 發(fā)送非應(yīng)答位子函數(shù)

 在 SDA 高電平期間 SCL 發(fā)生一個正脈沖

**********************************************************/
void  I2C_NAck(void)
{
   SDA_H; 
   delay(4);
   SCL_H; delay(4);
   SCL_L; delay(4);
   SDA_L;
}

/**********************************************************

  從MCU移出數(shù)據(jù)到AT24C02
  
  在指定地址addr處寫入一個字節(jié)子程序

**********************************************************/
void  Write_byte(uchar Addr,uchar in_Data)
{
   I2C_start();
   I2C_Send(Slave);
   Wait_Ack();
   I2C_Send(Addr);
   Wait_Ack(); 
   I2C_Send(in_Data);
   Wait_Ack();
   I2C_stop();
   delay(10);
}

/**********************************************************

  在指定地址addr處讀出一個字節(jié)子程序從AT24C04讀數(shù)據(jù)到MCU
  
**********************************************************/
void  Read_byte(uchar Addr)
{     
   I2C_start();
   I2C_Send(Slave);
   Wait_Ack();
   I2C_Send(Addr);
   Wait_Ack(); 
   I2C_start();
   I2C_Send(Slave+1);
   Wait_Ack();
   
   I2C_REV();  
   I2C_NAck();  
   I2C_stop();
   delay(10);
}

/**********************************************************

  主函數(shù)

**********************************************************/
int  main(void)
{
    uchar m;
    DDRA=0xff;
PORTA=0xff;
DDRC=0xff;
PORTC=0xff;
DDRD=0xff;
PORTD=0xff;
    for(m=0;m<72;m++)   
{                            //寫數(shù)據(jù)
    Write_byte(m,IN_data[m]);
PORTA= IN_data[m];
}

for(m=0;m<72;m++)            //讀數(shù)據(jù)
{ 
     Read_byte(m); 
 display[m]=temp;
}
while(1)
{
 for(m=0;m<72;m++)         //顯示數(shù)據(jù)
 {   
PORTA= display[m];
delayms(60);
 }
} 
}
關(guān)閉窗口

相關(guān)文章