July 22nd, 2017

Einstellungen im EEPROM eines AVR speichern2

Es gibt kaum eine Anwendung in der man keine Einstellungen speichern möchte. Doch wenn man sich schon den Aufwand macht Einstellungen zu speichern, sollten diese nach dem Reset auch wieder abrufbar sein. Daher wird so etwas im EEPROM gespeichert und ausgelesen. Wie man das ganz sinnvoll programmieren kann folgt hier:

Am sinnvollsten überlegt man sich vorher was zu speichern ist, dann erstellt man gesondert dafür eine Sourcedatei mit deren Header. Im Header erfolgt die Definition der Benötigten Bytes:

#define EEPROM_SECTION  __attribute__ ((section (".eeprom")))

/*
** this global variables are stored in EEPROM
*/
uint16_t  dummy          EEPROM_SECTION  = 0;  // avoid using lowest addresses

//——————————————————————————
// section 1: default settings
uint8_t   eeprom_def_brightness EEPROM_SECTION  = 1;  // EEPROM address 0002
uint16_t  eeprom_def_TempID     EEPROM_SECTION  = 2;  // EEPROM address 0003
uint8_t   eeprom_def_TempUnit   EEPROM_SECTION  = 3;  // EEPROM address 0005
uint16_t  eeprom_def_Filter     EEPROM_SECTION  = 4;  // EEPROM address 0006
uint8_t   eeprom_def_CANspeed   EEPROM_SECTION  = 5;  // EEPROM address 0008

// placeholder
uint16_t  eeprom_def_dummy1     EEPROM_SECTION  = 6;  // EEPROM address 0009
uint16_t  eeprom_def_dummy2     EEPROM_SECTION  = 7;  // EEPROM address 000B
uint8_t   eeprom_def_dummy3     EEPROM_SECTION  = 8;  // EEPROM address 000D
uint8_t   eeprom_def_dummy4     EEPROM_SECTION  = 9;  // EEPROM address 000E
uint8_t   eeprom_def_dummy5     EEPROM_SECTION  = 10; // EEPROM address 000F

//——————————————————————————
// section 2: user settings
uint8_t   eeprom_usr_brightness EEPROM_SECTION  = 11;  // EEPROM address 0010
uint16_t  eeprom_usr_TempID     EEPROM_SECTION  = 12;  // EEPROM address 0011
uint8_t   eeprom_usr_TempUnit   EEPROM_SECTION  = 13;  // EEPROM address 0013
uint16_t  eeprom_usr_Filter     EEPROM_SECTION  = 14;  // EEPROM address 0014
uint8_t   eeprom_usr_CANspeed   EEPROM_SECTION  = 15;  // EEPROM address 0016

// placeholder
uint16_t  eeprom_usr_dummy11    EEPROM_SECTION  = 16;  // EEPROM address 0017
uint16_t  eeprom_usr_dummy12    EEPROM_SECTION  = 17;  // EEPROM address 0019
uint8_t   eeprom_usr_dummy13    EEPROM_SECTION  = 18;  // EEPROM address 001B
uint8_t   eeprom_usr_dummy14    EEPROM_SECTION  = 19;  // EEPROM address 001C
uint8_t   eeprom_usr_dummy15    EEPROM_SECTION  = 20;  // EEPROM address 001D

Anschließend werden in der Sourcedatei die entsprechend der Reservierung benötigten Funktionen erstellt um die Werte zu lesen/schreiben.

#include <stdbool.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/eeprom.h>
#include "eeprom_access.h"

// returns the dataset from eeprom
uint16_t get_eeprom_word(uint8_t setting)
{
  uint16_t   eeprom_word;

  switch (setting)
  {
    case 12:
      eeprom_word = eeprom_read_word( &eeprom_usr_TempID );
      break;
    case 14:
      eeprom_word = eeprom_read_word( &eeprom_usr_Filter );
      break;
    default:
      break;
  }
  return eeprom_word;
}

// save data to eeprom
void set_eeprom_word( uint16_t eeprom_word, uint8_t setting )
{
  switch (setting)
  {
    case 12:
      eeprom_write_word( &eeprom_usr_TempID, eeprom_word );
        break;
    case 14:
      eeprom_write_word( &eeprom_usr_Filter, eeprom_word );
        break;
    default:
      break;
  }
}

// returns the dataset from eeprom
uint8_t get_eeprom_byte(uint8_t setting)
{
  uint8_t   eeprom_byte;

  switch (setting)
  {
    case 15:
      eeprom_byte = eeprom_read_byte( &eeprom_usr_CANspeed );
        break;
    default:
      break;
  }

  return eeprom_byte;
}

// save data to eeprom
void set_eeprom_byte( uint8_t eeprom_byte, uint8_t setting )
{
  switch (setting)
  {
    case 15:
      eeprom_write_byte( &eeprom_usr_CANspeed, eeprom_byte );
        break;
    default:
      break;
  }
}

In der main-Datei (oder wo man die Funktion aufrufen möchte) muss anschließend definiert werden wie die Einstellungen heißen und die externen Funktionen deklariert werden.

//——–
// EEPROM
//——–
// settings
#define CAN_Speed 15
#define CAN_Filter 14
#define Temp_ID 12

extern void set_eeprom_byte( uint8_t eeprom_byte, uint8_t setting );
extern uint8_t get_eeprom_byte(uint8_t setting);
extern void set_eeprom_word( uint16_t eeprom_word, uint8_t setting );
extern uint16_t get_eeprom_word(uint8_t setting);

Der Aufruf aus der main-Datei könnte dann wie folgt aussehen:

CANspeed = get_eeprom_byte(CAN_Speed);

set_eeprom_byte(CANspeed, CAN_Speed);

Tags: , ,


Alientech Powergate im Check4

Ich hatte neulich mal die Gelegenheit ein ECU-flasher (Programmiergerät für Motorsteuergerät) zu testen. Das Gerät kam aus dem Hause Alientech und nennt sich Powergate Pro. Interessant zu sehen fand ich, dass auch hier ein AT90CAN128 als Controller verwendet wurde, ein recht bekannter Chip mit integriertem CAN Controller und einigen mächtigen Features. Daneben platzierte man die üblichen Verdächtigen wie FT245BL, M6636B, 7805C, PCA82C250 und vier Flashbausteine a 16MB AT45DB161.

powergate

Zu sagen ist, dass die Komponenten recht gut verlötet sind und sehr sauber platziert. Die Leiterbahnverlegung und Anordnung der Controller halte ich allerdings für fragwürdig. Negativ anzumerken ist, dass ein Fahrzeug nur einmal geflasht werden kann.

Tags: , ,


Imhotep theme designed by Chris Lin. Proudly powered by Wordpress.
XHTML | CSS | RSS | Kommentare-RSS