⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avr256.c

📁 该程序是AVR单片机MEGA88对存储器AT24C256的硬件TWI程序,已调试过,没出问题,可参考
💻 C
字号:
#include<iom16v.h> 
#include <macros.h> 

//TWI状态定义 
//MT 主方式传输  MR 主方式接收 
#define START 0x08  
#define RE_START 0x10 

#define MT_SLA_ACK 0x18 
#define MT_SLA_NOACK 0x20 
#define MT_DATA_ACK  0x28 
#define MT_DATA_NOACK 0x30 

#define MR_SLA_ACK  0x40 
#define MR_SLA_NOACK 0x48 
#define MR_DATA_ACK 0x50 
#define MR_DATA_NOACK 0x58 
//常用TWI操作(主模式写和主模式读) 
#define Start()         (TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN)) 
#define Stop()          (TWCR=(1<<TWINT)|(1<<TWSTO)|(1<<TWEN)) 
#define Wait()           {while(!(TWCR&(1<<TWINT)));} 
#define TestAck()      (TWSR&0xf8) 
#define SetAck()     (TWCR|=(1<<TWEA)) 
#define SetNoAck()    (TWCR&=~(1<<TWEA)) 
#define Twi()          (TWCR=(1<<TWINT)|(1<<TWEN)) 
#define Write8Bit(x)  {TWDR=(x);TWCR=(1<<TWINT)|(1<<TWEN);}  

#define rd_device_add 0xa1 
#define wr_device_add 0xa0 

union _my_int 
{ 
      uint IntV; 
     uchar i[2]; 
}; 
      

extern void delay_nms(unsigned int time); 
/****************************************** 
置TWI管脚上拉 
******************************************/ 
void Init_TWI(void) 
{ 
     TWI_PORT_DDR  |= TWI_SCL |TWI_SDA;                  
    TWI_PORT_PORT |= TWI_SCL |TWI_SDA; 
     
    TWSR=00;     //设置TWI时钟50K 
    TWBR=0x16; 
} 

/****************************************** 
               I2C总线写一个字节 
             返回0:写成功 
            返回非0:写失败 
*******************************************/ 
unsigned char i2c_Write(unsigned char Wdata,unsigned int RomAddress)  
{ 
     unsigned char *P; 
     union _my_int k; 
     k.IntV=RomAddress; 
     P=&k.i[1]; 
      
     Start();//I2C启动 
     Wait(); 
     if(TestAck()!=START) return 1;//ACK 
     Write8Bit(wr_device_add);//写I2C从器件地址和写方式 
     Wait(); 
     if(TestAck()!=MT_SLA_ACK) return 1;//ACK 
      
     P--; 
     Write8Bit(*P);//写24C02的ROM地址 
     Wait(); 
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK 
      
     Write8Bit(*P);//写24C02的ROM地址 
     Wait(); 
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK 
      
      
      
     Write8Bit(Wdata);//写数据到24C02的ROM 
     Wait(); 
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK    
      
     Stop();//I2C停止 
      delay_nms(10);//延时等EEPROM写完 
     return 0; 
} 
/****************************************** 
               I2C总线读一个字节 
            如果读失败也返回0 
*******************************************/ 
unsigned char i2c_Read(unsigned int RomAddress)  
{ 
      unsigned char temp; 
      unsigned char *P; 
      union _my_int k; 
      k.IntV=RomAddress; 
      P=&k.i[1]; 
       
      Start();//I2C启动 
      Wait(); 
      if (TestAck()!=START) return 0;//ACK       
      Write8Bit(wr_device_add);//写I2C从器件地址和写方式 
      Wait();  
      if (TestAck()!=MT_SLA_ACK) return 0;//ACK 
       
      P--; 
      Write8Bit(*P);//写24C02的ROM地址 
      Wait(); 
      if (TestAck()!=MT_DATA_ACK) return 0; 
       
      Write8Bit(*P);//写24C02的ROM地址 
      Wait(); 
      if (TestAck()!=MT_DATA_ACK) return 0; 
       
      Start();//I2C重新启动 
      Wait(); 
      if (TestAck()!=RE_START)  return 0; 
      Write8Bit(rd_device_add);//写I2C从器件地址和读方式 
      Wait(); 
      if(TestAck()!=MR_SLA_ACK)  return 0;//ACK 
      Twi();//启动主I2C读方式 
      Wait(); 
      if(TestAck()!=MR_DATA_NOACK) return 0;//ACK    
       
      temp=TWDR;//读取I2C接收数据 
       Stop();//I2C停止 
      return temp; 
} 

//#define uchar unsigned char 
//#define uint  unsigned int 
//page write 
unsigned char PageWrTWI(unsigned char * Wdata,unsigned int RomAddress,unsigned char Num) 
{ 
      unsigned char *P; 
     union _my_int m; 
     m.IntV=RomAddress; 
     P=&m.i[1]; 
      
     Start();//I2C启动 
     Wait(); 
     if(TestAck()!=START) return 1;//ACK 
     Write8Bit(wr_device_add);//写I2C从器件地址和写方式 
     Wait(); 
     if(TestAck()!=MT_SLA_ACK) return 1;//ACK 
      
     P--; 
     Write8Bit(*P);//写24C02的ROM地址 
     Wait(); 
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK 
      
     Write8Bit(*P);//写24C02的ROM地址 
     Wait(); 
     if(TestAck()!=MT_DATA_ACK) return 1;//ACK 
      
     for(;Num>0;Num--) 
     { 
        Write8Bit(*Wdata);//写数据到24C02的ROM 
       Wdata++; 
       Wait(); 
        if(TestAck()!=MT_DATA_ACK)  
            return 1;//ACK 
     } 
     Stop();//I2C停止 
      delay_nms(10);//延时等EEPROM写完 
     return 0; 
} 

//page read 
unsigned char PageRdTWI(uchar *RdBuf,unsigned int RomAddress,uchar Num)  
{ 
      //unsigned char temp; 
      unsigned char *P; 
      union _my_int n; 
      n.IntV=RomAddress; 
      P=&n.i[1]; 
       
      Start();//I2C启动 
      Wait(); 
      if (TestAck()!=START) return 0;//ACK       
      Write8Bit(wr_device_add);//写I2C从器件地址和写方式 
      Wait();  
      if (TestAck()!=MT_SLA_ACK) return 0;//ACK 
       
      P--; 
      Write8Bit(*P);//写24C02的ROM地址 
      Wait(); 
      if (TestAck()!=MT_DATA_ACK) return 0; 
       
      Write8Bit(*P);//写24C02的ROM地址 
      Wait(); 
      if (TestAck()!=MT_DATA_ACK) return 0; 
       
      Start();//I2C重新启动 
      Wait(); 
      if (TestAck()!=RE_START)  return 0; 
      Write8Bit(rd_device_add);//写I2C从器件地址和读方式 
      Wait(); 
      if(TestAck()!=MR_SLA_ACK)  return 0;//ACK 
       
      Twi();//启动主I2C读方式 
       Wait(); 
      if(TestAck()!=MR_DATA_NOACK) return 0;//ACK 
      for(;Num>0;Num--) 
      { 
    
         //temp=TWDR;//读取I2C接收数据 
        *RdBuf=TWDR; 
                        SetAck() 
        RdBuf++; 
      } 
       
       Stop();//I2C停止 
      return 1; 
} 

void main() 
{ 
     Init_TWI(void); 
    ... 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -