|
技术交流 | 电路欣赏 | 工控天地 | 数字广电 | 通信技术 | 电源技术 | 测控之家 | EMC技术 | ARM技术 | EDA技术 | PCB技术 | 嵌入式系统 驱动编程 | 集成电路 | 器件替换 | 模拟技术 | 新手园地 | 单 片 机 | DSP技术 | MCU技术 | IC 设计 | IC 产业 | CAN-bus/DeviceNe |
我用GCC写的AT24C64接口程序,已调试通过,与大家分享 |
作者:mxh0506 栏目:单片机 |
一段小程序,没用仿真器,费了很大力气才除去所有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 于 2003/8/1 14:43:00 发布:
谢谢. 十分感谢. 不知是否可以对程序进行详细一点的注释, 或者对各函数的用法进行简要说明. 谢谢. |
3楼: | >>参与讨论 |
作者: mxh0506 于 2003/8/5 20:49:00 发布:
各函数说明: 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楼: | >>参与讨论 |
作者: 天空克理斯 于 2003/8/5 23:27:00 发布:
支持! 提问:如果不考虑价格因素,你选择ICC还是GCC? |
5楼: | >>参与讨论 |
作者: yongyizhou 于 2003/8/7 8:24:00 发布:
注释呢? |
6楼: | >>参与讨论 |
作者: 何以不胜 于 2003/8/7 16:01:00 发布:
安定 |
7楼: | >>参与讨论 |
作者: mxh0506 于 2003/8/7 20:32:00 发布:
yongyizhou:关键的注释都已经写在程序里了 细节部分要自己琢磨一下了,如有问题,可以参考24C64和ATMEGA128的手册。 |
8楼: | >>参与讨论 |
作者: wuwuping 于 2003/8/11 14:44:00 发布:
请问:有菲利浦RC500的中文资料或下载吗?谢谢,wwp@jucid.com |
9楼: | >>参与讨论 |
作者: bananawin 于 2006/11/14 15:02:00 发布:
byEEWait怎么用? byEEWait是一个延时函数吗?是怎么用的? |
|
|
免费注册为维库电子开发网会员,参与电子工程师社区讨论,点此进入 |
Copyright © 1998-2006 www.dzsc.com 浙ICP证030469号 |