Code:
'Set for using PIC18F46K80
'Programmed using PicBasic Pro 3.0.7.4
'Environment MCSP 5.0.0.5
'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.
'----------------------------------------------------------------------------------------
'Additional I/O Definitions
error var PORTA.5 'ERROR output, ACTIVE HIGH
heart var PORTA.6 'Heartbeat to know we are online - ACTIVE HIGH
warn var PORTD.4 'WARNING output, ACTIVE HIGH
status1 var PORTC.4 'STATUS output, ACTIVE HIGH
NCTS Var PORTC.5 'Goes high to xmit on COMMAND RS485
SCTS VAR PORTD.5 'Goes high to xmit on STUB RS485
PB1 var PORTB.3 'Pushbutton1 (far left)
PB2 var PORTB.2 'Pushbutton2
PB3 var PORTB.1 'Pushbutton3
PB4 var PORTB.0 'Pushbutton4 (on far right)
addr_dig1 var PORTE.0 'LSB of address
addr_dig2 var PORTE.1 'Digit 2 of address
addr_dig3 var PORTE.2 'MSB of address
DQ Var PORTA.1 'One-wire data pin
'------------------------------------------------------------------------------------------
'Variable List
i var byte 'Loop counter var
j var byte 'Loop counter var
Node_rxbyte var byte 'NODE serial receive byte
Stub_rxbyte var byte 'STUB serial receive byte
temperature Var Word 'Temperature storage
count_remain Var Byte 'Count remaining
count_per_c Var Byte 'Count per degree C
In_Count VAR BYTE 'Where we are in the 8 byte packet
Buff VAR BYTE[4] 'Array for the data
CMD_PORT VAR Buff[0] '2nd byte (after sync byte ($54) contains the 4 bits for STATUS/ 4 bits for PORT
BOARD VAR Buff[1] 'Board number on STUB network
SUMCHK VAR Buff[2] 'Simple sumcheck to see if payload is good
SyncRcvd VAR BIT 'Flag set when we get a proper sync byte
PacketRcvd VAR BIT 'Flag set when we get a whole packet
address var word 'Address variable
bcd1 VAR BYTE 'lsb of BCD address
bcd10 var byte '10's of BCD address
bcd100 var byte 'MSB of BCD address
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 are going to start this Pig!
'#########################################################################################################################
init:
heart=0 'Turns off HEARTBEAT led
warn=0 'Turns off WARNING led
error=0 'Turns off ERROR led
status1=0 'Turns off STATUS1 led
heart=1 : warn=1 : error=1 : status1=1 'Turns ON leds
pause 20 'Hold here for a bit while things IPL......
gosub initlcd 'Initializes the lcd
pause 2000 'Display for a while
heart=0 : warn=0 : error=0 : status1=0 'Turns OFF leds
'#########################################################################################################################
'# We go around the rest of the subroutines
'#########################################################################################################################
Initialize:
heart=0 'Turns off HEARTBEAT led
warn=0 'Turns off WARNING led
error=0 'Turns off ERROR led
status1=0 'Turns off STATUS1 led
ncts=0 'NODE network 485 in receive mode
scts=0 'STUB network 485 in receive mode
temperature=0 'Zeros var
bcd1=0 : bcd10=0 : bcd100=0 'Zeros the address vars
gosub chirp 'Flashed ERROR before we start
goto startmain 'Jumps around subroutines
'#########################################################################################################################
'# Subroutines
'#########################################################################################################################
initlcd:lcdout $fe,1 'Inits the lcd
return
get_addr:
'Get the address and perform functions to get the digit data
'this is code for the use of rotary hex switches - 3 of them
addr_dig1=0 : addr_dig2=0 : addr_dig3=0 'Set all commons LOW
status1=1 'Turns ON the StATUS1 led
addr_dig1=1 'Set LSB HIGH in order to read
bcd1=PORTC & $0F 'Reads port and strips off high nibble, puts in bcd1
pause 5
addr_dig1=0 'Resets digit 1 common
pause 5
addr_dig2=1 'Sets digit 2 common
bcd10=PORTC & $0F 'Reads port and strips off high nibble, puts in bcd10
pause 5
addr_dig2=0 'Resets digit 2 common
pause 5
addr_dig3=1 'Sets digit 3 common
bcd100=PORTC & $0F 'Reads port and strips off high nibble, puts in bcd100
pause 5
addr_dig3=0 'Resets digit 3 common
address=(bcd100*100)+(bcd10*10)+bcd1 'Builds the address from the 3 digits
status1=0 'Turns OFF STATUS2 led
return
h2d: ' Convert Hex coded data -> decimal data
K = (K & $F )+((K>>4)*10)
Return
d2h: ' Convert Decimal -> Hex coded data
K = (K DIG 1) * $10 + (K DIG 0)
Return
chirp: for i=1 to 3
high error
pause 50
low error
pause 50
next i
return
get_temp: 'Gets temperature from DS1820, puts in degrees F
OWOut DQ, 1, [$CC, $44] 'Start temperature conversion
pause 1000
OWIn DQ, 4, [count_remain] 'Check for still busy converting
If count_remain = 0 Then
OWOut DQ, 1, [$CC, $BE] 'Read the temperature
OWIn DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE, Skip 4, count_remain, count_per_c]
endif
temperature = (temperature */ 461) + 3200
return
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
value=ADCval
gosub average
ADCavg=value
'Here we 'normalize' the ADC reading to real-world voltage
ADCavg=ADCavg/10 'Leaves us with 3 digits
ADCavg=ADCavg*155 'Our normalizing junk-yard constant
ADCavg=ADCavg/100 'Leaves us with 3 digits
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:
gosub initlcd 'Initializes the lcd
gosub get_addr 'Gets board address
gosub get_temp 'Gets temp from DS18S20 - not quite working
gosub volt 'Gets the +5 volt rail voltage
pause 200
lcdout $FE,1
lcdout $FE,line1," CLUSTER CONTROLLER " 'Display who we are
lcdout $FE,line2,"SMODE address= ",dec3 address," "'Display our address
lcdout $FE,line3,"5 volt= ", DEC ADCavg/100,".",DEC2 ADCavg//100 'Display +5 volt rail
lcdout $FE,line4,DEC (temperature / 100), ".", DEC2 temperature, " F " 'Display our temp
pause 2000 'Display for a while
goto startmain
Bookmarks