1
\$\begingroup\$

I was making a programmer for pic16f877a using arduino with the help of the programming specification document as I can't find any good one around here at the time. I was able to write code in the user program memory and read it back in low voltage programming mode (and I'm very confident this process is successful) but I didn't write anything in the configuration memory.

The project didn't work (a simple blinking LED), so i made some research and found that it might be the 2 bits in the configuration word that define the type of the clock (supposedly RC oscillator by default) and it must be changed to another type. so i tried accessing and editing the configuration word using the commands given in the document but I always only read zeros whatever I do, even if I make a chip erase command at the configuration memory.

I know that this is very hard to answer as the programming protocol is specific to the device but I will really appreciate it if someone could give me a hint, and if there is any missing information just tell me in a comment and I will edit the question to add them.

Here is my code for accessing and reading the configuration word:

#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);
}

In short I am driving the MCU into low voltage programming mode, which appears to be working, the sending a command to move the program counter to the configuration memory, then incrementing the program counter till it reaches the configuration word address 2007h, then reading the word at this address.

There is another part for writing the code but I didn't add it here.

All of this is described in the programming document here

\$\endgroup\$
  • \$\begingroup\$ I made a programmer for a different chip (PIC12F508) and had some trouble with it. I initially just used the default RC oscillator mode and hooked up a slow RC oscillator. Then I could tell when I'd successfully managed to change the oscillator mode because the LED would blink faster. \$\endgroup\$ – immibis Apr 23 '18 at 23:58
  • \$\begingroup\$ @immibis I managed to do something like that and the project works with slow speed and some problems but I still can't figure out how to change the oscillator mode. I read the whole programming specification document and followed it precisely but with no result, always read as zeros. \$\endgroup\$ – maged rifaat Apr 25 '18 at 16:28
2
\$\begingroup\$

So I managed to read and write the configuration word by sending an unprogrammed data word (i.e. writing a word of all ones or 0x3FFF as a word is 14-bit) just after the load configuration command and before incrementing seven times.

It turns out that this is the typical way of writing the configuration word and yet the programming specification didn't bother mentioning it and I actually read the programming specification of a handful of different models until I found this information.

So, my advice is if you have a similar problem and can't find the solution in your data sheet or so, go check the similar models' documents and maybe you can find a hint or two to solve your problem.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.