⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eeprom.c

📁 AVR单片机的EEPROM的读写程序, 通过TWI接口读写.
💻 C
字号:
/************************************************************
 * Copyright (c) 2004-2005, POWERCOM Co., All Rights Reserved.
 * File        :"eeprom.c"
 * Description :

 * Author      : Xu Hailun
 * Date        : 2003-08-29
 * Version     : 1.0
 * Revisions   :
 ************************************************************/
 
//#include "..\inc\def.h"
#include "..\inc\all.h"
#include <inavr.h>
#define MAX_EEPROM_WAIT			10000

extern void delayx(uint x);
extern void Save_Log(uchar sel0,uchar sel1);
extern uint crc_fun(uint InitCRCValue,uchar *pbuf, uint numc);

__no_init uchar EEBuf[264] @ ESRAM_EEPROM_BUF;
void WRITE_EEPROM(uint START_ADDR, uint NUM)
{
	uint i;
	uint l;
	uchar cSREG;
	cSREG = SREG;
	asm("cli");
	for(i=0;i<NUM;i++){
		l = 0;
		while (chkbit(EECR,EEWE)){
			l++;
//			if(l>MAX_EEPROM_WAIT) goto ErrProc;
		}
		EEAR = START_ADDR+i;
		EEDR = EEBuf[i];
		setbit(EECR,EEMWE);
		setbit(EECR,EEWE);
		asm("wdr");//clear watchdog counter.
	}
	SREG = cSREG;
	asm("sei"); // enable interrupts
//ErrProc:
//	SREG = cSREG;
//	asm("sei"); // enable interrupts
//	return 1;
}

void READ_EEPROM(uint START_ADDR, uint NUM)
{
	uint i;
	uint l;
	uchar cSREG;
	cSREG = SREG;
	asm("cli");
	for(i=0;i<NUM;i++){
		l = 0;
		while (chkbit(EECR,EEWE)){
			l++;
			//if(l>MAX_EEPROM_WAIT) goto ErrProc;
		}
		EEAR = START_ADDR+i;
		setbit(EECR,EERE);
		EEBuf[i] = EEDR;
		asm("wdr");//clear watchdog counter.
	}
	SREG = cSREG;
	asm("sei"); // enable interrupts
//ErrProc:
//	SREG = cSREG;
//	asm("sei"); // enable interrupts
//	return 1;
}

/*=========================24c04================================
#ifdef __EXTEND_24C04__
#define EE_SCL      PORTC5
#define EE_SDA      PORTC4
uchar EE_DATA,WORD_ADDR;
ushort EE_ADDR;
void EE_CMD(uchar CTRL_BYTE, ushort OP_ADDR)
{
//	uchar WORD_ADDR;
//	uchar i;
	// Set page block address 
	if (OP_ADDR > 0xFF)	CTRL_BYTE = CTRL_BYTE | 0x02;
	// Get word address
	WORD_ADDR = OP_ADDR;
	// Start bit  
	clrbit(PORTC,EE_SCL);
	setbit(PORTC,EE_SDA);
	setbit(PORTC,EE_SCL);
	clrbit(PORTC,EE_SDA);

	for(i = 0 ; i <= 7;i++)
	{
		clrbit(PORTC,EE_SCL);
		if ((CTRL_BYTE & 0x80) == 0) clrbit(PORTC,EE_SDA);
		else setbit(PORTC,EE_SDA);

		setbit(PORTC,EE_SCL);
		CTRL_BYTE = CTRL_BYTE<<1;

	}

	// Acknowledge clock 
	clrbit(PORTC,EE_SCL);
	setbit(PORTC,EE_SCL);

	// Word address 
	for(i = 0 ; i<= 7;i++)
	{
		clrbit(PORTC,EE_SCL);
		if ((WORD_ADDR & 0x80) == 0) clrbit(PORTC,EE_SDA);
		else setbit(PORTC,EE_SDA);
		setbit(PORTC,EE_SCL);
		WORD_ADDR = WORD_ADDR<<1;
	}
	// Acknowledge clock 
	clrbit(PORTC,EE_SCL);
	setbit(PORTC,EE_SCL);
}

void UPDATE_EEPROM1(ushort START_ADDR, ushort NUM)
{
	for(j = 0; j<= NUM-1;j++)
	{
		EE_ADDR = START_ADDR + j;
		EE_DATA = EEBuf[j];
		EE_CMD(0xA0, EE_ADDR);

		for(i = 0;i <= 7; i++)
		{
			clrbit(PORTC,EE_SCL);
			if ((EE_DATA & 0x80) > 0) setbit(PORTC,EE_SDA);
			else clrbit(PORTC,EE_SDA);
			setbit(PORTC,EE_SCL);
			EE_DATA = EE_DATA<<1;
		}
		// Acknowledge clock
		clrbit(PORTC,EE_SCL);
		setbit(PORTC,EE_SCL);

		// Stop bit  
		clrbit(PORTC,EE_SCL);
		clrbit(PORTC,EE_SDA);
		setbit(PORTC,EE_SCL);
		setbit(PORTC,EE_SDA);

		DDRC=0x2c;
		// Acknowledge polling  
		clrbit(PORTC,EE_SCL);
		k = 0;
		setbit(PORTC,EE_SCL);
		while (chkbit(PINC,EE_SDA) && (k < 1000))
		{
//			clrbit(PORTC,EE_SCL);
			k++;
			asm("wdr");//clear watchdog counter.
//			setbit(PORTC,EE_SCL);
		}
		DDRC=0x3c;		
	}
}

void LOAD_EEPROM1(ushort START_ADDR, ushort NUM)
{
	for (j = 0; j <= NUM-1;j++)
	{
		EE_DATA = 0;
		EE_ADDR = START_ADDR + j;
		EE_CMD(0xA0, EE_ADDR);

		// Start bit 
		clrbit(PORTC,EE_SCL);
		setbit(PORTC,EE_SDA);
		setbit(PORTC,EE_SCL);
		clrbit(PORTC,EE_SDA);

		// Random read contro2l byte 
		for( i = 0 ;i <= 7;i++)
		{
			clrbit(PORTC,EE_SCL);
			switch(i)
			{
				case 0:
				case 2:
				case 7:setbit(PORTC,EE_SDA);break;
				case 1:
				case 3:
				case 4:
				case 5:clrbit(PORTC,EE_SDA);break;
				case 6:
					if(j > 0xFF) setbit(PORTC,EE_SDA);
					else clrbit(PORTC,EE_SDA);
			}
			setbit(PORTC,EE_SCL);

		}

		// Acknowledge clock
		clrbit(PORTC,EE_SCL);
		setbit(PORTC,EE_SCL);

		DDRC=0x2c;
		for(i = 0;i<= 7;i++)
		{
			clrbit(PORTC,EE_SCL);
			EE_DATA = EE_DATA << 1;
			if (chkbit(PINC,EE_SDA))
				EE_DATA = EE_DATA | 1;
			setbit(PORTC,EE_SCL);
		}

		clrbit(PORTC,EE_SCL);
		setbit(PORTC,EE_SDA);
		setbit(PORTC,EE_SCL);

		EEBuf[j] = EE_DATA;
		DDRC=0x3c;
		// Stop bit 
		clrbit(PORTC,EE_SCL);
		clrbit(PORTC,EE_SDA);
		setbit(PORTC,EE_SCL);
		setbit(PORTC,EE_SDA);
		asm("wdr");//clear watchdog counter.
	}
}

void test_Init()
{
	EEBuf[0] = 0xaa;
	for(l=0;l<511;l++) UPDATE_EEPROM1(l,1);
	l=0;
	for(;;){
		LOAD_EEPROM1(l,1);
		if(EEBuf[0] == 0xaa){
			EEBuf[0] = 0;
			l = (l+1)%512;
			if(l==511) return;
		}
		else for(;;);
	}
}
#endif
**********************************************************************/

void UPDATE_EEPROM(uint START_ADDR, uint NUM)
{//保存的数据同时保存到1,2区.
#ifdef __DEBUG_FLAG__
	return;
#else
	uint v1;//,offset;
	uchar *cpstr,len,i, cReg,cReg1;//pstr_h
	cReg = UCSR0B;
	cReg1 = UCSR1B;
	UCSR0B = 0;
	UCSR1B = 0;
	if(/*(START_ADDR >= EE_EQUIPINFO) &&*/ (START_ADDR < EE_NETPARA))
	{
		cpstr = (uchar *) &EqInfo;
		len = sizeof(EqInfo);
		//pstr_h = START_ADDR - EE_EQUIPINFO;
		//offset = EE_EQUIPINFO + len;
	}
	else if((START_ADDR >= EE_NETPARA) && (START_ADDR < EE_NETPARA1))
	{
		cpstr = (uchar *) &NetPara;
		len = sizeof(NetPara);
		//pstr_h = START_ADDR - EE_NETPARA;
		//offset = EE_NETPARA + len;
	}
	else if((START_ADDR >= EE_NETPARA1) && (START_ADDR < EE_NETPARA2))
	{
		cpstr = (uchar *) &NetPara1;
		len = sizeof(NetPara1);
		//pstr_h = START_ADDR - EE_NETPARA1;
		//offset = EE_NETPARA + len;
	}
	else if((START_ADDR >= EE_NETPARA2) && (START_ADDR < EE_CONPARA))
	{
		cpstr = (uchar *) &NetPara2;
		len = sizeof(NetPara2);
		//pstr_h = START_ADDR - EE_NETPARA2;
		//offset = EE_NETPARA + len;
	}
	else if((START_ADDR >= EE_CONPARA) && (START_ADDR < EE_FACTORY))
	{
		cpstr = (uchar *) &ConPara;
		len = sizeof(ConPara);
		//pstr_h = START_ADDR - EE_CONPARA;
		//offset = EE_CONPARA + len;
	}
	else if((START_ADDR >= EE_FACTORY) && (START_ADDR < EE_CCMCOBJMAPPING))
	{
		//cpstr = (uchar *) &RptPara;
		//len = sizeof(RptPara);
		//pstr_h = START_ADDR - EE_FACTORY;
		//offset = EE_FACTORY + len;
		return;
	}
	else if((START_ADDR >= EE_CCMCOBJMAPPING) && (START_ADDR < EE_ALARMPROC))
	{
	    cpstr = (uchar *) &CMCCObjMapping;
	    len = sizeof(CMCCObjMapping);
	}
	else if((START_ADDR >= EE_ALARMPROC))
	{
	    cpstr = (uchar *) &AlarmProcPara;
	    len = sizeof(AlarmProcPara);
	}
//	else if((START_ADDR >= EE_CCMCOBJMAPPING))
//	{
//		cpstr = (uchar *) &CMCCObjMapping;
//		len = sizeof(CMCCObjMapping);
//		//pstr_h = START_ADDR - EE_CCMCOBJMAPPING;
//		//offset = EE_CCMCOBJMAPPING + len;
//	}
	v1 = crc_fun(0, cpstr, len); //计算检验和
	//for(i = 0; i < NUM; i++) EEBuf[i] = cpstr[pstr_h+i];
	for(i = 0; i < NUM; i++) EEBuf[i] = cpstr[i];
	EEBuf[NUM] = v1 & 0xff;
	EEBuf[NUM+1] = (v1 >> 8) & 0xff;

	WRITE_EEPROM( __BACKUP_AREA0__ + START_ADDR,  NUM+2);
#ifdef __BACKUP_E2PROM__
	WRITE_EEPROM( __BACKUP_AREA1__ + START_ADDR,  NUM+2);
#endif

/*	WRITE_EEPROM( __BACKUP_AREA0__ + START_ADDR,  NUM);
#ifdef __BACKUP_E2PROM__
	WRITE_EEPROM( __BACKUP_AREA1__ + START_ADDR,  NUM);
#endif

	EEBuf[0] = v1 & 0xff;
	EEBuf[1] = (v1 >> 8) & 0xff;
	WRITE_EEPROM( __BACKUP_AREA0__ + offset,  2);
#ifdef __BACKUP_E2PROM__
	WRITE_EEPROM( __BACKUP_AREA1__ + offset,  2);
#endif*/
	UCSR0B = cReg;
	UCSR1B = cReg1;
#endif
}

uchar LOAD_EEPROM(uint START_ADDR, uint NUM)
{
#ifdef __DEBUG_FLAG__
	return 0;
#else
	uint v1, v2;
	uchar ok = 0;
	
	READ_EEPROM( __BACKUP_AREA0__ + START_ADDR,  NUM+2);
	v1 = crc_fun(0, EEBuf, NUM);
	v2 = EEBuf[NUM] + (EEBuf[NUM+1]<<8);
	
	if(v1 == v2) ok = 1;
#ifdef __BACKUP_E2PROM__
	READ_EEPROM( __BACKUP_AREA1__ + START_ADDR,  NUM+2);
	v1 = crc_fun(0, EEBuf, NUM);
	v2 = EEBuf[NUM] + (EEBuf[NUM+1]<<8);
	if(v1 == v2) ok = ok+2;
	
	if(ok == 1)
	{//第一区的数据正确,第二区数据错误, 用1区数据覆盖2区数据
		READ_EEPROM( __BACKUP_AREA0__ + START_ADDR,  NUM+2);
		WRITE_EEPROM( __BACKUP_AREA1__ + START_ADDR,  NUM+2);
		return 1;
	}
	else if(ok == 2)
	{//1区数据错误,2区数据正确, 用2区数据覆盖1区数据
		READ_EEPROM( __BACKUP_AREA1__ + START_ADDR,  NUM+2);
		WRITE_EEPROM( __BACKUP_AREA0__ + START_ADDR,  NUM+2);
		return 1;
	}
	else if(ok == 3) //1,2区的数据全部正确
		return 1;
#else
	if(ok)
		return 1;
#endif
	return 0;
#endif
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -