Re: SOLVED: How can I reduce ADC drift
Either my PIC is damaged, or something is whacked inside the breadboard.
105c and wasn't stopping.
Code:
#CONFIG
__config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
__config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
__config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_OFF
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
DEFINE OSC 4
ANSELA = %00000010 ' Pin A1 = ADC (B5K)
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000010 ' Pin A1 = ADC input 1
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11000000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
ADCinput var WORD
Pause 500 ' Let PIC and LCD stabilize
ADCinput = 0
Mainloop:
adcinput = 1023
end
Re: SOLVED: How can I reduce ADC drift
i simply hate this , all these pins made into outputs , shorted to gnd , no attempt to set them low
at power up are they low? before you short it all out
worst idea ever for breadboarding , i leave all pins as inputs unless they need to be an output
all this care re floating inputs is complete bull shit. for a battery operated device it will save a few microwatts that's it.
for the finished manufactured product sure do it , for bread boarding its dangerous nonsense where every mistake will be a bad one
Code:
TRISA = %00000010 ' Pin A1 = ADC input 1
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11000000
Quote:
I took everything non-essential off the breadboard (just kept my 2 power LEDs):
and all the dangerous grounds
Re: SOLVED: How can I reduce ADC drift
I realized something was seriously wrong when that nothing circuit was taking 670mA. I added:
Code:
PORTA = %00000000
PORTB = %00000000
PORTC = %00000000
Before the ANSELx and TRISx and it's taking 20mA now, 33c with no ADC, just ADCinput set at 1023 and the HSEROUT loop.
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
... i leave all pins as inputs unless they need to be an output
all this care re floating inputs is complete bull shit....
I try to keep my development code as close to final as possible, cause I know I'll forget to change stuff back. At least this way I can fire and forget the pin initialization.
But yeah, major bonehead move on my part. I put the old PIC back in and it runs at 20mA too. Gonna leave that 1st PIC in, just in case I do some other numbnut thing. :D
Thanks mucho Richard.
EDIT: Now this warning will follow my code for the rest of the development.
Code:
PORTA = %00000000 '-------------------------------------------'
PORTB = %00000000 ' ALWAYS SET PINS LOW FIRST '
PORTC = %00000000 '-------------------------------------------'
Re: SOLVED: How can I reduce ADC drift
Quote:
I try to keep my development code as close to final as possible, cause I know I'll forget to change stuff back. At least this way I can fire and forget the pin initialization
.
grounding unused pins and setting them as outputs is pointless , useless and potentially catastrophic
just leaving them as analog is ten times easier and can never do any harm, setting them as input with wpu on is also ok and can never do any harm
if the device is not battery powered its not worth any sort of effort
Re: SOLVED: How can I reduce ADC drift
- digital input,
- weak pull-up ON,
- pin not connected.
I try to stay away from analog settings; no idea why. Maybe cause I started using only digital way back when.
https://skills.microchip.com/introdu...tecture/691929
Unit will always be powered by wall adapter, or possibly USB; but never battery..
Re: SOLVED: How can I reduce ADC drift
According to this:
https://skills.microchip.com/introdu...tecture/691929
Quote:
The pull-up is disabled automatically when either TRIS is set to an output or the pin is set as an analog input. These changes to TRIS and ANSEL will override WPU settings.
I can just set all pull-ups ON, leave the unused pins unconnected and forget about them. Then use the others as I wish in ANSEL and TRIS.
The only times I need to be concerned with WPU is on pins that must not be disturbed for whatever special reason.
Code:
WPUA = %11111111 '----------------------------------------------------------------'
WPUB = %11111111 ' ALWAYS SET WEAK PULL-UPS ON ALL PINS FIRST '
WPUC = %11111111 '----------------------------------------------------------------'
' CHANGES TO ANSEL AND TRIS WILL OVERRIDE AS REQUIRED '
'----------------------------------------------------------------'
ANSELA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC (B5K) not implemented yet
' Pin A1 = ADC (B5K)
' Pin A0 = ADC (voltage divider) not implemented yet
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC input 2 not implemented yet
' Pin A1 = ADC input 1
' Pin A0 = ADC input 0 not implemented yet
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11000000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
EDIT: I can even leave PORT at the top in case a pin is left as analog output.
Code:
PORTA = %00000000 '-------------------------------------------'
PORTB = %00000000 ' ALWAYS SET PINS LOW FIRST '
PORTC = %00000000 '-------------------------------------------'
Or did I miss something important...? :(
1 Attachment(s)
Re: SOLVED: How can I reduce ADC drift
it looks to me that you are creating problems and complications trying to solve a problem that does not exist.
generic pin control solutions will never work for all chips, there are too many chip variations.
pic pins to date always default to inputs, analog if possible. leave them that way unless you need one to be different.
each and every pin you employ needs to configured to suit its usage
mcc makes it easy
Attachment 9924
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
it looks to me that you are creating problems and complications...
My memory is getting worse by the year. That's why I try ways to set my code so it's easy to copy and modify for future modules. Of course it rarely works.
Having WPUA.1 = 1 caused leakage to VSS; it wasn't completely 0; varying in the 1.1mV range. My ADC reading never reached 0.
I took out the Port = 0 settings, set WPU properly instead of leaving ANSEL/TRIS override it, and now my ADC reading varies from 0 to 1.
Code:
WPUA = %11111101 '----------------------------------------------------------------'
WPUB = %11111111 ' ALWAYS SET WEAK PULL-UPS ON ALL PINS FIRST '
WPUC = %11111111 '----------------------------------------------------------------'
' CHANGES TO ANSEL AND TRIS WILL OVERRIDE AS REQUIRED '
'----------------------------------------------------------------'
ANSELA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC (B5K) not implemented yet
' Pin A1 = ADC (B5K)
' Pin A0 = ADC (voltage divider) not implemented yet
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000010 ' Pin A3 = SW input not implemented yet
' Pin A2 = ADC input 2 not implemented yet
' Pin A1 = ADC input 1
' Pin A0 = ADC input 0 not implemented yet
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11000000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
Re: SOLVED: How can I reduce ADC drift
Yeah, FVR gave me a dead spot at the high end. These pots already have a slight deadzone at both ends, so FVR made it much more apparent.
Code:
adcin 1, ADCreading
ADCinput = ADCreading >> 1
Has light jitter with this pot.
Code:
adcin 1, ADCreading
ADCinput = ADCreading >> 2
Works, but if I get a pot that's slightly "less good", I'll get jitters.
I can work with >> 3, that still gives me 128 positions. That<S plenty of increments for a manual control, and I can always multiply by 4 when the flight sim absolutely wants 1024.
Re: SOLVED: How can I reduce ADC drift
Quote:
Having WPUA.1 = 1 caused leakage to VSS; it wasn't completely 0; varying in the 1.1mV range. My ADC reading never reached 0.
makes little sense , the wpu is approx 47k its impact on a 5k pot should not be noticeable , this may be indicative of a different problem
Quote:
I took out the Port = 0 settings, set WPU properly instead of leaving ANSEL/TRIS override it, and now my ADC reading varies from 0 to 1.
ansel does not override wpu , what you claim makes zero sense
Quote:
Has light jitter with this pot.
your power supply must be very noisy or the pots are complete crap [possibly microphonic] to get such poor results
Re: SOLVED: How can I reduce ADC drift
Quote:
My memory is getting worse by the year. That's why I try ways to set my code so it's easy to copy and modify for future modules. Of course it rarely works.
it happens to us all , especially if you don't use the knowledge regularly. that why i participate in the forum to keep my "practice" hours up.
the problem here is copying errors forward and propagating ancient pic myths. setting each pin as you employ it to make it work as you want it to is not difficult. imo it is actually easier and less prone to error.
using mcc documents it all for you and consolidates all pin setting into one file, it could not be easier
1 Attachment(s)
Re: SOLVED: How can I reduce ADC drift
Quote:
Originally Posted by
richard
...ansel does not override wpu , what you claim makes zero sense ...s
Got that info here, at the bottom:
https://developerhelp.microchip.com/...ly/digital-io/
Quote:
The pull-up will be disabled automatically when either TRIS is set to an output or the pin is set as an analog input. These changes to TRIS and ANSEL will override WPU settings
Anyways, I'm setting the WPU only for the unused pins now (even analog), playing it safe despite that quote above.
Quote:
Originally Posted by
richard
...your power supply must be very noisy or the pots are complete crap [possibly microphonic] to get such poor results
The TPS56637 seems very stable, especially since I have nothing on that one. The LCD and LED strip are on a separate TPS56637.
What do you mean by microphonic? Are you talking about the taper? Mine are linear, like Bourns B:
Attachment 9925
Re: SOLVED: How can I reduce ADC drift
Quote:
What do you mean by microphonic?
like a microphone in that the slightest vibration causes the resistance to vary
Quote:
The TPS56637 seems very stable
it might be stable but it can till be noisy , use your scope AC coupled X1 probe on say 5mV range 5mS/div, measure peak to peak noise
Re: SOLVED: How can I reduce ADC drift
and to be sure, use a resistor divider with cap of 1uF to ground from the tap point to ADC, instead of POT. If your results are stable then you can replace with a pot and see if the problem is the pot itself.
Ioannis
p.s. corrected the drift to jitter on the Thread title
Re: SOLVED: How can I reduce ADC jitter
Oh I still get jitter at 1023 or ">> 1". I'm running at ">> 2" and had to use Vref- (3R/1K) cause I was having some instability at the 0 end of scale. The pots already have a slight deadzone under 5% and above 95% (look at the chart above - that was from manuf spec sheet).
I only have a resolution of 256, with a maximum of 88 detents because I TX with changes in ADC larger than 2. But I'm still happy because this is good enough for my application (so far).
https://youtu.be/t96JQeyqYL4
TX:
Code:
#CONFIG
__config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
__config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
__config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_OFF
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
;--- Interrupts ----------------------------------------------------------------
include "I:\Project_v2\PBP\PBP_Includes\DT_INTS-14_16F1885x-7x.bas"
include "I:\Project_v2\PBP\PBP_Includes\ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _RXInterrupt, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
DEFINE OSC 32
DEFINE ADC_BITS 10 ' 10-bit Analog to digital
DEFINE ADC_SAMPLEUS 5 ' Set sampling time in uS
DEFINE HSER_RXREG PORTC
DEFINE HSER_RXBIT 7
DEFINE HSER_TXREG PORTC
DEFINE HSER_TXBIT 6
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
Define HSER_BAUD 115200
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRGH 0
DEFINE HSER_SPBRG 68
define CCP1_REG 0 ' Must clear unused CCP pins or else unpredictable results
DEFINE CCP1_BIT 0
define CCP2_REG 0
DEFINE CCP2_BIT 0
define CCP3_REG 0
DEFINE CCP3_BIT 0
define CCP4_REG 0
DEFINE CCP4_BIT 0
define CCP5_REG 0
DEFINE CCP5_BIT 0
;--- Setup registers -----------------------------------------------------------
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
INTCON = %11000000 ' INTERRUPT CONTROL REGISTER
' bit 7 GIE: Global Interrupt Enable bit
' 1 = Enables all active interrupts
' 0 = Disables all interrupts
' bit 6 PEIE: Peripheral Interrupt Enable bit
' 1 = Enables all active peripheral interrupts
' 0 = Disables all peripheral interrupts
PIE3 = %00100000 ' PERIPHERAL INTERRUPT ENABLE REGISTER 3
' bit 5 RCIE: USART Receive Interrupt Enable bit
' 1 = Enables the USART receive interrupt
' 0 = Enables the USART receive interrupt
PIR3 = %00000000 ' PERIPHERAL INTERRUPT REQUEST REGISTER 3
' bit 5 RCIF: EUSART Receive Interrupt Flag (read-only) bit (1)
' 1 = The EUSART receive buffer is not empty (contains at least one byte)
' 0 = The EUSART receive buffer is empty
FVRCON = %0000000 ' FIXED VOLTAGE REFERENCE CONTROL REGISTER
' bit 7 FVREN: Fixed Voltage Reference Enable bit
' 1 = Fixed Voltage Reference is enabled
' bit 1-0 ADFVR<1:0>: ADC FVR Buffer Gain Selection bit
' 11 = ADC FVR Buffer Gain is 4x, (4.096V)(2)
ADCON0 = %10000100 ' ADC CONTROL REGISTER 0
' bit 7 ADON: ADC Enable bit
' 1 = ADC is enabled
' bit 2 ADFRM0: ADC results Format/alignment Selection
' 1 = ADRES and ADPREV data are right-justified
ADCON2 = %00000000 ' ADC CONTROL REGISTER 2
' bit 2-0 ADMD<2:0>: ADC Operating Mode Selection bits(1)
' 000 = Basic (Legacy) mode
ADCLK = %00001111 ' ADC CLOCK SELECTION REGISTER
' bit 5-0 ADCCS<5:0>: ADC Conversion Clock Select bits
' 1111 = FOSC/32
ADREF = %00010000 ' ADC REFERENCE SELECTION REGISTER
' bit 4 ADNREF: ADC Negative Voltage Reference Selection bit
' 1 = VREF- is connected to VREF- pin
' 0 = VREF- is connected to AVSS
' bit 1-0 ADPREF: ADC Positive Voltage Reference Selection bits
' 11 = VREF+ is connected to FVR_buffer 1
' 10 = VREF+ is connected to VREF+ pin
' 00 = VREF+ is connected to VDD
ADPCH = %00000000 ' ADC POSITIVE CHANNEL SELECTION REGISTER
' 000000 = ANA0
WPUA = %01100000 ' Pin A7 = ADC-A0 debug
' Pin A4 = ADC-A4 (B10K)
' Pin A3 = SW external pull-down
' Pin A2 = Vref-
' Pin A1 = ADC-A1 (B5K w/SW)
' Pin A0 = ADC-A0 (B5K)
WPUB = %11111111
WPUC = %00100111 ' Pin C7 = RX
' Pin C6 = TX
' Pin C4 = ADC-C4 (B10K)
' Pin C3 = ADC-C3 (B10K)
ANSELA = %00010011 ' Pin A4 = ADC-A4 (B10K)
' Pin A1 = ADC-A1 (B5K w/SW)
' Pin A0 = ADC-A0 (B5K)
ANSELB = %00000000
ANSELC = %00011000 ' Pin C7 = RX
' Pin C6 = TX
' Pin C4 = ADC-C4 (B10K)
' Pin C3 = ADC-C3 (B10K)
TRISA = %00011011 ' Pin A7 = ADC-A0 debug
' Pin A4 = ADC-A4 (B10K)
' Pin A3 = SW
' Pin A1 = ADC-A1 (B5K w/SW)
' Pin A0 = ADC-A0 (B5K)
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
TRISC = %11011000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
' Pin C4 = ADC-C4 (B10K)
' Pin C3 = ADC-C3 (B10K)
A0debug var LATA.7
SW var PORTA.3
MsgData var byte[3]
MsgCode VAR BYTE
ADCinput var WORD
ADCcalc var WORD
ADCdiff var WORD
ADCchange var byte
ShiftRight var byte
OldADC var WORD
OldADC_A0 var WORD
OldADC_A1 var WORD
OldADC_A4 var WORD
OldADC_C3 var WORD
OldADC_C4 var WORD
OldSW var BYTE
RXoccurred var BYTE
A0debug = 0
RXoccurred = 0 ' Clear RX flag
@ INT_ENABLE RX_INT ; Enable USART Receive interrupts
Pause 1500 ' Let PIC and LCD stabilize
goto Start
;--- Interrupts ----------------------------------------------------------------
RXInterrupt:
hserin [ STR MsgData\3 ]
while BAUDCON1.6 = 0 ' Check RCIDL bit
wend
RXoccurred = 1 ' Set flag
@ INT_RETURN
;--- Subroutines ---------------------------------------------------------------
SendData:
hserout [ MsgData[0], MsgData[1], MsgData[2] ]
while TX1STA.1 = 0 ' Check TRMT bit
wend
while RXoccurred = 0 ' Check for interrupt
wend
RXoccurred = 0 ' Set flag
ADCchange = 1
RETURN
ProcessADC:
ADCchange = 0
if ADCcalc < oldADC then
ADCdiff = oldADC - ADCcalc
else
ADCdiff = ADCcalc - oldADC
endif
IF ADCdiff > 2 then ' Check for Diff over 2
MsgData[0] = MsgCode
if ADCcalc <> oldADC then ' ADC value changed
MsgData[1] = ADCcalc.byte1 : MsgData[2] = ADCcalc.byte0
GOSUB SendData
endif
ELSE
IF ADCdiff > 0 then ' Check for Diff over 0
if ADCcalc = 0 then ' Reached end of rotation
MsgData[1] = ADCcalc.byte1 : MsgData[2] = ADCcalc.byte0
GOSUB SendData
ELSE
if ADCcalc = 255 then ' Reached end of rotation
MsgData[1] = ADCcalc.byte1 : MsgData[2] = ADCcalc.byte0
GOSUB SendData
endif
endif
endif
endif
RETURN
Start:
ADCinput = 0 : ADCdiff = 0 : ADCcalc = 0
OldADC_A0 = 9999 : OldADC_A1 = 9999 : OldADC_A4 = 9999 : OldADC_C3 = 9999 : OldADC_C4 = 9999
OldSW = 9
ShiftRight = 2
Mainloop:
rem ADC A0 test
MsgCode = 0
adcin 0, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_A0
gosub ProcessADC
if ADCchange = 1 then
A0debug = 1
OldADC_A0 = ADCcalc
A0debug = 0
endif
rem ADC A1 test
MsgCode = 1
adcin 1, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_A1
gosub ProcessADC
if ADCchange = 1 then
OldADC_A1 = ADCcalc
endif
rem SW A3
MsgCode = 3
if SW <> oldSW then
oldSW = SW
MsgData[0] = MsgCode : MsgData[1] = oldSW :MsgData[2] = " "
GOSUB SendData
endif
rem ADC A4 test
MsgCode = 4
adcin 4, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_A4
gosub ProcessADC
if ADCchange = 1 then
OldADC_A4 = ADCcalc
endif
rem ADC C3 test
MsgCode = 5
adcin 19, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_C3
gosub ProcessADC
if ADCchange = 1 then
OldADC_C3 = ADCcalc
endif
rem ADC C4 test
MsgCode = 6
adcin 20, ADCinput
ADCcalc = ADCinput >> ShiftRight
oldADC = OldADC_C4
gosub ProcessADC
if ADCchange = 1 then
OldADC_C4 = ADCcalc
endif
GOTO Mainloop
end
RX:
Code:
#CONFIG
__config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_OFF & _FCMEN_ON
__config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _LPBOREN_OFF & _BOREN_ON & _BORV_LO & _ZCD_OFF & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
__config _CONFIG3, _WDTCPS_WDTCPS_11 & _WDTE_OFF & _WDTCWS_WDTCWS_7 & _WDTCCS_LFINTOSC
__config _CONFIG4, _WRT_OFF & _SCANE_available & _LVP_OFF
__config _CONFIG5, _CP_OFF & _CPD_OFF
#ENDCONFIG
;--- Interrupts ----------------------------------------------------------------
include "I:\Project_v2\PBP\PBP_Includes\DT_INTS-14_16F1885x-7x.bas"
include "I:\Project_v2\PBP\PBP_Includes\ReEnterPBP.bas"
ASM
INT_LIST macro ; IntSource, Label, Type, ResetFlag?
INT_Handler RX_INT, _RXInterrupt, PBP, no
endm
INT_CREATE ; Creates the interrupt processor
ENDASM
DEFINE OSC 32
DEFINE LCD_DREG PORTB ' Set LCD data port
DEFINE LCD_DBIT 0 ' Set starting data bit
DEFINE LCD_RSREG PORTC ' Set LCD register select port
DEFINE LCD_RSBIT 4 ' Set LCD register select bit
DEFINE LCD_EREG PORTC ' Set LCD enable port
DEFINE LCD_EBIT 5 ' Set LCD enable bit
DEFINE LCD_BITS 4 ' Set LCD bus size
DEFINE LCD_LINES 4 ' Set number of lines on LCD
DEFINE LCD_COMMANDUS 1000 ' Set command delay time in microseconds
DEFINE LCD_DATAUS 50 ' Set data delay time in microseconds
define CCP1_REG 0 ' Must clear unused CCP pins or else unpredictable results
DEFINE CCP1_BIT 0
define CCP2_REG 0
DEFINE CCP2_BIT 0
define CCP3_REG PORTB ' PWM Pulse out to LCD backlight
DEFINE CCP3_BIT 5
define CCP4_REG 0 ' Must clear unused CCP pins or else unpredictable results
DEFINE CCP4_BIT 0
define CCP5_REG PORTA ' PWM Pulse out to LED strips
DEFINE CCP5_BIT 4
DEFINE HSER_RXREG PORTC
DEFINE HSER_RXBIT 7
DEFINE HSER_TXREG PORTC
DEFINE HSER_TXBIT 6
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
Define HSER_BAUD 115200
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRGH 0
DEFINE HSER_SPBRG 68
;--- Setup registers -----------------------------------------------------------
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
INTCON = %11000000 ' INTERRUPT CONTROL REGISTER
' bit 7 GIE: Global Interrupt Enable bit
' 1 = Enables all active interrupts
' 0 = Disables all interrupts
' bit 6 PEIE: Peripheral Interrupt Enable bit
' 1 = Enables all active peripheral interrupts
' 0 = Disables all peripheral interrupts
PIE3 = %00100000 ' PERIPHERAL INTERRUPT ENABLE REGISTER 3
' bit 5 RCIE: USART Receive Interrupt Enable bit
' 1 = Enables the USART receive interrupt
' 0 = Enables the USART receive interrupt
PIR3 = %00000000 ' PERIPHERAL INTERRUPT REQUEST REGISTER 3
' bit 5 RCIF: EUSART Receive Interrupt Flag (read-only) bit (1)
' 1 = The EUSART receive buffer is not empty (contains at least one byte)
' 0 = The EUSART receive buffer is empty
CCP3CON = %10001111 ' CCP3 CONTROL REGISTER
' bit 7 EN: CCPx Module Enable bit
' 1 = CCPx is enabled
' bit 4 FMT: CCPW (Pulse Width) Alignment bit
' MODE = PWM mode
' 0 = Right-aligned format
' bit 3-0 MODE<3:0>: CCPx Mode Select bits(1)
' 1111 = PWM mode
CCP5CON = %10001111 ' CCP5 CONTROL REGISTER
' bit 7 EN: CCPx Module Enable bit
' 1 = CCPx is enabled
' bit 4 FMT: CCPW (Pulse Width) Alignment bit
' MODE = PWM mode
' 0 = Right-aligned format
' bit 3-0 MODE<3:0>: CCPx Mode Select bits(1)
' 1111 = PWM mode
ADCON0 = %00000000 ' ADC CONTROL REGISTER 0
WPUA = %11101111 ' Pin A7 = ADC-A0 debug
WPUB = %11011111
WPUC = %00111111
ANSELA = %00000000
ANSELB = %00000000
ANSELC = %00000000
TRISA = %00000000 ' Pin A7 = ADC-A0 debug
' Pin A4 = PWM to LED strips
TRISB = %00000000 ' Pin B7 = ...not available, ICSPDAT
' Pin B6 = ...not available, ICSPCLK
' Pin B5 = PWM to LCD backlight
TRISC = %11000000 ' Pin C7 = RX *** Datasheet requirement, INPUT ***
' Pin C6 = TX *** Datasheet requirement, INPUT ***
A0debug var LATA.7
MsgData var byte[3]
MsgCode VAR BYTE
MsgADC_A0 VAR WORD
MsgADC_A1 VAR WORD
MsgADC_A4 VAR WORD
MsgADC_C3 VAR WORD
MsgADC_C4 VAR WORD
MsgSW VAR BYTE
SWtext VAR BYTE[2]
HPWMlcdBL var BYTE
HPWMledstripe var BYTE
DefaultLcdBL var BYTE
DefaultLedstripe var BYTE
RXoccurred var BYTE
A0debug = 0
HPWMlcdBL = 255 ' OFF
HPWMledstripe = 0 ' OFF
HPWM 3, HPWMlcdBL, 1953
HPWM 5, HPWMledstripe, 1953
RXoccurred = 0 ' Clear RX flag
Pause 200 ' Let PIC and LCD stabilize
goto Start ' Jump over sub-routines
;--- Interrupts ----------------------------------------------------------------
RXInterrupt:
hserin [ STR MsgData\3 ]
' while BAUDCON1.6 = 0 ' Check RCIDL bit
' wend
RXoccurred = 1 ' Set flag
@ INT_RETURN
;--- Subroutines ---------------------------------------------------------------
SendConfirmation:
hserout [ MsgData[0], MsgData[1], MsgData[2] ]
' while TX1STA.1 = 0 ' Check TRMT bit
' wend
RETURN
ProcessADC_A0:
A0debug = 1
MsgADC_A0.byte1 = MsgData[1] : MsgADC_A0.byte0 = MsgData[2]
LCDOUT $FE, $C0+3, DEC4 MsgADC_A0
RXoccurred = 0 ' Clear RX flag
HPWMlcdBL = MsgADC_A0
HPWM 3, HPWMlcdBL, 1953
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, "x" : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
A0debug = 0
RETURN
ProcessADC_A1:
MsgADC_A1.byte1 = MsgData[1] : MsgADC_A1.byte0 = MsgData[2]
LCDOUT $FE, $94+3, DEC4 MsgADC_A1
RXoccurred = 0 ' Clear RX flag
HPWMledstripe = 255 - MsgADC_A1 ' Invert value
HPWM 5, HPWMledstripe, 1953
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, "x" : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
RETURN
ProcessSW3:
if MsgData[1] = 0 then
SWtext[0] = "O" : SWtext[1] = "f" : SWtext[2] = "f"
ELSE
SWtext[0] = "O" : SWtext[1] = "n" : SWtext[2] = " "
ENDIF
LCDOUT $FE, $D4+3, SWtext[0], SWtext[1], SWtext[2], " "
RXoccurred = 0 ' Clear RX flag
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, "x" : LCDOUT $FE, $D4+19, " "
RETURN
ProcessADC_A4:
MsgADC_A4.byte1 = MsgData[1] : MsgADC_A4.byte0 = MsgData[2]
RXoccurred = 0 ' Clear RX flag
LCDOUT $FE, $C0+14, DEC4 MsgADC_A4
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, "x"
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
RETURN
ProcessADC_C3:
MsgADC_C3.byte1 = MsgData[1] : MsgADC_C3.byte0 = MsgData[2]
RXoccurred = 0 ' Clear RX flag
LCDOUT $FE, $94+14, DEC4 MsgADC_C3
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+8, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+8, " " : LCDOUT $FE, $94+19, "x"
LCDOUT $FE, $D4+8, " " : LCDOUT $FE, $D4+19, " "
RETURN
ProcessADC_C4:
MsgADC_C4.byte1 = MsgData[1] : MsgADC_C4.byte0 = MsgData[2]
RXoccurred = 0 ' Clear RX flag
LCDOUT $FE, $D4+14, DEC4 MsgADC_C4
MsgData[0] = MsgCode : MsgData[1] = "O" : MsgData[2] = "K"
gosub SendConfirmation
LCDOUT $FE, $C0+9, " " : LCDOUT $FE, $C0+19, " "
LCDOUT $FE, $94+9, " " : LCDOUT $FE, $94+19, " "
LCDOUT $FE, $D4+9, " " : LCDOUT $FE, $D4+19, "x"
RETURN
Start:
HPWMlcdBL = 150
HPWMledstripe = 150
MsgADC_A0 = 0
MsgADC_A1 = 0
MsgADC_A4 = 0
MsgADC_C3 = 0
MsgADC_C4 = 0
MsgSW = 0
HPWM 3, HPWMlcdBL, 1953
HPWM 5, HPWMledstripe, 1953
LCDOUT $FE, 1
LCDOUT $FE, $80, " ADC TEST with SW "
LCDOUT $FE, $C0, "A0:____ _ A4:____ _"
LCDOUT $FE, $94, "A1:____ _ C3:____ _"
LCDOUT $FE, $D4, "SW:____ _ C4:____ _"
@ INT_ENABLE RX_INT ; Enable USART Receive interrupts
Mainloop:
while RXoccurred = 0 ' Check for interrupt
wend
MsgCode = MsgData[0]
if MsgCode = 0 then
gosub ProcessADC_A0
else
if MsgCode = 1 then
gosub ProcessADC_A1
else
if MsgCode = 3 then
gosub ProcessSW3
else
if MsgCode = 4 then
gosub ProcessADC_A4
else
if MsgCode = 5 then
gosub ProcessADC_C3
else
if MsgCode = 6 then
gosub ProcessADC_C4
endif
endif
endif
endif
endif
endif
GOTO Mainloop
end