# SDCC generates invalid programs for PIC 16f628a

I've been learning how to code for PIC 16f628A and I wrote a very simple code to turn on a LED, which is connected to RB0, and keep it on. My original intention was to use SDCC and GPUTILS to compile the projects. However, it seems that SDCC or GPUTILS are generating invalid hex files, since the program doesn't act as expected whenever I upload it to the chip, the LED keeps off during all the program execution. A similar code compiled with CSC's compiler runs without any problem. Also, I got no success in executing a simple program compiled with GPASM. It's noteworthy that GPSIM executes all those programs perfectly and shows the pins are working as expected. I'm using K150 as programmer. I don't know what is going on with SDCC and GPUTILS.

#include "pic16f628a.h"
//#include "tsmtypes.h"
//#include "tsmpic.h"

#include <stdint.h>

//CONFIG:__config (_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT)

uint16_t __at 0x2007  __CONFIG = _CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT;

#define CLOCK_8MHZ 0
#define CLOCK_4MHZ 1

void main(void)
{
//SCS = 1;

TRISA = 0x00;
TRISB = 0x00;

#ifdef __16f628a    // Only compile this section for PIC16f628a
CMCON = 0x07;   /** Disable comparators.  NEEDED FOR NORMAL PORTA
*  BEHAVIOR ON PIC16f628a!          */
#endif

// Loop forever.
while(1) {
RB0 = 1;
}
}

• I'm using internal clock – user12707 Nov 5 '15 at 0:02
• which version of SDCC? I think PIC support was "in beta" for awhile, did they ever finalize the PIC target for release? – MarkU Nov 5 '15 at 1:00
• The version I'm using is 3.3. I was thinking the SDCC's support for PIC was better than that. – user12707 Nov 5 '15 at 10:55

What's the physical configuration of your MCLR pin? Your config has MCLR enabled, so if you aren't supplying VCC to the MCLR pin(pin4/RA5) then you're basically holding down the reset button.

uint16_t __at 0x2007  __CONFIG = _CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTOSC_OSC_NOCLKOUT;


In more general advice, I have found it useful to explicitly disable all the config options I'm not using. It prevents things like being bitten by MCLR, but it also forces me to read more of the datasheet and learn more of the microcontroller's features.

I also see from your comment that you're using SDCC 3.3. As of this post, SDCC 3.5.5 is available. The current SDCC manual recommends using #pragma config to set configuration bits, as the method used in your example is deprecated. Here's an excerpt from the manual:

4.6.17 Configuration Bits
Configuration bits (also known as fuses) can be configured using one of two methods:

• using #pragma config (see section 4.6.6), which is a preferred method for the new code. Example:

#pragma config CP0=OFF,OSCS=ON,OSC=LP,BOR=ON,BORV=25,WDT=ON,WDTPS=128,CCP2MUX=ON
#pragma config STVR=ON

• using ‘__code’ and ‘__at’ modifiers. This method is deprecated. Possible options should be ANDed and

#include <pic18fregs.h> //Contains config addresses and options
static __code char __at(__CONFIG1L) configword1l =
_USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L &
_PLLDIV_NO_DIVIDE__4MHZ_INPUT__1L & [...];
static __code char __at(__CONFIG1H) configword1h = [...];
static __code char __at(__CONFIG2L) configword2l = [...];
//More configuration words

Mixing both methods is not allowed and throws an error message ”mixing __CONFIG and CONFIG directives”.


So, using the method recommended in the SDCC manual, your config block would be:

/* CONFIGURATION Bits */
#pragma config CP=OFF,CPD=OFF,LVP=OFF,BOREN=OFF
#pragma config MCLRE=OFF,PWRTE=OFF,WDTE=OFF
#pragma config FOSC=INTOSCIO


I found that with pic16f628 and pic16f628A WatchDog Timer isnt disabled if you choose OSC and ClockOut. I dont know if is SDCC or gpasm fault.

## EDIT

The error is in the header file /usr/share/gputils/header/p16f628a.inc, the value for WDTE_OFF 0x3ff7 is wrong and doesn't disable the WDT for all the configurations but affects the clock configuration. The right value is 0x3ffb. And the file p16f628.inc has the wrong value.

The above answer with pragma thing is for the 18f family not the old 16f628.