Programming PIC18F2550 via the Arduino - Page 1
Forum section: electronics / projects

author: kirill578
author_rank: Newbie
timestamp: March 05, 2012, 06:30:09 pm
content: Hey, so its my first time playing with a PIC, its 18F2550 and unfortunately I don't have any thing that could program it (and I have no parallel port). so I decided to write a "sketch" that will program the device using the Arduino. I've menaged to get it working, so it can erase, read, and write.I compiled quite simple program using "HI-TECH C -MPLAB IDE 8.84"Code:#include <p18f2550.h>void main(){TRISA = 0;TRISB = 0;TRISC = 0;PORTA = 0xFF;PORTB = 0xFF;PORTC = 0xFF;while(1){}}HEX file:Code::04000000F6EF3FF0E8:107FEC000001F9EF3FF0926A936A946A80688168A5:047FFC008268FFD7C1:00000001FFmy way of writing it to the device (check source code at the end)Code:W0000F6EF3FF0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFXW7FE0FFFFFFFFFFFFFFFFFFFFFFFF0001F9EF3FF0926A936A946A806881688268FFD7Xmy fuse settings are:00051F1F008385000FC00FE00F40I don't thing it has something to do with the programming. Do you have any suggestion, by the way here is the source code of the arduino sketch:Code:// I wrote it according to the following datasheet:// http://ww1.microchip.com/downloads/en/DeviceDoc/39622L.pdf//pin out config#define PGC 6#define PGD 5#define EN 7 //PGM & MCLR#define P15 1#define P12 1String inputString = "";boolean stringComplete = false;unsigned long temp;byte buffer;byte address;void setup(){Serial.begin(9600);pinMode(EN,OUTPUT);pinMode(PGC,OUTPUT);pinMode(PGD,OUTPUT);inputString.reserve(200);//insructionSerial.println("This will program your PIC18F2550");Serial.println("Read 32 bytes command: R< 6digit address >X works for 0x0 - 0x3FFFFF");Serial.println("Write 32 bytes command: W< 4digit address >< 32 bytes of data>X works for 0x0 - 0x007FFF");Serial.println("Erase all chip: EX");Serial.println("Config bits programming is yet to be implemented");Serial.println("");Serial.println("I myself couldn't get an led flashing, hope you did");Serial.println("I'd appreciate any help on the forum:");Serial.println("http://goo.gl/kMjd6");}void loop(){ } //nothing here//////THE MAIN CODE///////////////////////////////////////////////////////////////////////void serialEvent() {while (Serial.available()) {char inChar = (char)Serial.read();if (inChar == 'X') { //buffering till XstringComplete = true;break;}inputString += inChar;}if (stringComplete && inputString.charAt(0) == 'W'){ //WRITEif(inputString.length() != 69) {Serial.println("Input is wrong, should be: W<address - 4 digit><32bytes>X");nullString();goto endofthisif;}address = 0;address = char2byte(inputString.charAt(2),inputString.charAt(1));address = char2byte(inputString.charAt(4),inputString.charAt(3));nullBuffer(); // set everything FFfor(int i=0;i<32;i++){buffer = char2byte(inputString.charAt(2*i+6),inputString.charAt(2*i+5));}nullString();Serial.print("Programming 32bytes,starting at:");Serial.print("0x00");if(address<0x10) Serial.print("0"); Serial.print(address,HEX);if(address<0x10) Serial.print("0"); Serial.println(address,HEX);for(int i=0;i<32;i++) { Serial.print(buffer,HEX); Serial.print(" "); }Serial.println("");///WritedigitalWrite(EN,HIGH);delay(1);programBuffer(address,address,address);digitalWrite(EN,LOW);Serial.println("Programming complety");}endofthisif:;if (stringComplete && inputString.charAt(0) == 'E'){ //Erase alldigitalWrite(EN,HIGH);delay(1);////eraseerase_all();digitalWrite(EN,LOW);Serial.println("Erase complety");nullString();}if (stringComplete && inputString.charAt(0) == 'R'){ //READaddress = char2byte(inputString.charAt(2),inputString.charAt(1));address = char2byte(inputString.charAt(4),inputString.charAt(3));address = char2byte(inputString.charAt(6),inputString.charAt(5));//readtemp=0;temp = ((long)address)<<(16); //doesn't work with out (long)temp |= ((long)address)<<(8);temp |= (long)address;Serial.print(temp,HEX); Serial.print(":");digitalWrite(EN,HIGH);delay(1);for(int i=0;i<32;i++){address = byte( (temp&0xFF0000)>>16 );address = byte( (temp&0xFF00)>>8 );address = byte( temp&0xFF );Serial.print(readFlash(address,address,address),HEX);Serial.print(" ");temp++;}Serial.println("");digitalWrite(EN,LOW);nullString();}//clear string incase the first CHAR isn't E,R,Wif(inputString.charAt(0) != 'E' && inputString.charAt(0) != 'R' && inputString.charAt(0) != 'W') nullString();}byte readFlash(byte usb,byte msb,byte lsb){byte value=0;send4bitcommand(B0000);send16bit( 0x0e00 | usb ); //send4bitcommand(B0000);send16bit(0x6ef8);send4bitcommand(B0000);send16bit( 0x0e00 | msb ); //send4bitcommand(B0000);send16bit(0x6ef7);send4bitcommand(B0000);send16bit( 0x0e00 | lsb ); //send4bitcommand(B0000);send16bit(0x6ef6);send4bitcommand(B1000); //pinMode(PGD,INPUT); digitalWrite(PGD,LOW);for(byte i=0;i<8;i++){ //readdigitalWrite(PGC,HIGH);digitalWrite(PGC,LOW);}for(byte i=0;i<8;i++){ //shift outdigitalWrite(PGC,HIGH);digitalWrite(PGC,LOW);if(digitalRead(PGD) == HIGH) value += 1<<i; //sample PGD}return value;}void send4bitcommand(byte data){pinMode(PGD,OUTPUT);for(byte i=0;i<4;i++){if( (1<<i) & data ) digitalWrite(PGD,HIGH); else digitalWrite(PGD,LOW);digitalWrite(PGC,HIGH);digitalWrite(PGC,LOW);}}void send16bit(unsigned int data){pinMode(PGD,OUTPUT);for(byte i=0;i<16;i++){if( (1<<i) & data ) digitalWrite(PGD,HIGH); else digitalWrite(PGD,LOW);digitalWrite(PGC,HIGH);digitalWrite(PGC,LOW);}}void erase_all(){ //for some reason the chip stops respone, just reconnect voltagesend4bitcommand(B0000);send16bit(0x0e3c); //send4bitcommand(B0000);send16bit(0x6ef8);send4bitcommand(B0000);send16bit(0x0e00); //send4bitcommand(B0000);send16bit(0x6ef7);send4bitcommand(B0000);send16bit(0x0e05); //send4bitcommand(B0000);send16bit(0x6ef6);send4bitcommand(B1100);send16bit(0x3F3F);send4bitcommand(B0000);send16bit(0x0e3c); //send4bitcommand(B0000);send16bit(0x6ef8);send4bitcommand(B0000);send16bit(0x0e00); //send4bitcommand(B0000);send16bit(0x6ef7);send4bitcommand(B0000);send16bit(0x0e04); //send4bitcommand(B0000);send16bit(0x6ef6);send4bitcommand(B1100);send16bit(0x8F8F);send4bitcommand(B0000); //send16bit(0x0000); //delay(2);send4bitcommand(B0000); //send16bit(0x0000); //Serial.println("Disconnect and reconnect the chip, or it won't respone! (Yet to be fixed)");}void programBuffer(byte usb,byte msb,byte lsb){if( (lsb&0x0F) | ((lsb&0xF0)>>4)%2){Serial.println("Error: First digit (refere as HEX) have to be 0, and the second digit have to be even.");Serial.println("valid examples: 0x000000 , 0x000060, 0x006320, 0x0063E0");Serial.println("INvalid examples: 0x000004 , 0x000014, 0x006328, 0x0063EA");Serial.println("0,2,4,6,8,A,C,E are even");return;}//step 1send4bitcommand(B0000);send16bit(0x8ea6);send4bitcommand(B0000);send16bit(0x9ca6);//step 2send4bitcommand(B0000);send16bit( 0x0e00 | usb ); //send4bitcommand(B0000);send16bit(0x6ef8);send4bitcommand(B0000);send16bit( 0x0e00 | msb ); //send4bitcommand(B0000);send16bit(0x6ef7);send4bitcommand(B0000);send16bit( 0x0e00 | lsb ); //send4bitcommand(B0000);send16bit(0x6ef6);//step 3for(byte i=0;i<15;i++){send4bitcommand(B1101);send16bit( buffer[(2*i)+1]<<8 | buffer[(i*2)] );}//step 4send4bitcommand(B1111);send16bit( buffer<<8 | buffer );//nopdigitalWrite(PGC,HIGH);digitalWrite(PGC,LOW);digitalWrite(PGC,HIGH);digitalWrite(PGC,LOW);digitalWrite(PGC,HIGH);digitalWrite(PGC,LOW);digitalWrite(PGC,HIGH);delay(1);digitalWrite(PGC,LOW);delayMicroseconds(100);send16bit(0x0000);//done}///////////////////////////////nothing special underhere:void nullString(){inputString = "";stringComplete = false;}void nullBuffer(){for(byte i=0;i<32;i++) buffer = 0xFF;}byte char2byte(char lsb,char msb){byte result=0;switch(lsb){case '0': result = 0; break;case '1': result = 1; break;case '2': result = 2; break;case '3': result = 3; break;case '4': result = 4; break;case '5': result = 5; break;case '6': result = 6; break;case '7': result = 7; break;case '8': result = 8; break;case '9': result = 9; break;case 'A': result = 0xA; break;case 'B': result = 0xB; break;case 'C': result = 0xC; break;case 'D': result = 0xD; break;case 'E': result = 0xE; break;case 'F': result = 0xF; break;}switch(msb){case '0': result |= 0<<4; break;case '1': result |= 1<<4; break;case '2': result |= 2<<4; break;case '3': result |= 3<<4; break;case '4': result |= 4<<4; break;case '5': result |= 5<<4; break;case '6': result |= 6<<4; break;case '7': result |= 7<<4; break;case '8': result |= 8<<4; break;case '9': result |= 9<<4; break;case 'A': result |= 0xA<<4; break;case 'B': result |= 0xB<<4; break;case 'C': result |= 0xC<<4; break;case 'D': result |= 0xD<<4; break;case 'E': result |= 0xE<<4; break;case 'F': result |= 0xF<<4; break;}return result;}