Compiling for 16F877A using MPELAB - Page 1
Forum section: electronics / general

author: Keith956
author_rank: Regular Contributor
timestamp: January 10, 2021, 02:09:39 pm
content: I thought I'd learn PIC programming, so downloaded MPLAB X ide (v5.35) to my Mac.I have a Pickit 4 and a Waveshare Open16F877A board I got on ebay.I opened MPELAB and selected File->New Project then selected 'Microchip embedded' and 'Standalone project'.Set the family to midrange 8 bits inc PIC16, device to 16F877A.Hardware tools to the PICkit4, compiler to XC8Gave it a project name (Timer1_LED) and set as main project.I then created this main.c:/** File: main.c* Author: keith** Created on January 10, 2021, 1:16 PM*/// PIC16F877A Configuration Bit Settings// 'C' source line config statements// CONFIG#pragma config FOSC = EXTRC // Oscillator Selection bits (RC oscillator)#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)// #pragma config statements should precede project file includes.// Use project enums instead of #define for ON and OFF.#include <xc.h>void main(void){T1CKPS0=0;T1CKPS1=0;TMR1CS=0;TMR1L=(65536-12500)%256;TMR1H=(65536-12500)/256;GIE=1;PEIE=1;TMR1IE=1;TMR1ON=1;TRISB=0;PORTB=0;while(1){}}void __interrupt() isr(void){if(TMR1IE&&TMR1IF){TMR1L=(65536-12500)%256;TMR1H=(65536-12500)/256;TMR1IF=0;PORTB=PORTB+1;}}The config settings came from running Window->Target Memory Views->Configuration Bits and generating the source. The rest came from the waveshare demo example.It all seemed to compile OK except for a popup error: '/Users/keith/MPLABXProjects/Timer1_LED.X/dist/default/production/Timer1_LED.X.production. does not exist or is not executable'If I look, it seems to have compiled it:ls /Users/keith/MPLABXProjects/Timer1_LED.X/dist/default/productiontotal 408-rw-r--r-- 1 keith staff 44706 10 Jan 14:03 __eeprom.i-rw-r--r-- 1 keith staff 106 10 Jan 14:03 __eeprom.d-rw-r--r-- 1 keith staff 29318 10 Jan 14:03 __eeprom.p1-rw-r--r-- 1 keith staff 1358 10 Jan 14:03 Timer1_LED.X.production.sdb-rw-r--r-- 1 keith staff 30763 10 Jan 14:03 Timer1_LED.X.production.rlf-rw-r--r-- 1 keith staff 2426 10 Jan 14:03 Timer1_LED.X.production.o-rw-r--r-- 1 keith staff 26785 10 Jan 14:03 Timer1_LED.X.production.lst-rw-r--r-- 1 keith staff 11059 10 Jan 14:03 Timer1_LED.X.production.cmf-rw-r--r-- 1 keith staff 2903 10 Jan 14:03 Timer1_LED.X.production.sym-rw-r--r-- 1 keith staff 4739 10 Jan 14:03 Timer1_LED.X.production.elf-rw-r--r-- 1 keith staff 452 10 Jan 14:03 Timer1_LED.X.production.hex-rw-r--r-- 1 keith staff 841 10 Jan 14:03 Timer1_LED.X.production.hxl-rw-r--r-- 1 keith staff 383 10 Jan 14:03 Timer1_LED.X.production.mum-rw-r--r-- 1 keith staff 430 10 Jan 14:03 memoryfile.xml-rw-r--r-- 1 keith staff 12558 10 Jan 14:03 Timer1_LED.X.production.mapAnyone tell me what I'm doing wrong to get this 'does not exist' error?

author: nigelwright7557
author_rank: Frequent Contributor
timestamp: January 10, 2021, 03:23:12 pm
content: the .x file is the project name.Try loading project in again from "open project"

author: Keith956
author_rank: Regular Contributor
timestamp: January 10, 2021, 04:19:47 pm
content: Great, thanks. That seems to get past that error. It now compiles OK:CLEAN SUCCESSFUL (total time: 53ms)make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-confmake: Entering directory '/Users/keith/MPLABXProjects/Timer1_LED.X'make -f nbproject/Makefile-default.mk dist/default/production/Timer1_LED.X.production.hexmake: Entering directory '/Users/keith/MPLABXProjects/Timer1_LED.X'"/Applications/microchip/xc8/v2.20/bin/xc8-cc" -mcpu=16F877A -c -mdfp="/Applications/microchip/mplabx/v5.40/packs/Microchip/PIC16Fxxx_DFP/1.2.33/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/main.p1 main.c::: advisory: (2049) C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 libraries"/Applications/microchip/xc8/v2.20/bin/xc8-cc" -mcpu=16F877A -Wl,-Map=dist/default/production/Timer1_LED.X.production.map -DXPRJ_default=default -Wl,--defsym=__MPLAB_BUILD=1 -mdfp="/Applications/microchip/mplabx/v5.40/packs/Microchip/PIC16Fxxx_DFP/1.2.33/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -mwarn=-3 -Wa,-a -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -Wl,--memorysummary,dist/default/production/memoryfile.xml -o dist/default/production/Timer1_LED.X.production.elf build/default/production/main.p1::: advisory: (2049) C99 compliant libraries are currently not available for baseline or mid-range devices, or for enhanced mid-range devices using a reentrant stack; using C90 librariesMemory Summary:Program space used 48h ( 72) of 2000h words ( 0.9%)Data space used 4h ( 4) of 170h bytes ( 1.1%)EEPROM space used 0h ( 0) of 100h bytes ( 0.0%)Configuration bits used 1h ( 1) of 1h word (100.0%)ID Location space used 0h ( 0) of 4h bytes ( 0.0%)make: Leaving directory '/Users/keith/MPLABXProjects/Timer1_LED.X'make: Leaving directory '/Users/keith/MPLABXProjects/Timer1_LED.X'BUILD SUCCESSFUL (total time: 674ms)Loading code from /Users/keith/MPLABXProjects/Timer1_LED.X/dist/default/production/Timer1_LED.X.production.hex...Program loaded with pack,PIC16Fxxx_DFP,1.2.33,MicrochipLoading completedWhen I try and run 'make and program device' it comes back with an error:*****************************************************Connecting to MPLAB PICkit 4...Currently loaded versions:Application version............00.05.89Boot version...................01.00.00Script version.................00.03.77Script build number............648e375535Tool pack version .............1.1.774Connecting to MPLAB PICkit 4...Currently loaded versions:Boot version...................01.00.00Updating firmware application...Connecting to MPLAB PICkit 4...Currently loaded versions:Application version............00.06.08Boot version...................01.00.00Script version.................00.03.77Script build number............648e375535Tool pack version .............1.1.774Target voltage detectedTarget device PIC16F877A found.Device Revision Id = 0x8Calculating memory ranges for operation...Erasing...Verify failed. [config mem] 0x2007, expected 0x2fcf, got 0xecfProgramming did not complete.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 10, 2021, 04:57:13 pm
content: Quote from: Keith956 on January 10, 2021, 04:19:47 pmThis is the configuration word. The difference which it cannot write is 0x2100 - these are two unimplemented bits, which are set to 1 in your HEX file, but the device doesn't write them. The programmer shouldn't try to verify these bits, but it does. This is a bug in the tools. I guess the device is programmed anyway, so your program should run.You grabbed the newest tools and software and used a very old PIC. Both PICkit4 and MPLAB X were created when PIC16F877A was already obsolete. Even though it should work theoretically, you should expect problems.The best way is to get a newer PIC. They're substantially better than PIC16F877A.

author: Keith956
author_rank: Regular Contributor
timestamp: January 10, 2021, 06:44:25 pm
content: Thanks. Is it just the MPLAB recent version that has this issue - or the PICkit4?The 16F877A doesn't seem to be obsolete, it's available from the usual suppliers, if going back to an earlier rev of the software or e.g. a pickit3 would work that will mean I can use the board I already have...

author: Ian.M
author_rank: Super Contributor
timestamp: January 10, 2021, 07:26:05 pm
content: Unlike most other MCU manufacturers, Microchip doesn't discontinue obsolete parts until it is absolutely forced to by production line closure and lack of any 'in-house' alternative fabs still capable of running wafers on a legacy process. Instead they just jack up the price to avoid making a loss on the small remaining sales to users who for whatever reason cannot migrate to a newer part.

author: Keith956
author_rank: Regular Contributor
timestamp: January 11, 2021, 09:27:48 am
content: Would a 16F1789 be a suitable replacement? It appears to be pin compatible, not sure if would work in a board designed for a 16F877A - any thoughts?

author: Ian.M
author_rank: Super Contributor
timestamp: January 11, 2021, 10:00:26 am
content: That board should work with most 8 bit (PIC16/PIC18) non-USB 40 pin PICs, as Microchip have been fairly consistent with their pinouts across the 8 bit product ranges. It supports 5V and 3.3V Vdd, so you don't even have to avoid low voltage PICs. It wont work with 40 pin PIC24/dsPIC/PIC32 devices as their pinouts are totally incompatible.However a few of the peripherals can be on different pins, and many more recent PICs support remapping peripheral pins, either with a simple choice of a couple of pin locations or on PICs with PPS (Peripheral Pin Select), fully remappable to any PPS capable pin, so you should check that all peripheral modules that the board actually uses can be mapped to the same pins as a PIC16F877A - print out a large copy of the PIC16F877A DIP pinout from its datasheet, go through the datasheet of the PIC you propose to use and check you can map each peripheral used on the board to the same pin.Theboard schematicmay be helpful.Of course you'll have to completely rewrite the sample PIC16F877A code for your chosen PIC as its likely to have a rather different set of SFRs and subtle differences in peripheral initialization.If you are looking at reasonably modern PIC18 devices for more 'horespower', unlike the PIC18F....K20 series, the 'K22 series can operate at 5V. ThePIC18F46K22is basically the most maxed out 5V capable 40 pin PIC18 available and is pin (but not code) compatible with the PIC18F4520 which is supported by the board.

author: Keith956
author_rank: Regular Contributor
timestamp: January 11, 2021, 11:57:25 am
content: Thanks Ian, very helpful.I guess I was being a bit optimistic that what appeared to be a basic intro to microcontrollers was going to be simple!One remaining question: when you flash the code to the PIC, does it start executing it after - or do you need to do a power on reset, for example?

author: Ian.M
author_rank: Super Contributor
timestamp: January 11, 2021, 01:25:43 pm
content: Exiting programming mode is equivalent to a device reset. The programmer has control of the /MCLR pin, so whether or not the PIC runs immediately, depends on whether the programmer is configured to release /MCLR after programming *AND* if external /MCLR is enabled in the PIC CONFIG word(s).N.B. Its generally preferable to leave external /MCLR enabled (and use an external pullup to keep it high for normal operation) unless the application absolutely demands otherwise (which usually means you've chosen a PIC with too few pins) as otherwise the programmer cant hold the PIC in reset before programming and between programming phases, which, depending on the exact sequencing in your code, may cause problems with internal EEPROM corruption, or cause external circuits to glitch or may even make it very difficult to reprogram an already programmed PIC successfully.

author: NorthGuy
author_rank: Super Contributor
timestamp: January 11, 2021, 02:54:07 pm
content: Quote from: Keith956 on January 11, 2021, 11:57:25 amYes, it will execute right away, as soon as MCLR is high. Your PIC is probably executing your program already.Most PIC16/18 are pin-compatible, but each has its own set of periphery, so you need to make sure. If you want PIC16, look at the parts with 4 digits after 1 - these are the newest - PIC16F1xxxx. If you want PIC18, the newest are with Q40/Q41/Q43 at the end.

author: MarkF
author_rank: Super Contributor
timestamp: January 11, 2021, 03:41:14 pm
content: You have some errors in the configuration:- It's a crystal. Not a RC (external resistor/capacitor).- No code for watchdog timer ( CLRWDT(); // Clear watchdog timer ).Should be:Code:// CONFIG#pragma config FOSC = XT // Oscillator Selection bits (XT oscillator)#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)#pragma config PWRTE = ON // Power-up Timer Enable bit (PWRT enabled)#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)#pragma config LVP = ON // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit#pragma config WRT = OFF // Flash Program Memory Write Enable bits#pragma config CP = OFF // Flash Program Memory Code Protection bitI also get the configuration verify error using the old PICkit 2.Device is programmed and works fine. Ignore the config verify error.

author: Keith956
author_rank: Regular Contributor
timestamp: January 11, 2021, 10:26:46 pm
content: I checked and corrected the config bits. Although programming the device does seem to be doing something (pin 1 goes to the high programming voltage, ~9v I think, and I see activity on some other pins), nothing seems to be happening after.And there is no clk on pins 13/14 (I was expecting to see oscillation at the 4MHz vtal frequency), and more interestingly pin 1 is low - and is being held low by the PICkit. This does not seem to make sense either as from my understanding pin1 is active low reset?

author: MarkF
author_rank: Super Contributor
timestamp: January 11, 2021, 11:55:54 pm
content: Assuming you programmed it from within MPLAB...Check the 'Hold in Reset' button.Better yet disconnect it from the programmer, power it externally and pull the MCLR (pin 1) pin high.Edit: I guess the board does have a pull-up and switch for reset.Also, depending on how you're probing the oscillator pins, you may cause it to stop oscillating.

author: MarkF
author_rank: Super Contributor
timestamp: January 12, 2021, 12:20:06 am
content: You might want to add some test code that's not dependent on the timer.Code:// Configuration. . .// Include files#include <xc.h>// Defines#define _XTAL_FREQ 4000000L // 4 MHz clockvoid main(void){TRISB = 0b00000000; // Port B direction bitsTRISC = 0b11111110; // Port C direction bits// TODO: Add your timer initialization code herewhile (1) {PORTCbits.RC0 = 1; // Port C bit 0 set high__delay_ms(500); // Wait 500msPORTCbits.RC0 = 0; // Port C bit 0 set low__delay_ms(500); // Wait 500ms}}void __interrupt() isr(void){// TODO: Add your interrupt code here}You do know that in your configuration that onlyport B bit 0, 1, 2, 4 and 5 are I/O pins.- Bit 7 is Program data (PGD)- Bit 6 is Program clock (PGC)- Bit 3 is Low voltage program (PGM)

author: Ian.M
author_rank: Super Contributor
timestamp: January 12, 2021, 12:56:15 am
content: For the early LVP capable PICs like the PIC16F877A, noise on the PGM pin, or leaving that pin floating often causes issues. The sequence to enter LVP programming mode is so simple that the PIC can 'glitch' into it, effectively resetting it.I therefore strongly recommend configuring the PIC with:Code:#pragma config LVP = OFFto disable PGM, leaving RB3 as a normal I/O which requires no special considerations.

author: MarkF
author_rank: Super Contributor
timestamp: January 12, 2021, 04:24:32 am
content: Quote from: Ian.M on January 12, 2021, 12:56:15 amI agree.I always set LVP off unless I really need it.And you can always use an extra I/O pin.

author: Keith956
author_rank: Regular Contributor
timestamp: January 12, 2021, 09:48:00 am
content: Quote from: MarkF on January 11, 2021, 11:55:54 pmI'm probing pins 13/14 with a 10X scope probe, and see 0v with the board powered up, but not connected to the PICkit. If I press reset, pin 1 goes momentarily low - am I right in expecting that with a 4mhz crystal between pins 13&14 (and 22pf caps to ground) I should see it oscillating?

author: Ian.M
author_rank: Super Contributor
timestamp: January 12, 2021, 10:49:47 am
content: You need to check a couple of jumpers. Please see the attached image:(33), the PWR JMP should be in the 5V position (i.e. linking pins 2 (VCC) and 3 (5V) ), as Vbor is nom. 4.0V and you have BOREN on, so if Vcc is 3.3V it will never come out of reset.(34), the OSC JMP should be on pins 2 and 3, which I believe is towards the silver "4.000" MHz crystal, to connect the crystal.Additionally I recommend:(26) the LED JMP, RB6 and RB7 should be open as those pins are used for ICSP programming and will be used for ICD debugging. RB0-RB5 should be closed so you can use the LEDs on the rest of port B.(35) RA4 JMP should be closed as a pullup on the open drain pin RA4 is desirable.All other jumpers should be open to disconnect associated on-board accessories. Open jumper caps can be left 'parked' on a single pin of their jumper.

author: Keith956
author_rank: Regular Contributor
timestamp: January 12, 2021, 11:28:16 am
content: Ian, you're a star. Setting the PWR jumper to 5V did the trick - I could load the program, compile and program and run it.Also the verify issue seems to have gone away!

author: Ian.M
author_rank: Super Contributor
timestamp: January 12, 2021, 11:47:32 am
content: Yes. Many older PICs require Min. 4.5V Vdd for programming, which is a bit awkward if you are using them in a 3.3V system and can't isolate Vdd from the 3.3V rail.

author: TomS_
author_rank: Frequent Contributor
timestamp: January 13, 2021, 08:02:40 pm
content: Quote from: Keith956 on January 10, 2021, 02:09:39 pmI kind of feel like this should be more likeCode:if (PIR1 & TMR1IF) {to test the TMR1 interrupt flag in the PIR1 register, because at the moment you are just ANDing two masks with the same value, so it willalwaysexecute that branch of the code.

author: jackthomson43
author_rank: Contributor
timestamp: January 14, 2021, 05:39:41 pm
content: Quote from: Keith956 on January 12, 2021, 11:28:16 amGood to know that issue is resolved. Btw as you are a beginner so you should also try otherPIC compilerslike MikroC or CCS, they are paid but they have great libraries, which reduce the code significantly.

author: Ian.M
author_rank: Super Contributor
timestamp: January 14, 2021, 05:51:03 pm
content: I wouldn't touch MikroC with a bargepole due to its closed source libraries, with no source licence available, and lack of MPLAB integration. Fancy libraries are no help at all when you are hunting bugs and not certain whether the issue is with your code or the library and are reduced to having to wade through the disassembly because you cant examine the library source.

author: nigelwright7557
author_rank: Frequent Contributor
timestamp: April 29, 2021, 01:43:18 pm
content: Welcome to MPLAB !The pickit does fall over now and then.Mine wont even debug anything !I recently built up a pcb and tried to test it but MPLAB said no couldnt determine processor type.I thought maybe my SMD PIC wasnt soldered right so reworked it but still no joy.Had a look around the pcb for shorts and it all looked ok.Then turned around spotted other end of USB lead lying on the floor next to the PC !FFS all that work for nothing.Plugged it in and it worked straight away.The PK has improved over time and mine does crash as often as it used to.I was silly enough to buy my first PK3 off ebay and it often went wrong.When it finally packed up I bought one from Microchip and its been much better.I get the occasional problem but otherwise its fine.I know there was a problem with early PK4's blowing up some PIC's.They needed a 100R resistor in series with /MCLR pin.I like my Snap programmer best as its really fast.