Burning hex to PIC

Status
Not open for further replies.

Rusttree

Member
I'm hoping to find a source that explains how to burn the relevent bits of data from a hex file into a PIC. I've built a circuit and written software that should be able to burn the PIC. I understand the programming commands ("Begin Erase", "Load Data for Program Memory", etc) and I created an LED blinker hex file using MPLAB v7.4. All that's left is getting the hex file translated for the PIC.

I've spent some time studying the Intel hex file format, but I'm still at a bit of a loss. One issue that stands out to me is that my PIC (the 16F88) uses 14 bit words. The hex file is portioned into 8, 16, or 32 bit chunks. How are the 14 bit words arranged in there?

I tried wading through Microchip's website for documentation explaining the procedure, but they seem to be very vague on the subject (I'm sure with the hope that you'll buy their development kit instead). If anyone knows of Microchip documentation that explain this, that would probably be the most help.

Thank you!
Dan
 
The following appears inside the 16F628A programming specification DS41196E Page 6. Whether it still apply to the 16F88 I am not sure but I think it probably does.

Note the last sentence of the following quote:

 
Well heck, that's pretty simple. I don't remember reading that anywhere in the 16F88 documentation I found.

Ok, now this leads to my next question. Here's the hex file for the simple LED blinker:

:020000040000FA
:020000000328D3
:040002000034003492
:0A0006008316003085008312850187
:100010000D20FF3085000D200728FF30F100FF3054
:0C002000F200F20B1128F10B0F28080071
:02400E00913FE0
:02401000FC3F73
:00000001FF

The last 16 bits of the 4th line are 8501. In binary, this is:
1000 0101 0000 0001
I picked this one out because at a quick glance I see that the first bit and the 16th bit are both 1's. How do I make this a 14 bit word? It seems like I need all 16 bits of it. I think there is something fundamental I'm missing here.
 
Last edited:
The HEX file format is fully explained (all three versions of it!) in the MPASM helpfile - assuming that's what you're trying to do?.
 
According to the programming spec, you keep data line low and clock the PIC. This is the leading bit.

Then you send the LSB, the next higher bit...MSB of the program data. This sequence total takes 14-bits.

Afterwards, you keep data line low and clock the PIC. So all together you have sent sixteen bits, with the 14-data centered inside the 16 bit.

See also the following image:
 

Attachments

  • Hex_data.png
    3.8 KB · Views: 254
Ah, I wasn't swapping the lsb's and msb's visually in the hex file. L.Chung, thanks for including that graphic of my hex file. It makes it much easier to see the data that way. So my understanding is, then, that the hex file is created with pre-padded values. How convenient.
 
Rusttree said:
So my understanding is, then, that the hex file is created with pre-padded values. How convenient.

The data is right-justified with LSB at position bit0 of the 16-bit word. The 15th and 14th bit of the 16-bit word is padded zero by the MPLAB assembler.
 
I've run into a hardware issue that I hadn't forseen. The PGD pin is used for input to burn data and output to read data. I'm using my parallel port to interface, which has input pins and output pins. So, without putting much thought into it, I wired an output pin and an input pin to the PGD. But now I realize that whatever state the parallel port outpin pin is in will influence what the input pin reads, regardless of what state the PGD pin is in.

Is there a simple solution here so that the output pin doesn't affect the input pin, but they are still both attached to the PGD pin?
 
Yeah, download the P16PRO40 schematic from Nigels site, or look for a Tait Classic programmer. Study the schematics. Why "re-invent the wheel"?
 
Rusttree said:
Is there a simple solution here so that the output pin doesn't affect the input pin, but they are still both attached to the PGD pin?

If you check the designs that Mike mentions (which are ALL based on the original David Tait design - the true father of PIC programmers), you will see they all use open collector buffers - and that's why!. Bear in mind, a simple NPN transistor and two resistors can form an open-collector buffer if you only need one or two of them!.
 
Ok, I've studied the P16PRO40 diagram and I'm still having confusion between the interaction of the PGD pin and the "Data Out" pin. Specifically, during a read cycle.

If Data Out is idleing at High during a read, pin 3 of the 74LS05 will be High and pin 4 will be Low. If the PGD pin is at that moment sending a High voltage, what happens at pins 4 and 11 of the inverter? The way I see it, they're both simultaneously getting a high and a low voltage at the same time. Most importantly, how does pin 11 see that voltage?
 
Rusttree said:
If Data Out is idleing at High during a read, pin 3 of the 74LS05 will be High and pin 4 will be Low.

You do not let that happens by output a low to the printer port pin so that the inverter output pin 4 will be high(high Z in case of open-collector).


If PGD is sending a HIGH at this moment, then there is no concern. If the level of PGD is LOW, it can pull the open-collector to LOW because by definition, an open-collector pin cannot output current but only sinking current.
 
<EDIT>
I'm happy to say that I found my own error and fixed it!! I had forgotten the "Begin Programming Only" step in my sequence below. Now I am able to read the address bits that I programmed !
</EDIT>

Ah, I see. Thanks for the quick lesson. So I have to make sure my program holds the parallel port pin at low during a read.

Ok, so I've run my program now with this consideration and I'm not getting an expected response. My test program attempts to write 14 bits of code to address 0x0000 and then read it back. I'm still trying to debug this, but I'd appreciate it if someone could just give me a sanity check for now.

My program does this (after resetting and going into program mode):
Begin Erase
End Programming
Load Data For Program Memory
Burn data (sixteen 0's and 1's)
End Programming
Read Data From Program Memory
Read data (cycle clock 16 times and record input pin)

I attached LED's to the relevent pins and inserted huge delays so I could physically watch the cycles. I recorded the LED blinks as I saw them and got this:

000100 111010 010000 0_ _ _ _ _ _ _ _ _ _ _ _ _ _ 0 111010 001000 0111111111111111

I put underscores for my burning input because it didn't matter what those values were. The ouput was always all 1's at the end.

I just want to make sure that there's nothing silly I'm doing wrong before I move on. Thank you!
 
Last edited:
You're always going to struggle, because you're trying to debug both hardware and software at the same time, so you don't know which one is faulty, or if both of them are.

I would suggest you build some hardware that is compatible with some other software, once you know that the hardware is working correctly, THEN you can try and write your own software, secure in the knowledge that the hardware is OK.
 
Thanks for your guys' help so far. I've got the preliminary "engine" of the code working now. It can write words and then read them back. I'm running into a problem, though, when I attempt to write 4 or more words. I modeled my code after the "Algorithm 1 Flow Chart - Program Memory" in the 16F87/88 programming specification manual (fig. 3-2). The flowchart makes a point of keeping track of when you've loaded 4 words. If you have, you execute the Begin Programming Only command, go back and load 4 more words, etc. I'm guessing my mysterious error on the 4th word has something to do with this. What's the reason for loading 4 words at a time instead of a whole row at a time? I can't find a mention of loading 4 words at a time anywhere else in the specification manual.
 

It's because it's a FLASH chip, rather than EEPROM, which means you can program 4 words at a time, making it four times as fast to program!. The design of the chip sets it as 4 words, you can't increase it!.

The programming datasheets are usually very difficult to understand, and not always 100% correct!.
 
Rusttree said:
What's the reason for loading 4 words at a time instead of a whole row at a time?

The simple reason is that the input data buffer inside the 16F88 PIC to store the words before programming can only holds 4 words so a "Write" operation is needed to empty the buffer after it is filled.

If there are PICs that has buffer to hold 16 words, then one can write 16 words at a time.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…