Estaba haciendo un programador para pic16f877a usando arduino con la ayuda del documento de especificación de programación ya que no puedo encontrar ninguno bueno por aquí en ese momento. Pude escribir código en la memoria del programa del usuario y leerlo en el modo de programación de bajo voltaje (y estoy muy seguro de que este proceso es exitoso) pero no escribí nada en la memoria de configuración.
El proyecto no funcionó (un simple LED parpadeante), así que investigué un poco y descubrí que podrían ser los 2 bits en la palabra de configuración que definen el tipo de reloj (supuestamente el oscilador RC de forma predeterminada) y debe ser cambiado a otro tipo así que intenté acceder y editar la palabra de configuración usando los comandos que se dan en el documento, pero siempre solo leo ceros, sea lo que sea, incluso si hago un comando de borrado de chip en la memoria de configuración.
Sé que esto es muy difícil de responder ya que el protocolo de programación es específico para el dispositivo, pero realmente apreciaría que alguien me diera una pista, y si falta alguna información, simplemente dígalo en un comentario y editará la pregunta para agregarlos.
Aquí está mi código para acceder y leer la palabra de configuración:
#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);
}
En resumen, estoy conduciendo la MCU al modo de programación de bajo voltaje, que parece estar funcionando. El comando envía un contador para mover el contador de programas a la memoria de configuración, y luego aumenta el contador del programa hasta que llega a la dirección de palabra de configuración 2007h. luego leyendo la palabra en esta dirección.
Hay otra parte para escribir el código pero no lo agregué aquí.
Todo esto se describe en el documento de programación aquí