新闻  |   论坛  |   博客  |   在线研讨会
atmega128单片机读写EEPROM AT24C64 源程序,共享吧。
mayer | 2009-08-01 12:03:35    阅读:3740   发布文章

atmega128单片机读写EEPROM AT24C64 源程序,共享吧。

 

点击看大图

#include <avr/io.h>
#include <avr/signal.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <avr/pgmspace.h>

#ifndef cbi
        #define cbi(reg,bit)        reg &= ~_BV(bit)
#endif

#ifndef sbi
        #define sbi(reg,bit)        reg |= _BV(bit)
#endif


void delay_1ms(uint8_t xtal)
{
 uint8_t i;
 for(i=1;i<(uint8_t)(xtal*143-2);i++)
    {;}
}
//2 延时nms
void delay_ms(uint8_t m, uint8_t fosc)
{
 uint8_t i;
 i=0;
 while(i<m)
 {
  delay_1ms(fosc);
  i++;
 }
}

//-----------------------------IIC操作子程序-------------------------------
//IIC写操作
//address_device为器件地址,0xa0为24C64
//address_reg1为寄存器地址1,address_reg2为寄存器地址2
//data_package为写的数据
void twi_write(uint8_t address_reg1,uint8_t address_reg2, uint8_t data_package)

 //TWI预分频为4分频
 sbi(TWSR,TWPS0);
 cbi(TWSR,TWPS1);
 TWBR=0x20;//SCL频率92160HZ
begin:
 TWCR=_BV(TWEN)|_BV(TWSTA)|_BV(TWINT);
 while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示开始信号发送完毕
  ;
 if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
  goto begin;
 TWDR=0xa0;//将器件地址写入到TWDR寄存器,TWINT位清零,启动发送地址
    TWDR="0xa0";//%%%%%%%%%%%%%%%

 TWCR=_BV(TWEN)|_BV(TWINT);
 while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
  ;
 if((TWSR&0xF8)!=0x18)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
  goto begin; 
 //---发送寄存器地址
 TWDR=address_reg1;//写寄存器地址
 TWDR=address_reg1;//%%%%%%%%%%%%%%%
 TWCR=_BV(TWEN)|_BV(TWINT);
 while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
  ;
 if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
  goto begin;
    //---发送EEPROM的第二个地址
 TWDR=address_reg2;//写寄存器地址
 TWDR=address_reg2;//%%%%%%%%%%%%%%%
 TWCR=_BV(TWEN)|_BV(TWINT);
 while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
  ;
 if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
  goto begin;
  //---写入数据
 TWDR=data_package;//将数据载入到TWDR寄存器,TWINT位清零,启动发送地址
 TWDR=data_package;//%%%%%%%%%%%%%%%

 TWCR=_BV(TWINT)|_BV(TWEN); 
 while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线数据已发出,及收到应答信号ACK/NACK
  ;  
 if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是数据ACK,重新发送开始信号
  goto begin; 
 TWCR=_BV(TWINT)|_BV(TWSTO)|_BV(TWEN);//发送STOP信号
 delay_ms(2,8); 
 delay_ms(2,8); 
 delay_ms(2,8);
}
//-------------------------------------------
//IIC读操作
//address_reg1为寄存器地址,address_reg2为寄存器地址2
uint8_t twi_read(uint8_t address_reg1,uint8_t address_reg2)
{
 uint8_t result1=0;
 sbi(TWSR,TWPS0);//TWI预分频为4分频
 cbi(TWSR,TWPS1);
 TWBR=0x20;//SCL频率92160HZ
begin:
 delay_ms(2,8);
 
 TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送开始信号
 while(!(TWCR&(1<<TWINT)))//等待开始信号发送完毕
  ;
 if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查TWI状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
  goto begin;
 //---发送器件地址
 TWDR=0xa0;//发器件写地址,TWINT位清零,启动发送%%%%%%%%%%%%%%
 TWCR=(1<<TWINT)|(1<<TWEN);
 while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
  ;
 if((TWSR&0xF8)!=0x18)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
  goto begin;
 //---发送寄存器地址
 TWDR=address_reg1;//写寄存器地址,TWINT位清零,启动发送%%%%%%%%%%%%%%%%%%
 TWCR=(1<<TWINT)|(1<<TWEN);
 while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线数据已发出,及收到应答信号ACK/NACK
  ;
 if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是数据ACK,重新发送开始信号
  goto begin; 
 //---发送EEPROM的第二个地址
 TWDR=address_reg2;//写寄存器地址
 TWDR=address_reg2;//%%%%%%%%%%%%%%%
 TWCR=_BV(TWEN)|_BV(TWINT);
 while(!(TWCR&_BV(TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
  ;
 if((TWSR&0xF8)!=0x28)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
  goto begin;
 //---发送起始信号
 TWCR=(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);//发送开始信号
 while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示开始信号发送完毕
  ; 
 if(((TWSR&0xF8)!=0x08)&((TWSR&0xF8)!=0x10))//检查TWI状态寄存器,如果状态字不是START或RESTART,重新发送开始信号
  goto begin; 
 //---发送读命令
 TWDR=0xa0+1;//读器件地址写入到TWDR寄存器,TWINT位清零,启动发送
 TWCR=(1<<TWINT)|(1<<TWEN);
 while(!(TWCR&(1<<TWINT)))//等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
  ; 
 if((TWSR&0xF8)!=0x40)//检查TWI状态寄存器,如果状态字不是地址ACK,重新发送开始信号
  goto begin; 
 TWCR=(1<<TWINT)|(1<<TWEN);//发送NACK信号
 while(!(TWCR&(1<<TWINT)))
  ;
 if((TWSR&0xF8)!=0x58)
  goto begin; 
 TWCR=(1<<TWSTO)|(1<<TWEN);//发送STOP信号
 result1=TWDR;//将TWDR寄存器的数据读入 
 delay_ms(2,8); 
 delay_ms(2,8); 
 delay_ms(2,8);
 return result1;
}
//==================================================================  void main()
{
 int i,jianzhi=0,ms=0,a[11];
 
 for(i=0;i<=10;i++)
 {
  twi_write(0,i,i+0x32);//写入一串数据
 } 
 for(i=0;i<=10;i++)
 {
  a[i]=twi_read(0,i);//读出一串数据
 }}

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客