Hi Friends!

I am experiencing some strange activity with the A/D converter on my project. The design uses a

PIC16F876A.

I have a tight loop which monitors the voltage from an output circuit and either turns on or off PWM. Essentially a closed loop, special purpose power supply. The design works great, however, after about three minutes the A/D stops reading the data correctly and the power supply runs away as a result.

I have monitored the input voltage to the A/D on either side of its 10K series resistor. While operating normally I have approx. .328 volts on both sides. When the anomoly occurs the voltage on the processor side of the input resistor goes to 0, while the actual input voltage is still correct. At that point the firmware, seeing no voltage, starts increasing the PWM until the supply maxes out. Of course my output voltage is dangerously high at that time!

The only thing I can relate this too is as if the processor has somehow changed the port A pin from an input to an output and set it low? My firmware is a very tight loop however and I don't see how this could happen. In fact the program is continued and is not resetting.

I switched the input from AN4 to AN0 and the problem follows.

Here is the source:

'INCLUDES
Include "Modedefs.bas" 'for serial out routine

'DEFINES
DEFINE OSC 20 'use 20MHz crystal

'Define ADCIN parameters
Define ADC_BITS 10 ' Set number of bits in result
'Define ADC_CLOCK 3 ' Set clock source (3=rc)
Define ADC_CLOCK 0 ' Set clock source (0=clock / 2)
Define ADC_SAMPLEUS 50 ' Set sampling time in uS

'set WDT for 2.3 sec time out and no R pullups on portB
OPTION_REG = %10001111

'PORT DIRECTION, NAME ASSIGNMENTS
trisA = %11111111 'All inputs on Port A
ADCON1 = %00000000 'Set PORTA analog inputs
trisB = %00000011 'Set PortB outputs except 0 and 1
trisC = %10010000 'All outputs except Serial and Microwire data in

wKVset = 3000 ' 15300 actual = 14,500

gosub setup_PWM


Main001:
'GOSUB PWM_Off
GOSUB Get_HV

if wHVvolts > wKVset then
GOSUB PWM_Off
Else
gosub PWM_ON
ENDIF

goto Main001

Subs -

Get_HV:
'pause 1 ' don't delay, enough time spent in main
ADCIN 0, AdData[0] ' Read HV channel 4 to adval
'ADCIN 2, AdData[2] ' Read area pot for test sim

' For test purposes
'SEROUT pTXD, T9600, ["Raw HV AD: ", #AdData[0], 10,13]

' wHVvolts = (AdData[0] */ 82) >> 2 ' equates to: (adval * 82)/1024
' wHVvolts = wHVvolts * 10

wHVvolts = (AdData[0] /132)
wHVvolts = wHVvolts * 100
' wHVvolts now contains actual HV in volts
' For test purposes
'SEROUT pTXD, T9600, ["Actual HV: ", #wHVvolts, " Volts DC", 10,13]

Return


Setup_PWM:

TRISC.2 = 1 ' Set PORTC.2 (CCP1) to disable
PR2 = %00001000 ' Set PWM Period to 34 KHz
CCP1CON = %00001100 ' Set CCP1 to PWM, ACTIVE HIGH
CCPR1L = 0 'Set PWM Duty-Cycle to 0%
CCP1CON.4 = 0 ' Ten bits, set
CCP1CON.5 = 0
PIR1.1=0
T2CON = %00000111 ' Timer2 ON, Prescale 1:16
While PIR1.1=0 ' Wait for Timer 2 Overflow
wend
TRISC.2 = 0 'Set port C as output to enable

return


PWM_ON:
PWM_Duty = 500
CCP1CON.4 = PWM_Duty.1 ' Ten bits, set
CCP1CON.5 = PWM_Duty.0
CCPR1L = 4 'PWM_Duty >> 2 'Set PWM Duty-Cycle to 50%
return

PWM_OFF:
PWM_Duty = 0
CCP1CON.4 = PWM_Duty.0 ' Ten bits, set
CCP1CON.5 = PWM_Duty.0
CCPR1L = 0 'PWM_Duty >> 2 'Set PWM Duty-Cycle to 0%
return

Any advice would be appreciated.

Thanks in advance,
TR