登录 免费注册 首页 | 行业黑名单 | 帮助
维库电子市场网
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统
驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe

我用GCC写的AT24C64接口程序,已调试通过,与大家分享

作者:mxh0506 栏目:单片机
我用GCC写的AT24C64接口程序,已调试通过,与大家分享
一段小程序,没用仿真器,费了很大力气才除去所有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 )){
     
2楼: >>参与讨论
blackthick
谢谢.
十分感谢.
不知是否可以对程序进行详细一点的注释,
或者对各函数的用法进行简要说明.
谢谢.

3楼: >>参与讨论
mxh0506
各函数说明:
BOOL EEPStart(BYTE addr, BOOL bWrite)
用于产生开始条件及应答轮询,addr是EEPROM存储单元地址(非器件地址),bWrite是读写选择,0为写,1为读(参见程序头部的宏定义)
此函数主要由其它两个函数调用,最终使用时可以不深究

BYTE EEPWrite( WORD uiAddress, WORD uiLen, void *pBuf )
BYTE EEPRead( WORD uiAddress, WORD uiLen, void *pBuf )
uiAddress是EEPROM存储单元地址(非器件地址);
uiLen是要写的数据字节数;
pBuf是数据缓冲区首地址

用法:
struct DEV_CFG config;
// set configure values...
EEPWrite( EEP_DEV_CFG,sizeof(config),&config); // save to EEPROM
// read configure from EEPROM
EEPRead( EEP_DEV_CFG,sizeof(config),&config);




4楼: >>参与讨论
天空克理斯
支持!
提问:如果不考虑价格因素,你选择ICC还是GCC?

5楼: >>参与讨论
yongyizhou
注释呢?
 
6楼: >>参与讨论
何以不胜
安定
 
7楼: >>参与讨论
mxh0506
yongyizhou:关键的注释都已经写在程序里了
细节部分要自己琢磨一下了,如有问题,可以参考24C64ATMEGA128的手册。

8楼: >>参与讨论
wuwuping
请问:有菲利浦RC500的中文资料或下载吗?谢谢,wwp@jucid.com
 
9楼: >>参与讨论
bananawin
byEEWait怎么用?
byEEWait是一个延时函数吗?是怎么用的?

参与讨论
昵称:
讨论内容:
 
 
相关帖子
请教ic卡设计方案
请教个问题
M48的中断机制导致计时失误!
请问AVRISP  MKii的6个引脚分别接什么?(原来用10脚的座)
ATMEGA8-16AC可否用ATMEGA8-16PC替换
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入


Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号