PIC16F877A Program Memory Write - Page 1
Forum section: electronics / general

author: meliharicii
author_rank: Contributor
timestamp: October 30, 2016, 08:59:47 pm
content: (Soory for my english)I read to datasheet and I was use the next example assembly program but I cant be succesful .I am use PIC16F877A0000|0000|0000|0000||-EEADRH-|-EEADR---|1-) I am be sure to writeable program memory with config bits2-) write to EEADR to low addres3-) write to EEADRH to high addres4-) write to EEDATA5-) write to EEDATH (this both data be 0xBB)6-) and EECON1's 7th bits will be set for EEPGD7-) write EECON2 0x55 and 0xAA sequentially8-) write EECON1 WR bits setsand nothing happenedwhat I make wrong please help me .please use simple englishThanks everyone.

author: Andy Watson
author_rank: Super Contributor
timestamp: October 30, 2016, 09:59:05 pm
content: Step 6. Bit 7 should be set to access program memory.What are you writing in, C or assembly?

author: meliharicii
author_rank: Contributor
timestamp: October 30, 2016, 10:25:01 pm
content: I am trying in C

author: Andy Watson
author_rank: Super Contributor
timestamp: October 30, 2016, 11:19:59 pm
content: If you are operating on program memory (rather than data eeprom) the later devices need to be programmed in blocks of four writes. See section 3.6 of the data sheet.http://ww1.microchip.com/downloads/en/DeviceDoc/39582C.pdf

author: StillTrying
author_rank: Super Contributor
timestamp: October 31, 2016, 12:37:48 am
content: BSF EECON1,WREN ; Enable writes.........BCF EECON1,WREN ; Disable writesSeem to be missing, and probably others!

author: JPortici
author_rank: Super Contributor
timestamp: October 31, 2016, 06:20:13 am
content: post your code.

author: meliharicii
author_rank: Contributor
timestamp: November 01, 2016, 09:36:55 pm
content: Code:void WritePM(unsigned char datl,unsigned char dath,unsigned char addrl,unsigned char addrh){unsigned char addr;unsigned char datal=datl;unsigned char datah=dath;unsigned char tmp;unsigned char loop=1;addr=&datal;EEADRH=addrh;EEADR=addrl;FSR=addr;while(loop){EEDATA=INDF;FSR=FSR+1;EEDATH=INDF;FSR=FSR+1;EECON1=EECON1|0x80; // EEPGD bits set 1000 0000 =0x80EECON1=EECON1|0x4; // WREN bit set 0000 0100 =0x4INTCON=INTCON&0x7F; // GIE clear 0111 1111 =0x7FEECON2=0x55;EECON2=0xAA;EECON1=EECON1|0x2; //WR bit set 0000 0010 =0x2EECON1=EECON1&0xFB;//WREN bit clear 1111 1011 =0xFBINTCON=INTCON|0x80;//GIE set 1000 0000 =0x80EEADR=EEADR+1;tmp=EEADR;tmp=tmp&0x03;tmp=tmp^0x03;if(tmp==0){loop=0;}}}sorry about late answer , what does it look like?

author: Andy Watson
author_rank: Super Contributor
timestamp: November 01, 2016, 09:57:36 pm
content: I am wondering if the EEPROM can be written using C. The PIC Midrange Reference manual states that the sequence write 55, write aa and then set WR bit must be performed exactly. The 16F877 manual also states that one or two instructions following the initiation of a write will be ignored and treated as a NOP. I think it may be necessary to code the writing sequence into assembly code.

author: meliharicii
author_rank: Contributor
timestamp: November 01, 2016, 10:22:28 pm
content: I tried write EEPROM with C. its worked but I am trying to write program memory. Not good result. you think I should write assembly ?

author: Andy Watson
author_rank: Super Contributor
timestamp: November 01, 2016, 11:41:37 pm
content: The assembly code example in the manual calls for two NOPs to follow the EECON1 Write.Code:EECON1=EECON1|0x2; //WR bit set 0000 0010 =0x2NOPNOPEECON1=EECON1&0xFB;//WREN bit clear 1111 1011 =0xFBDoes your compiler allow in-line assembly?Edit: The program read operation also requires two NOPs following the RD initiation instruction.

author: meliharicii
author_rank: Contributor
timestamp: November 02, 2016, 12:41:45 am
content: I write this styleCode:EECON1=EECON1|0x2; //WR bit set 0000 0010 =0x2asm("NOP");asm("NOP");EECON1=EECON1&0xFB;//WREN bit clear 1111 1011 =0xFBdebug code look like thisCode:EECON1=EECON1|0x2; //WR bit set 0000 0010 =0x20x7D7: MOVF PIR1, W0x7D8: IORLW 0x20x7D9: MOVWF PIR1! asm("NOP");0x7DA: NOP! asm("NOP");0x7DB: NOP! EECON1=EECON1&0xFB;//WREN bit clear 1111 1011 =0xFB0x7DC: BSF STATUS, 0x50x7DD: BSF STATUS, 0x60x7DE: MOVF PIR1, W0x7DF: ANDLW 0xFB0x7E0: MOVWF PIR1Not worked.I tried this styleCode://EECON1=EECON1|0x2; //WR bit set 0000 0010 =0x2asm("BSF EECON1,1"); //not define WRasm("NOP");asm("NOP");asm("BCF EECON1,2");//EECON1=EECON1&0xFB;//WREN bit clear 1111 1011 =0xFBI tried in main this.Code:int main(int argc, char** argv) {WritePM(0xBB,0xBB,0x00,0x00);return (EXIT_SUCCESS);}I dont know maybe this wrong side.

author: JPortici
author_rank: Super Contributor
timestamp: November 02, 2016, 07:06:50 am
content: what compiler are you using again?and it seems to me you are not following the procedure written in the datasheet on page 44, where you even have a ready-to-use procedure.first of all, the status of the WRT configuration bit? if it's set you can't write on program memory.then the cose trasnlated from assembly would look like thisCode:unsigned char dataL,dataH;unsigned char addrL,addrH;EEADR = addrL; //the compiler here perform bank switching if necessaryEEADRH = addrH;EEDATA = dataL;EEDATH = dataH;EECON1bits.EEPGD = 1; //point to program memoryEECON1bits.WREN = 1; //enable writesINTCONbits.GIE = 0; //disable interrupts if neededEECON2 = 0x55;EECON2 = 0xAA;EECON1bits.WR = 1; //start program memory writeNOP();NOP();INTCON1bits.GIE = 1;EECON1bits.WREN = 0; //disable writeif this up here doesn't work toss away your compiler because it's a shitty one. free version of XC8 will do better.

author: meliharicii
author_rank: Contributor
timestamp: November 05, 2016, 07:54:59 pm
content: Code:#include <htc.h>#define _XTAL_FREQ 4000000/***/void WritePM(unsigned char datl,unsigned char dath,unsigned char addrl,unsigned char addrh){unsigned char addr;unsigned char datal=datl;unsigned char datah=dath;addr=&datal;EEADR=addrl;EEADRH=addrh;EEDATA=datal;EEDATH=datah;EECON1bits.EEPGD=1; // EEPGD bits set 1000 0000 =0x80EECON1bits.WREN=1; // WREN bit set 0000 0100 =0x4INTCONbits.GIE=0; // GIE clear 0111 1111 =0x7FEECON2=0x55;EECON2=0xAA;EECON1bits.WR=1; //WR bit set 0000 0010 =0x2//asm("BSF EECON1,1"); //not define WRasm("NOP");asm("NOP");__delay_ms(2);//asm("BCF EECON1,2");INTCONbits.GIE=1;//GIE set 1000 0000 =0x80EECON1bits.WREN=0;//WREN bit clear 1111 1011 =0xFBreturn;}void main(void) {unsigned char Hello1=0x00;unsigned char Hello2=0x00;while(1){WritePM(0x00,0x10,Hello1,Hello2);Hello1++;if(Hello1==0xFE){if(Hello2==0xFE){Hello2=0x00;}Hello2++;Hello1=0x00;}}}It's working .Now another questionI can't write all memory when I run this code in simulation. Last writen adress is 0x03FE . Picture in attachment.

author: JPortici
author_rank: Super Contributor
timestamp: November 05, 2016, 08:03:35 pm
content: maybe with the last write you are actually overwriting your application code?

author: Bruce Abbott
author_rank: Frequent Contributor
timestamp: November 06, 2016, 01:54:38 am
content: Kind of hard for the program to keep working after it wipes out its own memory!And this:-Code:Hello1++;if(Hello1==0xFE){if(Hello2==0xFE){Hello2=0x00;}Hello2++;Hello1=0x00;skips 0xFE and 0xFF (which I am guessing is not what you wanted).'unsigned char' automatically wraps around from 0xFF to 0x00. So you can just do this:-Code:Hello1++;if(Hello1==0x00){Hello2++;}Two more things:-1. Did you disable the watchdog?2. You don't need the __delay_ms(2) because the CPU is automatically halted while program memory is being written to (since it can't fetch instructions during this time!).

author: meliharicii
author_rank: Contributor
timestamp: November 20, 2016, 05:02:59 am
content: 1 WDT disable2 its trueNew thing "bootloader"Code:#include <htc.h>#define _XTAL_FREQ 4000000#define BASEADRESS 0x0009#define BASEADRESSL 0x09#define BASEADRESSH 0x00#define SET 0x01unsigned char ProgramData[]={0x16,0x83,0x13,0x03,0x01,0x86,0x30,0xFF,0x12,0x83,0x13,0x03,0x00,0x86,0x30,0x03\,0x00,0xF2,0x30,0x8A,0x00,0xF1,0x30,0x56,0x00,0xF0,0x0B,0xF0,0x2F,0xE4,0x0B,0xF1\,0x2F,0xE4,0x0B,0xF2,0x2F,0xE4,0x2F,0xEB,0x12,0x83,0x13,0x03,0x01,0x86,0x30,0x03\,0x00,0xF2,0x30,0x8A,0x00,0xF1,0x30,0x56,0x00,0xF0,0x0B,0xF0,0x2F,0xF4,0x0B,0xF1\,0x2F,0xF4,0x0B,0xF2,0x2F,0xF4,0x2F,0xFB,0x2F,0xDA,0x01,0x83,0x12,0x0A,0x11,0x8A\,0x2F,0xD7};void led(){TRISB=0x00;while(1){PORTB=0xFF;__delay_ms(500);PORTB=0x00;__delay_ms(500);}}void WritePM(unsigned char dath,unsigned char datl,unsigned char addrh,unsigned char addrl){//unsigned char addr;unsigned char datal=datl;unsigned char datah=dath;//addr=&datal;EEADR=addrl;EEADRH=addrh;EEDATA=datal;EEDATH=datah;EECON1bits.EEPGD=1; // EEPGD bits set 1000 0000 =0x80EECON1bits.WREN=1; // WREN bit set 0000 0100 =0x4INTCONbits.GIE=0; // GIE clear 0111 1111 =0x7FEECON2=0x55;EECON2=0xAA;EECON1bits.WR=1; //WR bit set 0000 0010 =0x2//asm("BSF EECON1,1"); //not define WRasm("NOP");asm("NOP");//asm("BCF EECON1,2");INTCONbits.GIE=1;//GIE set 1000 0000 =0x80EECON1bits.WREN=0;//WREN bit clear 1111 1011 =0xFBreturn;}void FillPrgMem(unsigned char *ptr,unsigned int sizeofprogram){unsigned char addrrh=BASEADRESSH;unsigned char addrrl=BASEADRESSL-1;unsigned char flag1=0;unsigned char flag2=0;unsigned int loopcalculate=sizeofprogram;while(loopcalculate){addrrl++;if(addrrl==0xFF){flag1=SET;addrrh++;}if(addrrh==0xFF){flag2=SET;}WritePM(*ptr,*(ptr+1),addrrh,addrrl);if(flag1==SET){addrrl=0x00;}if(flag2==SET){addrrh=0x00;}ptr=ptr+0x02;loopcalculate--;}}void main(void) {/**/void (*start)(void);FillPrgMem(ProgramData,88);start=BASEADRESS;start();}I am trying write bootloader and again I have some problem.I need your proposalI am still working on this code.