5 votos

Cómo guardar variables dentro de la memoria de los microcontroladores

Estoy diseñando una aplicación que incluye GSM SIM900 con PIC18F2520 . La aplicación incluye servicios básicos de llamadas y sms. El usuario presionará un botón para que se realice una llamada a un número definido. Este número puede ser cambiado a través de sms. Así que cada vez que se pulsa el botón de nuevo, la llamada se hará al nuevo número definido. Actualmente estoy usando estas variables para el número:

char callNumber1[10];
char callNumber2[10];
*
*
char callNumber5[10];

El problema al que me enfrento es que estas variables funcionan como se esperaba. Pero cuando apago la energía de la MCU, los datos almacenados en ellas se pierden. Quiero que los datos se mantengan como están después de apagar y puedan ser usados de nuevo después de encender. Cómo guardarlos en la memoria del MCU. Por favor, proporcione cualquier enlace donde pueda leer sobre la memoria en el MCU. Por favor, ayúdeme.

9 votos

The problem I am facing is these variables works as expected. Ese no es tu problema.

0 votos

Steve, ¿cuál es el objetivo de tu comentario?

20voto

Ale Puntos 407

Cualquier cosa que declare como variable en su código estará en la RAM del PIC, y por lo tanto desaparecerá cuando lo apague. Sin embargo, el PIC18F2580 tiene 256 bytes de memoria EEPROM, que no es volátil. Puedes almacenar allí tus números de teléfono cada vez que se modifiquen, y cargarlos al arrancar en tus variables.

Para leer y escribir un byte en una dirección determinada de la EEPROM, hay que utilizar la función EECON1 , EECON2 , EEDATL y EEADRL registros (véase el capítulo 8 de la hoja de datos ), por ejemplo:

uint8_t read_eeprom(uint8_t addr)
{
  EECON1 = 0;
  EEADRL = addr;
  EECON1bits.RD = 1;
  return EEDATL;
}

void write_eeprom(uint8_t addr, uint8_t value)
{
  EECON1 = 0;
  EEADRL = addr;           // address to write to
  EEDATL = value;          // value to write
  EECON1bits.WREN = 1;     // enable write
  EECON2 = 0x55;           // write unlock sequence
  EECON2 = 0xAA;
  EECON1bits.WR = 1;       // do the actual write
  EECON1bits.WREN = 0;     // disable writing
  while (EECON1bits.WR != 0);  // wait for the writing to complete
  EEIF = 0;                // clear EEPROM interrupt flag
}

Y luego puedes cargar tus números con algo como esto:

void load_number(const uint8_t start_addr, char* n, const int len)
{
  for (uint8_t i = 0; i < n; i++) {
    n[i] = read_eeprom(start_addr + i);
  }
}

load_number(0, callNumber1, 10);
load_number(10, callNumber2, 10);
// etc.

Y la misma idea para el ahorro. Para tener en cuenta que este código no está utilizando la memoria EEPROM muy eficientemente, porque el almacenamiento de los dígitos ASCII en ella desperdicia espacio. Si te ves limitado por los 256 bytes de EEPROM, podrías por ejemplo almacenar los números en formato BCD, teniendo así dos dígitos por byte.

A diferencia de la RAM, las memorias no volátiles como EEPROM y Flash tienen un número limitado de ciclos de escritura. Aunque este número es generalmente muy alto (1 millón de ciclos para la EEPROM del PIC18F2580), es una buena práctica no escribir en la memoria no volátil a menos que sea necesario es decir, los datos han sido realmente modificados y tienen que ser almacenados.

Si los datos deben escribirse periódicamente en una EEPROM o una memoria Flash, un algoritmo de nivelación del desgaste podría ser útil para distribuir uniformemente el desgaste de las células de memoria. Esto podría ser aún más importante con la memoria no volátil basada en Flash, que a menudo tiene menos ciclos de escritura que la EEPROM (por ejemplo, la memoria Flash del PIC18F2580 tiene "sólo" 100k ciclos de escritura de resistencia).

0 votos

Si no tienes EEPROM disponible, la mayoría de los micros (todos los que he conocido) permitirán que el firmware escriba en flash. No es tan rápido, fácil o de bajo consumo como la EEPROM, pero se puede hacer. Si tienes EEPROM, ese es definitivamente el camino a seguir.

8 votos

Aunque la EEPROM del PIC18F2520 tiene una especificación de 1M de ciclos de borrado/escritura, podría ser una buena idea mencionar ese tema. Podrías cubrirlo brevemente o apuntar a otras preguntas/recursos que cubran la mitigación del número de veces que se escribe la EEPROM (por ejemplo, sólo escribir al detectar la pérdida de energía, nivelación de desgaste, etc.). Aunque puede que no sea necesario en la situación específica de la OP, sería útil para la gente que vea esta pregunta y respuesta en el futuro, al menos haber mencionado que hay otras consideraciones además de pensar que deben almacenar alguna variable aleatoria en la EEPROM/FLASH.

0 votos

@Ale Gracias. Esto es genial. Estudié sobre la gestión de la memoria y probé este código y su trabajo. Antes de fusionar este código a mi código GSM existente, he probado mi código para el GSM. Apagué el MCU y lo encendí de nuevo y funcionó. Las variables definidas están incluso trabajando después de apagar. Ahora esto ha creado una gran confusión en mi mente. Cómo las variables están trabajando después de apagar. ¿Cómo los datos en las variables siguen siendo seguros?

14voto

jns Puntos 449

La SIM900 tiene en realidad su propia "agenda", que puedes utilizar para guardar los números. Ver AT+CPBW y comandos relacionados.

Ejemplos de la documentación. Escribir en la agenda:

AT+CPBW=, "13918 18xxxx",129, "Daniel"

Leer de la agenda:

AT+CPBF="Daniel"

devuelve

+CPBF:5, "13918186089",129,"Daniel"

Listar la agenda telefónica:

AT+CPBR=1,10

0 votos

Este método está muy bien pero el problema es que cuando guardamos los contactos, no nos dice la ubicación en la que se guarda el contacto. Ahora, si quiero modificarlo, primero tenemos que borrar el contacto. Al borrarlo nos pide la ubicación de los contactos que no conocemos. Aunque puedo usar AT+CPBR para listar todos los contactos pero eso listará todos los datos de los contactos que desbordarán el buffer. No elimina el contacto usando el nombre.

0 votos

@Andrew ¿No hay un comando para cambiar simplemente el número de un contacto? Es un caso de uso básico.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X