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

用GCC写的AT24C64接口程序

发布时间:2024-10-22 发布时间:
|

// AT24C64 support functions using ATMEGA's TWI 

// PIN-WP is hard-wired to GND 
// fuctions work better outside interrupt routines 
// by MXH, 2003/07/30 

#include "DStruct.h" 
#include  

// CONSTANTS DEFINITION FOR EEPROM 
#define EEADDR        0 
#define EEWR        0 
#define EERD        1 
// TWINT *NOT* set after STOP condition is sent 
// check status? 
// TWSTO is cleared by hardware 
#define TwiStop()    TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO) 
#define TwiStart()    TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTA) 
#define TWI_STATUS    (TWSR & 0xF8) 

BYTE byEEWait; 

////////////////////////////////////////////////////////////////////////// 
// implementation 

BOOL EEPStart(BYTE addr, BOOL bWrite) 

    byEEWait = 10;    // 90~100ms 
poll_ack: 
    TwiStart(); 
    while (!(TWCR & (1<        if ( byEEWait == 0 ){ 
            return FALSE; 
        } 
    } 
    if ((TWI_STATUS != TW_START)&&(TWI_STATUS != TW_REP_START)) 
        goto poll_ack; 
    //byEEWait = 3;    // 20~30ms 
    // send SLA+R/W 
    TWDR = addr | bWrite; 
    TWCR = (1<    while (!(TWCR & (1<        if( byEEWait == 0 ){ 
            TwiStop(); 
            return FALSE; 
        } 
    } 
    if( EEWR == bWrite ){    // MT mode 
        //if(TWI_STATUS != TW_MT_SLA_ACK) 
        switch(TWI_STATUS){ 
            case TW_MT_SLA_ACK: 
                break; 
            case TW_MT_SLA_NACK: 
                goto poll_ack; 
            default: 
                TwiStop(); 
                return FALSE; 
        } 
    }else{                    // MR mode 
        if(TWI_STATUS != TW_MR_SLA_ACK) 
            return FALSE; 
    } 
    return TRUE; 


////////////////////////////////////////////////////////////////////// 
//  
BYTE EEPWrite( WORD uiAddress, WORD uiLen, void *pBuf ) //using 0 

    unsigned int i,j,uICnt; 
     
    if( uiLen == 0 ) return 0; 
    uiCnt = 0; 
//    uiEnd = uiAddress + uiLen; 
    i = uiAddress; 
    do{ 
        if(!EEPStart(0xA0|EEADDR,EEWR)){    //PollAck() is built-in 
            return 0; 
        } 
        TWDR = (BYTE)((i>>8)&0x00ff);        // MSB of address 
        TWCR = (1<        byEEWait = 3;    // 20~30ms 
        while (!(TWCR & (1<            if( byEEWait == 0 ) 
                return FALSE; 
        } 
        if(TWI_STATUS != TW_MT_DATA_ACK){ 
            return FALSE; 
        } 
        TWDR = (BYTE)(i&0x00ff);            // LSB of address 
        TWCR = (1<        byEEWait = 3;    // 20~30ms 
        while (!(TWCR & (1<            if( byEEWait == 0 ) 
                return FALSE; 
        } 
        if(TWI_STATUS != TW_MT_DATA_ACK) 
            return FALSE; 
        // write data 
        for( j=0; j<32; j++ ){ 
            TWDR = ((BYTE*)pBuf)[uiCnt]; 
            TWCR = (1<            byEEWait = 3;    // 20~30ms 
            while (!(TWCR & (1<                if( byEEWait == 0 ) 
                    return FALSE; 
            } 
            if(TWI_STATUS != TW_MT_DATA_ACK){ 
                return FALSE; 
            } 
            i++; 
            uiCnt++; 
            if(( 0 == i%32 )||( uiCnt == uiLen )){ 
                TwiStop(); 
                break; 
            } 
        } 
    }while( uiCnt //    while( !PollAck()); 
    return 1; 


////////////////////////////////////////////////////////////////////// 
//  
BYTE EEPRead( WORD uiAddress, WORD uiLen, void *pBuf ) 

    UINT i; 
     
    if ( uiLen == 0 ) return 0; 
    if(!EEPStart(0xA0|EEADDR,EEWR)){    //PollAck() is built-in 
        return 0;             //↑ 
    }    // not RD but write device address to the Chip 
    TWDR = (BYTE)(( uiAddress >> 8) & 0x00ff );    //((BYTE*)(&uiAddress))[1];    // MSB of address 
    TWCR = (1<    byEEWait = 3;    // 20~30ms 
    while (!(TWCR & (1<        if( byEEWait == 0 ) 
            return FALSE; 
    } 
    if (TWI_STATUS != TW_MT_DATA_ACK) 
        return FALSE; 
    TWDR = (BYTE)( uiAddress & 0x00ff );    //((BYTE*)(&uiAddress))[0];        // LSB of address 
    TWCR = (1<    byEEWait = 3;    // 20~30ms 
    while (!(TWCR & (1<        if( byEEWait == 0 ) 
            return FALSE; 
    } 
    if (TWI_STATUS != TW_MT_DATA_ACK) 
        return FALSE; 
    if(!EEPStart(0xA0+EEADDR,EERD)){    //PollAck()){ 
        return 0;             //↑ 
    }// ??? how to read? 
    for ( i=0; i        TWCR = _BV(TWINT)|_BV(TWEN)|_BV(TWEA); 
        byEEWait = 3;    // 20~30ms 
        while (!(TWCR & (1<            if( byEEWait == 0 ) 
                return FALSE; 
        } 
        if (TWI_STATUS != TW_MR_DATA_ACK) 
            return FALSE; 
        ((BYTE*)pBuf)[i] = TWDR;    // EEInByte(); 
    } 
    TWCR = _BV(TWINT) | _BV(TWEN);    // send NACK to inDICate final byte 
    byEEWait = 3;    // 20~30ms 
    while (!(TWCR & (1<        if( byEEWait == 0 ) 
            return FALSE; 
    } 
    //if (TWI_STATUS != TW_MR_DATA_ACK) 
    //    return FALSE; 
    ((BYTE*)pBuf)[i] = TWDR; 
    TwiStop(); 
    return 1; 


关键字:GCC  AT24C64  接口程序 

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

热门文章 更多
msp430ADC程序