网站公告列表

  没有公告

加入收藏
设为首页
联系站长
您现在的位置: 61IC中国电子在线 >> 技术文库 >> 嵌入式 >> 文章正文
  用GCC写的AT24C64接口程序 已调试通过         ★★★ 【字体:
用GCC写的AT24C64接口程序 已调试通过
作者:61IC录入    文章来源:本站原创    点击数:    更新时间:2006-4-7    

一段小程序,没用仿真器,费了很大力气才除去所有BUG。
希望今后大家多交流,让我们这些做程序的人日子过得舒服些。
//////////////////////////////////////////////////////////////////////////
// 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 <avr/twi.h>

// 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<<TWINT))){    // wait
        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<<TWINT)|(1<<TWEN);
    while (!(TWCR & (1<<TWINT))){
        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<<TWINT)|(1<<TWEN);
        byEEWait = 3;    // 20~30ms
        while (!(TWCR & (1<<TWINT))){
            if( byEEWait == 0 )
                return FALSE;
        }
        if(TWI_STATUS != TW_MT_DATA_ACK){
            return FALSE;
        }
        TWDR = (BYTE)(i&0x00ff);            // LSB of address
        TWCR = (1<<TWINT)|(1<<TWEN);
        byEEWait = 3;    // 20~30ms
        while (!(TWCR & (1<<TWINT))){
            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<<TWINT)|(1<<TWEN);
            byEEWait = 3;    // 20~30ms
            while (!(TWCR & (1<<TWINT))){
                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 < uiLen );
//    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<<TWINT)|(1<<TWEN);
    byEEWait = 3;    // 20~30ms
    while (!(TWCR & (1<<TWINT))){
        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<<TWINT)|(1<<TWEN);
    byEEWait = 3;    // 20~30ms
    while (!(TWCR & (1<<TWINT))){
        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<uiLen-1; i++ ){
        TWCR = _BV(TWINT)|_BV(TWEN)|_BV(TWEA);
        byEEWait = 3;    // 20~30ms
        while (!(TWCR & (1<<TWINT))){
            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<<TWINT))){
        if( byEEWait == 0 )
            return FALSE;
    }
    //if (TWI_STATUS != TW_MR_DATA_ACK)
    //    return FALSE;
    ((BYTE*)pBuf)[i] = TWDR;
    TwiStop();
    return 1;
}

               欢迎点击进入:TI德州中文网   (国内唯一针对TI应用的中文技术网站)    文章录入:admin    责任编辑:admin 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    站长:61IC 湘ICP备05002478号