AVR-TWI驱动FM24C16B

来源:互联网 发布:淘宝司法拍卖网首页 编辑:程序博客网 时间:2024/06/07 15:44
  • FM24C16B相关

      24C16的字节存储地址的范围为:0x0000~0x07FF,地址位A10,A9,A8,A7~A0,一共可以存储2048个字节。

      24C16的三个地址引脚都是无效的,器件地址为如下表所示,其中bit3~bit1是存储地址的高三位。
芯片 bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0 24C16 1 0 1 0 A10 A9 A8 R/W


- H文件中的相关定义

/*TWSR状态码*/#define START                   ( ( uint8_t ) 0x08 )#define RE_START                ( ( uint8_t ) 0x10 )#define MT_SLA_ACK              ( ( uint8_t ) 0x18 )#define MT_SLA_NOACK            ( ( uint8_t ) 0x20 )#define MT_DATA_ACK             ( ( uint8_t ) 0x28 )#define MT_DATA_NOACK           ( ( uint8_t ) 0x30 )#define MR_SLA_ACK              ( ( uint8_t ) 0x40 )#define MR_SLA_NOACK            ( ( uint8_t ) 0x48 )#define MR_DATA_ACK             ( ( uint8_t ) 0x50 )#define MR_DATA_NOACK           ( ( uint8_t ) 0x58 )/*读、写器件地址*/#define RD_DEVICE_ADDR          ( ( uint8_t ) 0xA1 )#define WD_DEVICE_ADDR          ( ( uint8_t ) 0xA0 )/*常用TWI操作(主模式写和读)*/#define TWI_Start()             do{                                         \                                    TWCR = _BV(TWINT)|_BV(TWSTA)|_BV(TWEN); \                                    while(!(TWCR & _BV(TWINT)));            \                                  }while(0)#define TWI_Stop()              do{                                         \                                    TWCR = _BV(TWINT)|_BV(TWSTO)|_BV(TWEN); \                                  }while(0)#define TWI_Write(X)            do{                                         \                                    TWDR = X;                               \                                    TWCR = _BV(TWINT)|_BV(TWEN);            \                                    while(!(TWCR & _BV(TWINT)));            \                                  }while(0)#define TWI_Read(X)             do{                                         \                                    TWCR = _BV(TWINT)|_BV(TWEN);            \                                    while(!(TWCR & _BV(TWINT)));            \                                    X = TWDR;                               \                                  }while(0)#define TWI_ReadAck(X)          do{                                         \                                    TWCR = _BV(TWINT)|_BV(TWEA)|_BV(TWEN);  \                                    while(!(TWCR & _BV(TWINT)));            \                                    X = TWDR;                               \                                  }while(0)#define TWI_GetStatus()         (TWSR & 0XF8)
  • C文件中的相关函数
/* * 设置片上TWI功能,驱动铁电存储器FM24C16B */void TWI_Init( void ){    /*使能TWI功能*/    TWCR = _BV(TWEN);    /*根据TWI_RATE_HZ设置TWBR值,TWI_RATE_HZ在头文件Def_Config.h中配置*/    TWBR = (uint8_t)((F_CPU/( uint32_t )TWI_RATE_HZ-16)/2);    /*设置TWI预分频值为1*/    TWSR = 0;}/*在address地址写入一个值为data的字节*/uint8_t FM_WriteByte( uint16_t address, uint8_t data ){    TWI_Start();    if(TWI_GetStatus()!=START)return pdERROR;    TWI_Write(WD_DEVICE_ADDR|(uint8_t)((address & 0x0700)>>7));    if(TWI_GetStatus()!=MT_SLA_ACK)return pdERROR;    TWI_Write((uint8_t)address);    if(TWI_GetStatus()!=MT_DATA_ACK)return pdERROR;    TWI_Write(data);    if(TWI_GetStatus()!=MT_DATA_ACK)return pdERROR;    TWI_Stop();    _delay_ms(5);    return pdSUCCESS;}/*从address地址读出数据,存放到*data中*/uint8_t FM_ReadByte( uint16_t address, uint8_t * data ){    TWI_Start();    if(TWI_GetStatus()!=START)return pdERROR;    TWI_Write(WD_DEVICE_ADDR|(uint8_t)((address & 0x0700)>>7));    if(TWI_GetStatus()!=MT_SLA_ACK)return pdERROR;    TWI_Write((uint8_t)address);    if(TWI_GetStatus()!=MT_DATA_ACK)return pdERROR;    TWI_Start();    if(TWI_GetStatus()!=RE_START)return pdERROR;    TWI_Write(RD_DEVICE_ADDR|(uint8_t)((address & 0x0700)>>7));    if(TWI_GetStatus()!=MR_SLA_ACK)return pdERROR;    TWI_Read(*data);    if(TWI_GetStatus()!=MR_DATA_NOACK)return pdERROR;    TWI_Stop();    _delay_ms(5);    return pdSUCCESS;}/*从address地址读出N个数据,存放到*data中*/uint8_t FM_ReadNBytes( uint16_t address, uint8_t * data, uint16_t N ){    TWI_Start();    if(TWI_GetStatus()!=START)return pdERROR;    TWI_Write(WD_DEVICE_ADDR|(uint8_t)((address & 0x0700)>>7));    if(TWI_GetStatus()!=MT_SLA_ACK)return pdERROR;    TWI_Write((uint8_t)address);    if(TWI_GetStatus()!=MT_DATA_ACK)return pdERROR;    TWI_Start();    if(TWI_GetStatus()!=RE_START)return pdERROR;    TWI_Write(RD_DEVICE_ADDR|(uint8_t)((address & 0x0700)>>7));    if(TWI_GetStatus()!=MR_SLA_ACK)return pdERROR;    for(; N >1; N--)    {        TWI_ReadAck(*data++);        if(TWI_GetStatus()!=MR_DATA_ACK)return pdERROR;    }    TWI_Read(*data);    if(TWI_GetStatus()!=MR_DATA_NOACK)return pdERROR;    TWI_Stop();    _delay_ms(5);    return pdSUCCESS;}
原创粉丝点击