Programando PIC18F2550 con un Arduino

2

Estoy intentando implementar un programador de modo de bajo voltaje para el PIC18F2550 en un Arduino Uno de acuerdo con estos especificaciones de programación.

Las secuencias de bits se escriben en el bit menos significativo PIC al bit más significativo. También he tenido en cuenta los retrasos mínimos especificados en la hoja de datos, no parece haber retrasos máximos, excepto por el tiempo de subida de MCLR / Vpp.

Para validar mi código, quiero leer el ID de dispositivo en las direcciones 0x3ffffe y 0x3fffff. Aquí está mi código:

    /* 
 * Trying to build an arduino pic programmer for the PIC18F2550
 * Programming specifications: http://ww1.microchip.com/downloads/en/DeviceDoc/39622L.pdf
 * Author: Ingmar Jager
 */

//Arduino Pinout
int pgc = 9;  // program clock
int pgd = 8;  // program data
int pgm = 10;  // program mode
int MCLR = 11; //Master Clear Reset / Vpp

void setup()
{
  Serial.begin(9600);

  pinMode(pgc, OUTPUT);
  pinMode(pgd, OUTPUT);
  pinMode(pgm, OUTPUT);
  pinMode(MCLR, OUTPUT);
  digitalWrite(pgc, LOW);
  digitalWrite(pgd, LOW);
  digitalWrite(pgm, LOW);
  digitalWrite(MCLR, LOW);
  delay(500);

  enterProgramming();
  delay(500);
  tableRead(0x3F, 0xFF, 0xFF); //read DeviceID2 at 0x3FFFFF. Should be 0x12 = 00010010

  //delay(500);
  tableRead(0x3F, 0xFF, 0xFF);
 // delay(500);
  tableRead(0x3F, 0xFF, 0xFF);
  exitingProgramming();
}

/*
 * @param: three bytes which form the tablepointer address
 */
void setTablePTR(int addr_upper_byte,int addr_half_byte,int addr_lower_byte)
{

 Serial.print("Set TablePTR to: 0x");
 Serial.print(addr_upper_byte, HEX);
 Serial.print(addr_half_byte, HEX);
 Serial.println(addr_lower_byte, HEX);


 writeBits(4, 0x0); // 4 bit command

 writeBits(16, (0x0E << 8) + addr_upper_byte); // 16 bit data payload: load address

 writeBits(4, 0x0); 
 writeBits(16, 0x6EF8);  // set TBLPTR_U to addr_upper_byte

 writeBits(4, 0x0);
 writeBits(16, (0x0E << 8) + addr_half_byte);

 writeBits(4, 0x0);
 writeBits(16, 0x6EF7); //TBLPTR_H

 writeBits(4, 0x0);
 writeBits(16, (0x0E << 8) + addr_lower_byte);

 writeBits(4, 0x0);
 writeBits(16, 0x6EF6); //TBLPTR_L

}

/*
 * Read byte from the given address
 */
void tableRead(int high_byte, int mid_byte, int low_byte)
{

  setTablePTR(high_byte,mid_byte,low_byte);

  writeBits(4, 0x9); //1000 = Read and no increment
  writeBits(8, 0x00);
  pinMode(pgd, INPUT);
  delayMicroseconds(5); //P6 

  byte data = 0;
  //actual read
  Serial.print("Read bits from LSB to MSB: ");
  for (int i = 0; i < 8; i++)
  {
    digitalWrite(pgc, HIGH);
    delayMicroseconds(3); //P14 

    if (digitalRead(pgd)==HIGH)
    {
      Serial.print("1");
      data += (1 << i);
    }
    else
    {
      Serial.print("0");
    }

    digitalWrite(pgc, LOW);
        delayMicroseconds(3); 
  }  

  delayMicroseconds(5); //P5A
  pinMode(pgd, OUTPUT);
  Serial.println();
  Serial.print("Reading result: ");
  Serial.println(data);

}

/* Write LSB to MSB
 * @param n = number of bits to write
 * @param value = value to write in n bits
 */
void writeBits(int n, int value)
{

  for (int i = 0; i < n; i++) {
   if(boolean ((value >> i) & 1))
     {   
       digitalWrite(pgd,HIGH);
     //   Serial.println("Write High");
     } // else Serial.println("Write Low");
  }   
  digitalWrite(pgc, HIGH);
  delayMicroseconds(3);
  digitalWrite(pgc, LOW);
  delayMicroseconds(3);
  digitalWrite(pgd,LOW);
  delayMicroseconds(5); //P5A
} 

/*
 * Entering low voltage programming signals
 */
void enterProgramming()
{
   digitalWrite(pgc, LOW);
   digitalWrite(pgd, LOW);
   digitalWrite(pgm, LOW);
   digitalWrite(MCLR, LOW);

   delayMicroseconds(20);

   digitalWrite(pgm, HIGH);
   delayMicroseconds(3);//P15
   digitalWrite(MCLR, HIGH);
   delayMicroseconds(3);//P12
   Serial.println("Entered Low Voltage Programming");
}

/*
 * Exiting low voltage programming signals
 */
void exitingProgramming()
{
   digitalWrite(pgc, LOW);
   digitalWrite(pgd, LOW);
   delayMicroseconds(1); //P16
   digitalWrite(MCLR, LOW);
   delayMicroseconds(1); //P18
   digitalWrite(pgm, LOW);
   Serial.println("Exiting Low Voltage Programming");
}


void loop()
{

}

Este código ingresa al modo de programación, luego intenta leer de 0x3fffff tres veces seguidas, finalmente sale del modo de programación. Lástima que estoy obteniendo tres resultados diferentes, aparentemente no estoy leyendo el ID de dispositivo ... El resultado impreso es:

Entered Low Voltage Programming
Set TablePTR to: 0x3FFFFE
Read bits from LSB to MSB: 00000111
Reading result: 224
Set TablePTR to: 0x3FFFFF
Read bits from LSB to MSB: 00011111
Reading result: 248
Set TablePTR to: 0x3FFFFF
Read bits from LSB to MSB: 00000000
Reading result: 0
Exiting Low Voltage Programming

Cuando conecto otro PIC18F2550 los resultados difieren. Ahora no sé cómo seguir depurando este proyecto. ¿Alguien tiene experiencia con este asunto y / o algunas sugerencias?

p.s. Sé que es más fácil usar un programador, pero esto es más divertido;)

    
pregunta Jager

1 respuesta

0

Lo primero para depurar algo así es verificar que realmente ingresaste al modo de programación. La forma más confiable es utilizar el modo de entrada de alto voltaje. Asegúrese de que el pin PGM se mantiene bajo durante este tiempo. También asegúrese de que todos los pines de conexión a tierra y de alimentación todos estén conectados, ya sea que piense que los está utilizando o no, con una tapa de derivación en cada pin de encendido.

Para verificar que ingresó al modo de programación, cambie a algo que deba manejar el PGD, como la lectura de la instrucción TABLAT (0010). Siga esto con 8 bits cero, luego, en el siguiente flanco ascendente de PGC, el chip de destino debería cambiar a PGD de conducción por ser una alta impedancia previamente.

Una vez que esté funcionando, lo siguiente es leer la ID del dispositivo, ya que siempre es un valor conocido fijo. Esto es más complicado ya que tiene que ejecutar instrucciones básicas para cargar los tres bytes de TBLPTR, luego hacer una lectura.

Dado que todas estas interacciones son sincrónicas y usted posee el reloj, puede ir tan lento como desee y observar todo en el alcance una pieza a la vez.

Le ayudaría si describe exactamente lo que cree que es su proceso de intentar realizar estas operaciones. No, no voy a buscar el código arduino. Hay demasiado entre eso y las líneas PGC y PGD.

    
respondido por el Olin Lathrop

Lea otras preguntas en las etiquetas