PIC-Programmierer hat Probleme beim Lesen und Schreiben des Programmkonfigurationsspeichers

Ich habe mit Hilfe des Programmierspezifikationsdokuments einen Programmierer für pic16f877a mit Arduino erstellt, da ich zu diesem Zeitpunkt hier keinen guten finden kann. Ich konnte Code in den Benutzerprogrammspeicher schreiben und ihn im Niederspannungs-Programmiermodus zurücklesen (und ich bin sehr zuversichtlich, dass dieser Vorgang erfolgreich ist), aber ich habe nichts in den Konfigurationsspeicher geschrieben.

Das Projekt hat nicht funktioniert (eine einfache blinkende LED), also habe ich etwas recherchiert und festgestellt, dass es möglicherweise die 2 Bits im Konfigurationswort sind, die den Typ der Uhr definieren (angeblich standardmäßig RC-Oszillator) und geändert werden müssen zu einem anderen Typ. Also habe ich versucht, mit den im Dokument angegebenen Befehlen auf das Konfigurationswort zuzugreifen und es zu bearbeiten, aber ich lese immer nur Nullen, was immer ich tue, selbst wenn ich einen Chip-Löschbefehl am Konfigurationsspeicher mache.

Ich weiß, dass dies sehr schwer zu beantworten ist, da das Programmierprotokoll spezifisch für das Gerät ist, aber ich würde es sehr schätzen, wenn mir jemand einen Hinweis geben könnte, und wenn irgendwelche Informationen fehlen, teilen Sie es mir einfach in einem Kommentar mit und ich werde die bearbeiten Frage, um sie hinzuzufügen.

Hier ist mein Code für den Zugriff und das Lesen des Konfigurationsworts:

#define MCLR 8
#define PGM 9
#define DATA 10
#define CLK 11

  /*
    MCLR -> MCLR
    PGM -> RB3
    data -> RB7
    clk -> RB6
  */


void setup() {
  pinMode(MCLR, OUTPUT);
  pinMode(PGM, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLK, OUTPUT);

  digitalWrite(DATA, LOW);
  digitalWrite(CLK, LOW);
  digitalWrite(PGM, LOW);
  digitalWrite(MCLR, LOW);

  Serial.begin(9600);
  while(Serial.available() == 0);

  // Low voltage programming
  digitalWrite(PGM, HIGH);
  delayMicroseconds(1);
  digitalWrite(MCLR, HIGH);
  delayMicroseconds(10);


  loadConfig();
  for (int i = 0; i < 7; i++)
  {
     increment(); 
  }
  Serial.print(readData(),DEC);

}

void loop() {
  // no need

}

void writeBit(int a)
{
  digitalWrite(DATA, a);
  digitalWrite(CLK, HIGH);
  delayMicroseconds(1);
  digitalWrite(CLK, LOW);
  delayMicroseconds(1);
  digitalWrite(DATA, LOW);
}

byte readBit()
{
  byte _bit;
  digitalWrite(CLK, HIGH);
  delayMicroseconds(1);
  _bit = digitalRead(DATA);
  digitalWrite(CLK, LOW);
  delayMicroseconds(1);
  return _bit;
}

void sendCommand(char command)
{
  for (int i = 1; i <= 0b100000; i *= 2)
  {
    writeBit((command & i) >= 1);
  }
}
uint16_t readData()
{
    sendCommand(0b000100);
    delayMicroseconds(2);
    uint16_t value = 0;
    pinMode(DATA, INPUT);
    readBit();
    for(int i = 0; i < 14; i++)
    {
        value = (value<<1) | readBit();
    }
    readBit();
    pinMode(DATA, OUTPUT);
    return value;
}

void loadConfig()
{
    sendCommand(0b000000);
    delay(2);
}

void increment()
{
   sendCommand(0b000110);
   delayMicroseconds(2);
}

Kurz gesagt, ich fahre die MCU in den Niederspannungs-Programmiermodus, der zu funktionieren scheint, sende einen Befehl, um den Programmzähler in den Konfigurationsspeicher zu verschieben, dann erhöhe den Programmzähler, bis er die Konfigurationswortadresse 2007h erreicht, und lese dann die Wort unter dieser Adresse.

Es gibt einen weiteren Teil zum Schreiben des Codes, aber ich habe ihn hier nicht hinzugefügt.

All dies ist hier im Programmierdokument beschrieben

Ich habe einen Programmierer für einen anderen Chip (PIC12F508) gemacht und hatte einige Probleme damit. Ich habe zunächst nur den Standard-RC-Oszillatormodus verwendet und einen langsamen RC-Oszillator angeschlossen. Dann konnte ich sagen, wann ich es geschafft hatte, den Oszillatormodus zu ändern, weil die LED schneller blinken würde.
@immibis Ich habe so etwas geschafft und das Projekt funktioniert mit langsamer Geschwindigkeit und einigen Problemen, aber ich kann immer noch nicht herausfinden, wie ich den Oszillatormodus ändern kann. Ich habe das gesamte Programmierspezifikationsdokument gelesen und es genau befolgt, aber ohne Ergebnis, immer als Nullen gelesen.

Antworten (1)

Also habe ich es geschafft, das Konfigurationswort zu lesen und zu schreiben, indem ich ein unprogrammiertes Datenwort gesendet habe (dh ein Wort nur aus Einsen oder 0x3FFF geschrieben habe, da ein Wort 14-Bit ist) direkt nach dem Befehl zum Laden der Konfiguration und vor dem siebenmaligen Inkrementieren.

Es stellt sich heraus, dass dies die typische Schreibweise des Konfigurationsworts ist und die Programmierspezifikation sich nicht die Mühe gemacht hat, dies zu erwähnen, und ich habe tatsächlich die Programmierspezifikation einer Handvoll verschiedener Modelle gelesen, bis ich diese Information gefunden habe.

Also, mein Rat ist, wenn Sie ein ähnliches Problem haben und die Lösung nicht in Ihrem Datenblatt oder so finden können, sehen Sie sich die Dokumente der ähnlichen Modelle an und vielleicht finden Sie ein oder zwei Hinweise zur Lösung Ihres Problems.