Neue Entwicklungstools kosten immer Zeit. Aber manchmal kann sich der Aufwand lohnen und ein Mikrocontroller ist keine gute Debugging-Plattform für Algorithmen.

Ich hab's jetzt mal mit Eclipse-CDT probiert, damit kann man gut durchs Programm steppen.

Mein ( Dein )Programm wirft allerdings folgends aus:
Gucki running
error, no pattern

Code:
#define RUNNING_ON_PC

#define NUMBEROFNEURONS 30

//********************** RUNNIN ON PC ***********************************
#ifdef RUNNING_ON_PC
#include <iostream>
#include <stdint.h>
using namespace std;

#define FOREVER while(1)
typedef uint8_t uns8; // stdint.h compatibility
typedef bool   BOOL;
#define FALSE  0
#define TRUE   1

// funktioniert nicht
static unsigned char* FSR;
#define INDF (*FSR)

#define LINK_SRC 0
#define LINK_DST 1
#define LINK_USE 2

/*
#define src 0
#define dst 1
#define use 2
*/
#endif
//************************** RUNNING ON PIC ***************************************

#ifdef PIC
#include "allpic.h"
#pragma config = 0b000110000100     // hex-datei: fuses des 12F629

#pragma cdata[0x2100] =            \
  0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,\
  0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,\
  0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,\
  0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,\
  0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,\
  0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,\
  0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,0xFF,0,0,\
  0xFF,0xFF                // eeprom initialisierung

#define EE_ROM                // eeprom nutzen
#include "pic_mem.h"

#include "timeloop.h"

// LINK-Zugriffe
#define LINK_RD(a,m)    ee_read((a) + offsetof(struct _link,m))
#define LINK_WR(a,m,v)    ee_write((a) + offsetof(struct _link,m),v)
#endif


#define OUT_0        0        // GPIO
#define OUT_1        1        //
#define OUT_2        2        //
#define IN_2        3        //
#define IN_1        4        //
#define IN_0        5        //

//** alle sensoren, aktoren, triebe und neuronen nach abstraktion gestaffelt ******
uns8 zellen[30];            // zellen im RAM anlegen

#define FIRE_LIMIT    10        // fire_limit

#define RD_SUM        (INDF & 0x3F)    // ZELL-Zugriffe
#define WR_SUM(s)    {INDF &= ~0x3F; INDF |= (s);}

#ifdef RUNNING_ON_PIC
#define RD_FIRE_REQ    (INDF.7)
#define WR_FIRE_REQ(b)    {INDF.7 = (b);}
#endif

#ifdef RUNNING_ON_PC
#define RD_FIRE_REQ    !!(INDF>>7)
#define WR_FIRE_REQ(b)    {INDF&=~0x80;INDF|=b;} //{INDF.7 = (b);}
#endif

#define SENS_0        0               // Sensoren
#define SENS_1        1
#define SENS_2        2
#define AKT_0        3               // spezialzellen definieren
#define AKT_1        4
#define AKT_2        5
#define TIMER        6        // Timer-Zelle
#define HUNGER        7        // Hunger-Zelle
#define FIRST_NEURON    8        // Beginn des Hirns

//******* verbunden werden zellen mit vielen links (dendriten) *********
#define NO_LINK        -1
#define MAX_LINKS    (128 / sizeof(struct _link))    // viele links im EEPROM

struct _link {                // struktur eines EEPROM-links
  uns8 src;                // leerer link: src_zelle == NO_LINK
  uns8 dst;                // verbindet source- mit dest-zelle
  uns8 use;                // nützlichkeit dieses links
};

//********************** RUNNIN ON PC ***********************************
#ifdef RUNNING_ON_PC

_link Simulated_EEPROM[NUMBEROFNEURONS];

uns8 LINK_RD(uns8 address, uns8 component)
{
  uns8 value = 0;
  if (component == LINK_SRC) value = Simulated_EEPROM[address].src;
  if (component == LINK_DST) value = Simulated_EEPROM[address].dst;
  if (component == LINK_USE) value = Simulated_EEPROM[address].use;
  return value;
}

void LINK_WR(uns8 address, uns8 component, uns8 value)
{

  if (address < NUMBEROFNEURONS)
  {
    if (component == LINK_SRC) Simulated_EEPROM[address].src = value;
    if (component == LINK_DST) Simulated_EEPROM[address].dst = value;
    if (component == LINK_USE) Simulated_EEPROM[address].use = value;
  } else
  {
      cout << "Error: link address out of range " + address << endl;
//    Serial.print("Error: link address out of range "); Serial.println(address);
//    delay(100);
  }
}

#endif

static uns8 rand_link;            // randomize link

static uns8 pattern;
static uns8 learn;

static void gi_lerne(void)        // die genesis
{
  uns8 zell_ind = 0, link, free, buf;
  BOOL hit;
  do {                    // Suche feuernde zellen
    FSR = &zellen[zell_ind];        // pointer auf zelle
    /**** sensoren, aktoren und triebe sind besondere zellen *****/
/*
    switch(zell_ind) {
      case SENS_0: WR_FIRE_REQ(pattern.0); break;
      case SENS_1: WR_FIRE_REQ(pattern.1); break;
      case SENS_2: WR_FIRE_REQ(FALSE); break;
      case AKT_0:  GPIO.OUT_0 = RD_FIRE_REQ; continue;
      case AKT_1:  GPIO.OUT_1 = RD_FIRE_REQ; continue;
      case AKT_2:  GPIO.OUT_2 = RD_FIRE_REQ; continue;
      default: break;
    }
*/

    /***** diese zeilen sind der kern des systems *****************/
    if(!RD_FIRE_REQ) continue;        // zelle möchte nicht feuern
    WR_FIRE_REQ(FALSE);            // zell-feuerwunsch wird nun erfüllt
    free = NO_LINK; link = 0; hit = FALSE;    // verfolge die links
    do {                // alle links durchsuchen
      buf = LINK_RD(link,LINK_SRC);        // linkbyte lesen
      if(buf == NO_LINK) free = link;    // leeren link merken
      else if(buf == zell_ind) {    // einen link gefunden
    uns8 hbuf = LINK_RD(link,LINK_USE);    // nuetzlichkeit lesen
    if(hbuf) hit = TRUE;        // nutzlink gefunden
    if(++hbuf > FIRE_LIMIT) hbuf = FIRE_LIMIT;// limitieren
    FSR = zellen + LINK_RD(link,LINK_DST);// pointer auf dst-zelle
    buf = RD_SUM + hbuf;        // zellsumme berechnen
    if(buf > FIRE_LIMIT) buf = FIRE_LIMIT;    // limitieren
    WR_SUM(buf);            // zellsumme speichern
    if((buf == FIRE_LIMIT)&&(!RD_FIRE_REQ)) {// will dst feuern?
      WR_FIRE_REQ(TRUE);        // FIRE_REQ vormerken
      LINK_WR(link,LINK_USE,hbuf);    // nuetzlichkeit inkrementieren
    }
      }
      link += sizeof(struct _link);    // nächsten link adressieren
    } while(link < MAX_LINKS * sizeof(struct _link));

    /** wenn kein nützlicher link gefunden und platz ist: erzeuge neuen link **/
    if((!hit)&&(free != NO_LINK)) {
      LINK_WR(free,LINK_SRC,zell_ind);    // link neu erzeugen
      if(learn) buf = learn;        // gewollte verlinkung
      else {                // zufällige verlinkung
    if(++rand_link >= sizeof(zellen)) rand_link = FIRST_NEURON;
    buf = rand_link;
    if((buf == zell_ind)&&(++buf >= sizeof(zellen))) buf = FIRST_NEURON;
      }
      LINK_WR(free,LINK_DST,buf);
      LINK_WR(free,LINK_USE,0);        // ob der link nützlich wird, weiß keiner
    }
  } while(++zell_ind < sizeof(zellen));    // nächste zelle
}

static void gi_verlerne(void)        // links überarbeiten
{
  uns8 link = 0, buf;
  do {                    // alle links durchsuchen
    if(LINK_RD(link,LINK_SRC) != NO_LINK) {    // leere links skippen
      buf = LINK_RD(link,LINK_USE);        // nuetzlichkeit lesen
      if(buf) LINK_WR(link,LINK_USE,--buf);    // langsam verlernen
      if(!buf) LINK_WR(link,LINK_SRC,NO_LINK);// link ganz löschen
    }
    link += sizeof(struct _link);    // nächster link
  } while(link < MAX_LINKS * sizeof(struct _link));
}

#define DELETE        0
#define REDUCE        1
#define SLEEP        2

static void gi_zellen(uns8 steuer)    // zell-erregungen überarbeiten
{                    // DELETE, REDUCE oder SLEEP
  uns8 zell_ind = 0;
  do {                    // Suche zellen
    FSR = zellen + zell_ind;
    if(steuer == DELETE) INDF = 0;    // flags und summe auf einen schlag
    else if(steuer == REDUCE) {if(RD_SUM) WR_SUM(RD_SUM - 1);}
    else if(RD_SUM > FIRE_LIMIT) WR_SUM(FIRE_LIMIT);
  } while(++zell_ind < sizeof(zellen));    // nächste zelle
}

#define NUMBER_OF_SIMULATION_STEPS 100

int main()
{
    cout << "Gucki running" << endl;

#ifdef PIC
  RP0 = 1;                // erstmal alle Spezialregister...
  #asm
    DW /*CALL*/ 0x2000 + /*ADRESSE*/ 0x03FF // oscal abholen
  #endasm
  OSCCAL = W;                // und Oszillatorkalibrierung speichern

  OPTION = 0;                 // global weak-pullup ein (je 20kOhm)
  WPU = _BV(IN_0) | _BV(IN_1) | _BV(IN_2);
  TRISIO = _BV(IN_0) | _BV(IN_1) | _BV(IN_2);    // eingänge

  RP0 = 0;                // normale register und ram
  CMCON = 0x07;                // komparator aus
  timeloop_init();            // timer initialisieren
#endif

  rand_link = FIRST_NEURON;
  gi_zellen(DELETE);            // zellerregungen löschen

  uns8 loop = 0;

  int steps=0;
  for(steps=0;steps<NUMBER_OF_SIMULATION_STEPS;steps++)
  {
    switch(loop)
    {
      case 0: pattern = 0x01; learn = AKT_0; break;
      case 1: pattern = 0x02; learn = AKT_1; break;
      case 2: pattern = 0x03; learn = AKT_2; break;
      default:
      {
          cout << "error, no pattern" << endl;
      }//FOREVER;
    }
    gi_lerne();
    loop++;

#ifdef WEG
    gi_verlerne();            // links langsam verlernen

    if(!++loop) {
      gi_verlerne();            // links langsam verlernen
      gi_zellen(SLEEP);            // schlafen
    }
    else if(!(loop & 0x1F))        // alle 32 durchläufe
      gi_zellen(REDUCE);        // zellerregungen vermindern
#endif
  }

  cout << steps + " simulations steps done" << endl;
  cout << " Gucki stopped" << endl;
    //return 0;
}


/* ENDE */