×
单片机 > 单片机程序设计 > 详情

AVR单片机IO仿真I2C

发布时间:2020-06-19 发布时间:
|
#include

#define EEP_PORT PORTC   //定义是使用PROTC口
#define EEP_DDR DDRC     //定义是使用PROTC口
#define SDA 0X10         //定义sda连接的是portd1
#define SCL 0X20         //定义scl连接的是portd0
//#define WP 0X04          //定义wp连接的是portd2
#define EEP_ADD_R 0xa1   //写I2C从器件地址和读方式 a0,a1接地
#define EEP_ADD_W 0   //写I2C从器件地址和写方式 a0,a1接地

void delay(unsigned int us)
{
     while(us--);
}

void eep_init(void)
{
EEP_DDR|= SDA | SCL ;//| WP ;
EEP_PORT|=SDA | SCL ;//| WP ;
}

void send(void)
{
      EEP_PORT|=SCL;
      asm("nop");
      EEP_PORT&=~SCL;
}
/********************************************
内部函数,I2C开始
********************************************/
void Start(void)

    EEP_PORT|=SDA; //sda
    EEP_PORT|=SCL; //scl
    asm("nop");
    EEP_PORT&=~SDA;
    asm("nop");
    EEP_PORT&=~SCL;
}
/********************************************
内部函数,I2C结束
********************************************/
void Stop(void)
{
    EEP_PORT&=~SDA;
    EEP_PORT&=~SCL;
    asm("nop");
    EEP_PORT|=SCL;
    asm("nop");
    EEP_PORT|=SDA;
    asm("nop");
}

/********************************************
内部函数,等待ACK
********************************************/
void ACK(void)

   unsigned char errtime=20;
   EEP_PORT|=SDA;       //上拉
   EEP_DDR&=~SDA;   //设置为输入口
   EEP_PORT|=SCL;       
   asm("nop");
   while(PINC&SDA)
  {  errtime--;
     if(!errtime)
  {
  Stop();
  EEP_PORT&=~SDA; //超时,给他个离开的理由
  }
   }
   EEP_PORT&=~SCL;
   asm("nop");
   EEP_DDR|=SDA;   //设置为输出口
}
/********************************************
内部函数.输出数据字节
********************************************/
void writebyte(unsigned char wdata)
{
   unsigned char i;
   for(i=0;i<8;i++)
   {
      if((wdata&0x80)){EEP_PORT|=SDA;}else{EEP_PORT&=~SDA;}
   wdata<<=1;
      send(); //发送一个位
   
   }
}
/********************************************
内部函数.输入数据
********************************************/
unsigned char Readbyte(void)
{
   unsigned char i,bytedata;
   EEP_DDR&=~SDA;   //设置为输入?
   for(i=0;i<8;i++)
   {
      EEP_PORT|=SCL;
      bytedata<<=1;
   if(PINC&SDA){
      bytedata|=0X01;
   }else{
   bytedata&=~0X01;
   }
      EEP_PORT&=~SCL;
      asm("nop");
   }
   EEP_DDR|=SDA;
    return(bytedata);
 
}

/********************读24cxx--外部调用********************/
unsigned char read_eep(unsigned char add1,unsigned char add2)
{  unsigned char mdata;
   Start();                   //起始位
   writebyte(EEP_ADD_W);      //写eeprom地址+1个写命令
     ACK();                   //等待应答信号
   writebyte(add1);           //写如访问地址
     ACK();                   //等待应答信号
   writebyte(add2);           //写入访问地址
     ACK();                   //等待应答信号
   Start();                   //起始位
   writebyte(EEP_ADD_R);      //写eeprom地址+1个读命令
     ACK();                   //等待应答信号
   mdata=Readbyte();          //获取数据
     Stop();          //发送停止位置
   asm("nop");               //此处延时根据实际情况,如果不延时,可能会不正常
   return(mdata);
}
/********************写24cxx--外部调用********************/
void write_eep(unsigned char add1,unsigned char add2,unsigned char udata)
{
//EEP_PORT&=~WP;                //关闭写保护
   Start();                   //起始位
   writebyte(EEP_ADD_W);   //写eeprom地址+1个写命令
   ACK();       //等待应答信号
   writebyte(add1);        //写如访问地址
   ACK();       //等待应答信号
   writebyte(add2);        //写如访问地址
   ACK();       //等待应答信号
   writebyte(udata);    //写入数据
   ACK();       //等待应答信号
   Stop();                    //发送停止位
   delay(24000);
   //delay_nms(4);              //此处延时根据实际情况,大多EEPROM都需要3毫秒的写入时间,如果不延时,可能会不正常
   //EEP_PORT|=WP;                 //打开写保护
}

void main(void)
{
    unsigned char tmp;
 eep_init();
 DDRC|=(1<<0);
 PORTC&=~(1<<0);
 write_eep(0,2,7);
 tmp=read_eep(0,2);
 if(tmp==7)
    PORTC|=(1<<0);
 while(1);
}

关键字:AVR单片机  IO  仿真I2C

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机制作超级流水灯