Code:
'Set for using PIC18F46K80
'Programmed using PicBasic Pro 3.0.7.4
'Environment MCSP 5.0.0.5
'Program using the USB MELABS programmer - not yet
'Define configuration
#CONFIG
CONFIG RETEN = ON ;Ultra-low regulator ON
CONFIG FOSC = EC3 ;External HS oscillator, port function on RA6
CONFIG INTOSCSEL = LOW ;LF-INTOSC in Low-power mode during Sleep
CONFIG SOSCSEL = DIG ;Digital (SCLKI) mode
;FCMEM doesn't seem to work here.....
; CONFIG FCMEM = OFF ;Fail Safe CLock Monitor is OFF
CONFIG IESO = OFF ;Internal/External oscillator switchover is OFF
CONFIG PWRTEN = ON ;Power Up timer is ON
CONFIG BOREN = OFF ;Brown Out Reset is OFF - for now
CONFIG BORV = 0 ;Brown Out level is 4.6v
CONFIG WDTEN = OFF ;Watchdog is OFF - for now
CONFIG MCLRE = ON ;MCLR pin is ENABLED
CONFIG STVREN = ON ;Stack FULL/UNDERFLOW reset is ENABLED
CONFIG BBSIZ = BB1K ;Boot Block size - 1K?
CONFIG XINST = OFF ;Extended Instructgion set is DISABLED
#ENDCONFIG
'---------------------------------------------------------------------------------------
'Define the oscillator and setup the INCLUDE files
DEFINE OSC 64 '64 MHz oscillator, external
INCLUDE "DT_INTS-18.bas" 'Base Interrupt System
INCLUDE "ReEnterPBP-18.bas" 'Include if using PBP interrupts
'---------------------------------------------------------------------------------------
'OKAY, Lets set up the registers.....
OSCCON= %00001000 'Device enters SLEEP mode when SLEEP is executed
OSCCON2= %00000000 'System clock comes from other osc than internal
REFOCON.7=0 'Refrence oscillator is DISABLED
WPUB= %00000000 'PORTB pullups DISABLED
PADCFG1= %00000000 'ALL pull up resistors DISABLED on ports D,E
ANCON0= %00000001 'Selects AN1-AN7 as DIGITAL, AN0 as ANALOG
ANCON1= %00000000 'Selects remaining analog/digital inputs as DIGITAL
ADCON0= %00000000 'Turns OFF ADC - REMEMBER TO TURN IT BACK ON AFTER DEBUG-, selects AD0 as input
ADCON1= %10110000 'Vref is INTERNAL 4.1v and AVss
ADCON2= %10010110 'RIGHT justified, 4 TAD A2D aq time select, Fosc/64
T0CON.7=0 'DISABLES TMR0
CM1CON= %00000000 'Turns OFF CM1 comparator
CM2CON= %00000000 'Turns OFF CM2 comparator
CVRCON.7=0 'Comparator voltage ref is powered DOWN
HLVDCON.4=0 'High Low Voltage Detect is DISABLED
CCP1CON=%00000000 'Turns OFF capture, compare, pwm
CCP2CON=%00000000 'Turns OFF capture, compare, pwm
CCP3CON=%00000000 'Turns OFF capture, compare, pwm
CCP4CON=%00000000 'Turns OFF capture, compare, pwm
CCP5CON=%00000000 'Turns OFF capture, compare, pwm
CANCON=%00100000 'CAN disabled
CTMUCONH.7=0 'CTMU disabled
INTCON= %00000000 'INT0 and POIRTB change external interrupt is DISABLED
INTCON2= %01111100 'PORTB pullups enabled by TRIS, int are RISING edge, TMR0 hi and rest low priority
INTCON3.3=0 'Disables INT1 external interupt
IOCB= %00000000 'PORTB interrupt on change all bits DISABLED
SLRCON=%00000000 'Slew rate for all ports is STANDARD
SSPCON1.5=0 'MSSP port is DISABLED
ODCON=%00000000 'Open Drain capability is DISABLED
PSTR1CON= %00000000
' MDCON=%00000000 'Modulation Control is DISABLED
'---------------------------------------------------------------------------------------
'Direction registers
TRISA = %10001011 'Set PORTA for bit7 is clk in, 2 led out, 1 temp in, 1 A/D in, ext Vref
TRISB = %11001111 'PORTB is ICSP, 2 pins for LCD, low nibble for 4 button inputs
TRISC = %10001111 'Set RC7 (RX), rest are outputs, low 4 bits used as inputs for addressing
TRISD = %10000000 'Set PORTD for serial, 1 LED, 4 LCD data
TRISE = %00001000 'Set PORTE for MCLR, low 3 bits for addressing - high order not used
'----------------------------------------------------------------------------------------
'Constants here
sync con $54
Line1 CON 128 'Point to beginning of line 1 ($2)
Line2 CON 192 'Point to beginning of line 2 ($C0)
Line3 con 148 'Point to beginning of line 3 ($94)
line4 con 212 'Point to beginning of line 4 ($D4)
HystLevel CON 7 ' 7 = .7 of the Least Significant Digit
' Valid HystLevel is from 6 to 13
AvgCount CON 16 ' = Number of samples to average. For best response
' times, keep AvgCount as small as you can
FAspread CON 50 ' = Fast Average threshold +/-
' FAspread should be larger than the worst possible
' noise in the A/D conversion.
'------------------------------------------------------------------------------------------
'Variable List
ADCval var word 'Result of 12 bit ADC
ADCavg var word 'Running ADC average
k var byte
AVGchanged VAR BIT ' 1 indicates that the Average Value has changed
' you have to clear this bit after using it
ADavg VAR WORD ' Stores the current Average
ADhyst VAR WORD ' Stores the current Value for Hysterisis
Value VAR WORD ' Input / Output variable to be averaged
spread CON FAspread * 10 ' adjust spread *10 for Hyst.
'---------------------------------------------------------------------------------------------
'#########################################################################################################################
'# We go around the rest of the subroutines
'#########################################################################################################################
Initialize:
goto startmain 'Jumps around subroutines
'#########################################################################################################################
'# Subroutines
'#########################################################################################################################
Volt:
ADCON0=%00000011 'Select channel AN0, and start sampling then after 4 TADs - convert
while ADCON0.1 = 1 :wend 'Wait for ADC DONE
ADCval.highbyte = ADRESH 'Move HIGH byte of result to adcVAL
ADCval.lowbyte = ADRESL 'Move LOW byte of result to adcVAL
' adcval=(adcval*1.567) '1.567 will convert voltage divider into real voltage
' Just don't know HOW to do it.........
'I have taken the ((ADCavg/1000)*1547)/1000 which works on the calculator, but here without REAL numbers????
'THEN add a decimal so ADCavg ends up being 5.06 given ADCavg of 3272.....
value=ADCval
gosub average
ADCavg=value
return
Average:'Thanks Darrel...via PBP forum.
Value = Value * 10 ' Scale value up for hysterisis
IF Value = ADavg Then NoChange ' if they're the same, nothing to do
IF ABS (Value - ADavg) > spread OR Value < AvgCount Then FastAvg
IF ABS (Value - ADavg) < AvgCount Then RealClose
ADavg = ADavg - (ADavg/AvgCount) ' Subtract 1 samples worth
ADavg = ADavg + (Value/AvgCount) ' Add in the new sample portion
GoTo AVGok
FastAvg: ' Catch up to the changing value
ADavg = Value ' Set Average to the current value
GoTo AVGok
RealClose: ' Reduce the sample size when
ADavg = ADavg - (ADavg/(AvgCount/4)) ' the average and the sample are
ADavg = ADavg + (Value/(AvgCount/4)) ' "Real Close"
AVGok:
IF ABS (ADavg - ADhyst) > HystLevel then ' If it changed > HystLevel +/-
ADhyst = ((ADavg + 5) / 10) * 10 ' Round ADavg to get new Value
AVGchanged = 1 ' Indicate that Average changed
ENDIF
NoChange:
Value = ADhyst / 10 ' Scale the result down
Return
'#########################################################################################################################
'# Startmain - where the MAGIC starts!
'#########################################################################################################################
startmain:
lcdout $FE,1
lcdout $FE,line3," @ startmain " 'Display code version
lcdout $FE,line4,"SMODE address= ",dec3 address," "'Display our ADDRESS
pause 2000 'Display for a while
PB:
'Get PBs to work and print to LCD
gosub volt
if PB1=1 then lcdout $FE,line1,"5 volt= ", dec ADCavg," ", dec ADCval
' if PB1=1 then lcdout $FE,line1,"5 volt= ", dec ADCavg," ", [#(ADCval/10,".",#(ADCval//10)]
lcdout $FE,line2," "
lcdout $FE,line3,DEC (temperature / 100), ".", DEC2 temperature, " F "
' lcdout $FE,line4," " 'Display done with init
pause 100 'Display for a while
goto PB
Bookmarks