Thoughts on why my included PIC asm code isn't doing as it should?

Thread Starter


Joined Jul 27, 2010
Hi, I've got quite a simple circuit to build around a PIC10F222, but having written the program and made up a test ciruit board it's not behaving as I was hoping and I was hoping I could get some thoughts from this forum. I'll check over my program first.

The idea is very simple; the uC starts with 2 of its I/O pins in output mode set high. When the ADC (GP0) reads a voltage above a certain limit, these 2 I/O pins (GP1 and GP2) switch low and never switch back high, no matter what the ADC measures until the uC is reset.

I have included my test code. Apart from plenty of optimisations that could be made, should this code do as I've outlined above? The board I have made up does not seem to do this And I'm struggling to figure out what's the problem, but the software should be easiest to check first.

It seems to work as expected, except that it switches off the I/O pins at a VERY low voltage. In the code I have it set to switch at around half the working voltage (around 2.5V running the chip at 5V) but it actually switches at around 0.007V (consistantly, I'm using a Fluke DMM to measure this). I'm using a 1k pot to set the ADC voltage so I think this should be fine.

If the code is fine, I at least know its something wrong with my test board.
Rich (BB code):
            LIST   P=PIC10F222

            ERRORLEVEL    -302        ; Supress bank switching messages

            __config    _MCLRE_ON & _CP_OFF & _WDT_OFF & _MCPU_OFF & _IOFSCS_8MHZ

            org 0
            limit     equ    0x10            ;Location to store voltage limit.
            movlw    d'128'                ;Conversion: 1 = 0.01953125V
            movwf    limit                ;Move into F

            movlw    b'11011111'            ;Set up option bits
            OPTION    w                    ;Set Option bits

            movlw    b'01000001'            ;Set up ADC to use AN0/GP0
            movwf    ADCON0                ;and move into ADC register
            movlw    b'00001001'            ;Set up GP1 and GP2 as outputs            
            TRIS     0x06                ;and move into TRIS    

            bsf        GPIO,GP1            ;Set output High
            bsf        GPIO,GP2            ;Set output High

start        clrwdt                        ;Clear watchdog timer
            bsf        GPIO,GP1            ;Make sure output is high (not needed?)
            bsf        GPIO,GP2            ;Make sure output is high (not needed?)
            bsf        ADCON0,GO            ;Start ADC cycle
ADCBegin    btfsc    ADCON0,NOT_DONE        ;Evaluate if ADC is finished
            goto    ADCBegin            ;Not done so keep checking
            movfw    ADRES                ;ADC finished. Move result into W
            subwf    limit                ;Subtract result from limit
            btfsc    STATUS,C            ;Evaluate if it went less than 0
            goto    start                ;Voltage less than limit, retest.
warning        bcf        GPIO,GP1            ;Voltage is over limit, set warning pin
            bcf        GPIO,GP2            ;Voltage is over limit, set warning pin
            clrwdt                        ;Keep watchdog timer clear
            goto    warning                ;Stay in warning loop



Joined Sep 7, 2009
You want to use "subwf limit, W" because the default is to put the result in "limit", so by the time it's been through the loop a few times any ADRES apart from 0 will cause a carry.

Thread Starter


Joined Jul 27, 2010
That was it, so simple. Thanks for the help, that piece of information will be ingrained in my memory for next time I need to do something similar.