Electronic – SDCC generates invalid programs for PIC 16f628a

linuxpic

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;
    }
}

Best Answer

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.

Change your config statement to:

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
can be found in your processor header file. Example for PIC18F2550:

#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