Multiplexing switches using a PIC ADC

Thread Starter

bance

Joined Aug 11, 2012
315
Hi all,

I'm trying to multiplex 3 switches onto a single pin using an ADC on a PIC16F684.

I have the switches arranged on a resistor divider network, providing a unique voltage to the analogue input, for each switch.

As far as I can tell the ADC is configured correctly, and since I have a useful timebase already configured, everything runs inside the ISR.

There are 4 outputs, green LED, amber LED, red LED and white LED (the white LED flashes at 1Hz.)

The scenario I'm trying to achieve is this:-
The coloured LEDs are off, until a switch is made, at which point the corresponding LED is turned on (but not latched) upon release the LED is extinguished, and the white LED continues flashing the whole time, at 1Hz.

The scenario I am realising is this:-
As soon as the programme runs, the green LED is lit, and making button 3 (the corresponding button) does nothing. However making either of the other buttons, extinguishes the green LED and illuminates the correct LED (amber or red.) The white LED continues to flash at 1 HZ.

Since I don't require 10 bit accuracy, and it simplifies the code, I am only using the 8 MSB. Then 0-5V equates to 0-255, full-scale, in the conversion.

This is where I think the error lies:-
Rich (BB code):
        banksel ADRESH
;        movlw   .0
;        xorwf   ADRESH
        movlw   .1
        subwf   ADRESH,w
        btfss   STATUS,C        ; see if adresh contains anything
        goto    INTX            ; if not exit,otherwise...
        movlw   .100
        subwf   ADRESH,w        ; is result >100? (switch3)
        btfss   STATUS,C
        goto    GRN
        movlw   .150
        subwf   ADRESH,w        ; is result >150? (switch1)
        btfss   STATUS,C
        goto    RED
        bsf     PORTC,4         ; else (switch2) turn on amber LED
        clrf    ADRESH
        goto    INTX
I have included a flow-chart depicting my rationale, a schematic for the circuit and the complete code.

Point me in the right direction please!!!!

The .txt file is code. the pdf is a flow-chart of rationale.
 

Attachments

Thread Starter

bance

Joined Aug 11, 2012
315
Thanks thatoneguy,

OK, so I added a zero to the first test and now the code works....

But I'm curious as to why it doesn't work with just subtracting 1, ADRESH can only be in two states at the start of the routine:-
  1. zero
  2. something
If I subtract 1 from 0 there's a borrow and a rollover and the result in W should be 255, with STATUS bit C cleared. (0 - 1 = 255, C=0)

If I subtract 1 from X there's no borrow and the result in W should be X-1, with STATUS bit C set. (X - 1 = (X-1), C=1)

Is it because I'm discarding the 2 LSB's?
 

thatoneguy

Joined Feb 19, 2009
6,359
Use the PICKit Debugging function to see what the ADC is actually reading, but it does fluctuate a bit. Your code was only testing for >150, without a test for near ground, which isn't always 0, if that makes sense.
 

Thread Starter

bance

Joined Aug 11, 2012
315
OK,

I was just wondering if discarding the LSB's had a gotcha....

I have to admit I struggled debugging this because putting an analogue input in stimulus seem's a bit daunting. I think I have to use register injection or something and the timing factor confused me!!!

Anyway thanks for the help,

Steve.
 

Markd77

Joined Sep 7, 2009
2,806
If you are using MPLAB simulator then for simple testing I would just put a breakpoint the line after moving the ADRES into W, then change W.
 
Top