Problema de escritura EEPROM PIC18F452

Hola mis amigos programadores. Tengo un problema de escritura de EEPROM del PIC18F452. No puedo hacer que se guarden los datos en la eeprom utilizando la funcion EEPROM_WRITE(). Por el contrario la funcion EEPROM_READ() si funciona. Esto lo he comprobado porque al inicializar la memoria con __EEPROM_DATA() se guardan los datos que le paso como argumentos, pero cuando trato de cambiarlos con EEPROM_WRITE() no lo logro y permanencen iguales.

Estas funciones las he utilizado con exito programando el PIC16F877 con HI-TECH PICC LITE v.9.5.
Lo que pasa es que estoy pasando dicho programa al PIC18F452 porque tiene mas memoria y necesito incluir mas funcionalidades a un proyecto que estoy desarrollando.

La simulacion con proteus funciona bien. Pero al programar el micro, no funciona como debe ser. Estoy programando con WinPic800 y JDM.

Ya he configurado los fuses de diferentes maneras, pero nada.

Agradezco que me ayuden a solucionar este detalle porque hace parte de un proyecto.

Código:
/*
PROGRAMA PARA PROBAR LAS FUNCIONES DE ESCRITURA Y LECTURA DE LA EEPROM DEL
MICROCONTROLADOR PIC18F452

EDITADO CON:
MPLAB IDE v7.01,
COMPILADOR HI-TECH PICC18 PRO 9.63
*/

#include <htc.h>
#include "delay.h"


//Fuses Configuration
__CONFIG(1, XT); 					//
__CONFIG(2,BORDIS & WDTDIS); 		//BORDIS=brown out reset disabled, WDTDIS=watch dog timer disabled
//__CONFIG(3,CCP2RC1);				//--------------	
__CONFIG(4,DEBUGDIS & LVPDIS & STVRDIS); //DEBUGDIS=debug disabled, LVPDIS=low voltage programmin disabled
__CONFIG(5,UNPROTECT); 			//unprotected
__CONFIG(6,WRTEN); 				//
__CONFIG(7,TRU); 					//all unprotected including boot block


#define bit_set(var,bitno) ((var) |= 1 << (bitno))	//para escanear bits
#define bit_clr(var,bitno) ((var) &= ~(1 << (bitno)))
#define testbit(data,bitno) ((data>>bitno)&0x01)	//testear bit


unsigned char DATO=0;

__EEPROM_DATA(0, 0, 0, 0, 0, 0, 0, 0);  //INICIALIZAR LA EEPROM

void 
main(void)
{	
	int i=0;

	TRISD 	= 0;	//PUERTO D COMO SALIDA
	 PORTD 	=0; 

	PORTD = 0x02;		//ENCENDER EL LED EN RD0

	for(i=0; i<10 ; i++)		//RETARDO DE UN SEGUNDO APROX.
		DelayMs(100);

	PORTD 	= 0x00; 	//APAGAR EL LED EN RD0

	EEPROM_WRITE(0,0x11);
	EEPROM_WRITE(1,0x22);
	EEPROM_WRITE(2,0x33);
	EEPROM_WRITE(3,0x44);

	DelayMs(10);
	
	DATO = EEPROM_READ(0);	//LEER LA DIRECCION O DE LA EEPROM


	while(1){
		if(DATO == 0x11)  //SI LA VARIABLE LEIDA CORRESPONDE AL VALOR , SE ENCIENDE EL FLASHEA
		{	
				PORTD 	= 0x02; 
				DelayMs(100);
				PORTD 	= 0x00; 
				DelayMs(100);
		}
		else
			PORTD 	= 0x02; 
	}
}
 

Adjuntos

  • eepromtest_152.rar
    75.1 KB · Visitas: 45
Sube ese delay de 10ms de después de las EEPROM_WRITE a bastante más, creo recordar (hace mucho que no uso las EEPROM) que tardaban un huevo en grabarse. Empieza probando con 500ms y ve bajando...

Por si te sirve, te dejo unas funciones de lectura y escritura que funcionan en ese PIC (las usaba en un 18F442 que es igual que el 18F452). Son para el compilador MCC18 pero igual te dan alguna idea...

Código:
// Lectura de la EEPROM
unsigned char LeerEEPROM(unsigned char address) {
	unsigned char byte;   
	EEADR = address; // Dirección de memoria a leer de la EEPROM
	EECON1bits.EEPGD = 0; // Acceso a memoria de datos
	EECON1bits.CFGS = 0; // Acceso a la memoria
	EECON1bits.RD = 1; // Inicializa lectura de la EEPROM
	byte = EEDATA; // El dato está disponible justo un ciclo de instrucción más tarde
	return(byte);
}

// Escritura de la EEPROM
void EscribirEEPROM(unsigned char address, unsigned char data) {
	EEADR = address; // Dirección de memoria donde escribir el dato en la EEPROM
	EEDATA = data; // Dato a escribir
	EECON1bits.EEPGD = 0; // Acceso a memoria de datos
	EECON1bits.CFGS = 0; // Acceso a la memoria
	EECON1bits.WREN = 1; // Habilita escritura de la EEPROM
	EECON2 = 0x55; // Secuencia necesaria
	EECON2 = 0xAA; // Secuencia necesaria
	EECON1bits.WR = 1; // Comienza la escritura
	while(!PIR2bits.EEIF); // Esperar a que se complete la escritura (tarda unos pocos ms)
	EECON1bits.WREN = 0; // Deshabilita escritura de la EEPROM
	PIR2bits.EEIF = 0; // Bajar la bandera de interrupción
}
 
Gracias por tu opinion Ferny. Segui probando codigo pero sin resultados positivos con esta version de Hi-Tech para 18F. Lo de los fuses los configure de distintas formas pero nada. Probe con C18 y si pude grabar y leer la eeprom de datos. Finalmente retome un codigo para Pic16f877 con Hi-tech Picc Lite, depure todo el codigo posible para meter otra funcion y finalmente pude obtener el programa deseado con una ocupacion de 98.5 % de la memoria de programa.

Seguire trabajando con los 18F probando distintos compiladores, pero el Hi-Tech para 16F me gusta.

Hasta pronto.
 
Hola Jonathan gracias por tu concejo.

Bueno en cuanto a que hace el codigo, te comento: El codido del micro tiene distintas funciones que son, manejar una LCD 16x2, atender interrupciones de tres botones de pto B, leer la hora constantamente del chip DS1302. Ademas el menu presenta varias funciones que son leer los eventos programados por el usuario, programar eventos, borrar memoria de datos, reprogramar el reloj. Y tiene una funciones para procesar la hora leida del reloj para poder ser presentada en LCD, ademas de verificar coincidencias entre eventos programados y la hora leida.
 
Saludos a todos. Estoy realizando una libreria para una eeprom i2c. Tengo todas las funciones creadas y funcionando perfectamente exepto la de leer una cadena de bytes. No me explico que puede ser pero al simularlo solo me toma el primer caracter, y no es un problema de lectura propiamente dicho sino mas bien un problema de punteros o del propio compilador. Para simplificar la cuestion hago un ejemplo limpio sin las rutinas de eeprom propiamente dichas.
Todo esto esta compilado en Hi-Tech PICC 18 en un PIC18F4520.

Código:
void leer_cadena(char addr_mem, int pointer_addr, int *buffer, char cant_bytes)
{	
	for(char cnt = 0; cnt < cant_bytes; cnt++)
	{
		*buffer = cnt + 0x30; // convierto cnt en su valor pero en ascii para poder imprimir con printf %s como si fuera un string
		buffer++;
	}	
	return;
}

void main ()
{
	char buffer[10];

	leer_cadena(0xA0,0x00,&buf,10); // direccion de memoria, posicion en memoria, direccion de memoria del buffer, cantidad de bytes a leer
	printf(">>Texto leido: %s",buf);

	return;
}

En el simulador la salida seria la siguiente:
>>Texto: 0

cuando en realidad deberia ser
>>Texto: 0123456789

A alguien se le ocurre alguna idea con respecto al motivo de esta falla?
Muchas gracias!

Gonzalo

Edito: Solucionado con ayuda de un usuario de otro foro.

La definicion de la funciona leer_cadena esta mal. Deberia ser:
void leer_cadena(char addr_mem, int pointer_addr, char *buffer, char cant_bytes)
 
Última edición:
Atrás
Arriba