Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;*******************************************************************************************
- ;* PCB Etching Tank - Temperature Control v 0.E *
- ;*-----------------------------------------------------------------------------------------*
- ;* Jugurtha Hadjar - Raouf Moualdi - Iheb Renai *
- ;*-----------------------------------------------------------------------------------------*
- ;* Pr. Youcef Smara Dr. Samir Boukhenous *
- ;*-----------------------------------------------------------------------------------------*
- ;* Université des Sciences et de la Technologie Houari Boumédiène *
- ;*-----------------------------------------------------------------------------------------*
- ; PIC used: PIC 16F887 40 PIN, Dual in line. 10 bit ADC. Only 8 bits will be used.
- ; Sensor : LM 35 (as of this version) . 10mv/°C slope.
- ; TODO: Project Due for June, 26th 2012. Give to Pr Smara.
- ; TODO: Figure out OPTION_REG.
- ; TODO: Delete the goto START line if there's nothing between
- ; that line and the START label.
- ; TODO: Delete the goto Initialize_PIC if there's nothing below it.
- ; UPDATE 0.D --> 0.E : Changing from Left justified, to right justified.
- ; We'll be using the lower 8 bits (ADRESL).
- ; If the count is 255, then the temperature is 500°C and voltage = 5V.
- ; so 8 bits are enough.
- ; We'll use some subroutines for temperature checks, etc...
- ;***********************************************************************************
- ;* THE SETUP *
- ;***********************************************************************************
- LIST p=16F887, r=dec, f=inhx8m
- #include "p16F887.inc"
- __config _CPD_OFF & _LFOSC & _MCLRE_ON & _CP_OFF & _WDT_OFF & _INTOSC
- ;Watchdog Timer OFF
- ;Power Up Timer ON
- #define Relay_Pin PORTB,1
- #define Sensor_Pin PORTA,0
- cblock 0x20 ; General Purpose Registers start here in a PIC16F887.
- Delay_Counter_1, Delay_Counter_2, Temp_Sensor, Voltage_Sensor_ADC
- endc
- ;******************************************************************************************
- ;* OPTION_REG Description *
- ;*----------------------------------------------------------------------------------------*
- ;* Bit7:RBPU(active low) PORTB Pull-Up Enable Bit (1, Disabled) *
- ;* Bit6:INTEDG, Interrupt Edge Select Bit(0, Interrupt on falling edge B0/INT) *
- ;* Bit5:T0CS, TMR0 Clock Source Select Bit (0, Internal Instruction Cycle Clock) *
- ;* Bit4:T0SE, TMR0 Source Edge Select Bit(1, Increment on Hi-to-Lo transition on RA4) *
- ;* Bit3:PSA,PRESCALER Assignment Bit(0, Prescaler assigned to TMR0 module) *
- ;* Bit2-0:PRESCALER Select Bits (110, 1:128) *
- ;******************************************************************************************
- org 0x00 ;Reset Vector.
- goto Initialize_PIC
- Initialize_PIC
- clrf PORTA
- clrf PORTB ; This includes the Relay_Pin (PORTB, 1 - Heater) which is
- ; cleared (turned off) by default for security measures.
- clrf PORTC
- bcf STATUS, RP0
- movlw 0x96
- banksel OPTION_REG
- movwf OPTION_REG ; Configure OPTION_REG (81h in Bank1).
- goto START ; Here we go..
- START
- Initialize_ADC
- banksel ADCON1
- movlw b'1000000' ; Right justified. The ADC has a resolution of 10 bits.
- ; We'll read the higher 8 bits in ADRESL since the temperatures
- ; we are interested in won't make it to the 9th or 10th bit.
- ; VDD & VSS for VCFG1 & VCFG0
- movwf ADCON1
- banksel TRISA
- bsf TRISA, 0 ; Set RA0 (Pin2) to Input
- banksel ANSEL
- bsf ANSEL, 0 ; Set RA0 as Analog ..
- ; Now RA0 is Analog, and is Input.
- ; RA0 is ready to receive information
- ; from the sensor.
- banksel ADCON0
- movlw b'11000001' ; The ADCON0 Register:
- ; ADCS1 ADCS0 CHS2 CHS1 CHS0 GO_DONE - ADON
- ; ADCS1 ADCS0 : 11 Conversion Clock frequency Frc
- ; 4 us typical.
- ; CHS2 CHS1 CHS0 : 000 RA0
- ; GO_DONE : 0 . Setting it to 1 starts conversion.
- ; automatically cleared when conversion is done.
- ; ADON : 1 . The ADC is enabled.
- movwf ADCON0
- ADC_Get
- movlw d'100' ; A value which will be decreased to lose some time.
- movwf Delay_Counter_2
- call Delay ; Acquisition Time : See Datasheet "ADC time requirements".
- ; Might as well be the best example of Cargo Cult Programming from me.
- bsf ADCON0, GO ; Start Analog to Digital Conversion.
- btfsc ADCON0, GO ; Check if the conversion is finished.
- goto $ - 1
- banksel ADRESH
- movf ADRESH, w ; Get the ADRESH byte and put it in Voltage_Sensor_ADC
- movwf Voltage_Sensor_ADC ; The value is the digitized analog voltage from the sensor.
- ; In order to compare it with a temperature, we need to
- ; calculate to which temperature in Celsius a certain
- ; voltage from the LM35 corresponds. (10mv/°C).
- ; Need to figure out an "easy" way to do multiplication.
- ;------------------------------------------------------------------------
- ; Check_High_Threshold
- ;------------------------------------------------------------------------
- movlw d'86' ; That's our High Threshold.
- call Check_Temperature ; Go to the end of the code
- ; in "A Little Story About Conversion" to see
- ; where did this value come from.
- ; In a nutshell, that's the expected
- ; result a temperature of 42 °C would give
- ; after being converted by a 10 bits , 5 V Vref. ADC.
- btfss STATUS, C ; Is the Temperature from the Sensor
- ; greater than the High threshold (42°C) ?
- call Temp_Is_High ; If yes, i.e the temperature is HIGH, then
- ; it's time to turn off the heater.
- ; If not, i.e the Temperature from the sensor
- ; is less than the High threshold and it's more
- ; than the Low Threshold, then do nothing.
- ;----------------------------------------------------------------------------
- ; Check_Low_Threshold
- ;----------------------------------------------------------------------------
- movlw d'81' ; That's our Low Threshold
- call Check_Temperature ; In order to know if the temperature from
- ; the sensor is lesser or greater than our
- ; threshold, we need to perform a substraction
- ; the Carry flag in the STATUS register tells us
- ; something about the sign, thus is it greater or lesser?
- btfsc STATUS, C ; Is the result of the substraction in Check_Temperature positive?
- ; If yes, it means that the temperature from the sensor
- call Temp_Is_Low ; is less than our Low Threshold, hence we need to
- ; turn the Relay_Pin on. We call the Temp_Is_Low subroutine for that.
- Hysteresis
- goto ADC_Get ; Here land all cases that need to keep the state of the heater.
- ; Basically, all cases have been checked (> High Threshold ? < Low Threshold ? Between the two?)
- ; And the only thing to do now, is to perform another conversion and
- ; start a new cycle.
- ; goto START TODO: Remove that line at the end if it's not necessary.
- ;----------------------------------------------------------------------------------
- ; SUBROUTINES
- ;----------------------------------------------------------------------------------
- ;----------------------------------------------------------
- Check_Temperature
- subwf Voltage_Sensor_ADC, w
- return
- ;----------------------------------------------------------
- Temp_Is_Low
- btfss Relay_Pin ; Is the relay ON ? If it is, then return. (let it that way)
- bsf Relay_Pin ; If it's OFF, then turn it ON and return.
- return
- ;-----------------------------------------------------------
- Temp_Is_High
- btfsc Relay_Pin ; Is the Relay OFF? If it is, then return. (let it off).
- bcf Relay_Pin ; If it's ON, then turn it OFF and return.
- return
- ;-----------------------------------------------------------
- Delay
- decfsz Delay_Counter_2, f ; Teenage wasteland. Lose some time.
- goto Delay ; Emo stuff...
- return
- ;-----------------------------------------------------------
- ; A Little Story About Conversion
- ; Let's talk about the conversion a bit:
- ; Let's say we use Vref = 5V of the supply.
- ; The output voltage of the LM35 sensor is
- ; Voltage_Sensor = Temperature * 10 / 1000 V
- ; Voltage_Sensor = Temperature / 100
- ; The result of the conversion of Voltage_Sensor
- ; is called Voltage_Sensor_ADC.
- ; 5 volts input correspond to 255 (8 bits to 1)
- ; Voltage_Sensor corresponds to Voltage_Sensor_ADC (or Count)
- ; Voltage_Sensor_ADC = Voltage_Sensor * 255 / 5
- Voltage_Sensor_ADC = Voltage_Sensor * 51
- ; Knowing that Voltage_Sensor = Temperature / 100
- ; We get:
- ; Voltage_Sensor_ADC = (Temperature / 100) * 51
- ; Voltage_Sensor_ADC = Temperature * (51/100)
- ; This means that if the Temperature is 100 °C
- ; The result of the conversion will be:
- ; 100 * 51 / 100 = 51.
- ; This relation will help translate the "Count" or
- ; Voltage_Sensor_ADC to the corresponding temperature.
- ; Temperature = Voltage_Sensor_ADC * (100/51)
- ; Which means that when we read ADRESL
- ; Let's say it has a value or 30.
- ; The Temperature which caused this number is
- ; Temperature = 30 * (100/51)
- ; Which is roughly 58 °C.
- ; Now I get the idea that I can calculate the Count for
- ; my two thresholds, and instead of having the PIC compute
- ; the corresponding temperature for each acquisition..
- ; I'll have it compare each ADRESL with the count corresponding
- ; to each threshold.
- ; Example: Low_Threshold = 40 °C.
- ; Voltage_Sensor_ADC_Low = 40 * 51 / 100 = 20.4 (we'll worry floating point later).
- ; Voltage_Sensor_ADC_High = 42 * 51 / 100 = 21.42.
- ; So I'll just match ADRESL with 20 and 21.
- ; However ... 20 and 21 are kind of too close.
- ; We have two values 2 °C apart (that's huge)
- ; Yet, the corresponding counts are very close.
- ; That's not good
- ; I understand why Ericgibbs and Mr RB insisted on using the whole 10 bits.
- ; Maybe use the whole 10 bits like he suggested.
- ; 5V ---------------> 1023
- ; Voltage_Sensor ---> Voltage_Sensor_ADC
- ; Voltage_Sensor_ADC = Voltage_Sensor * 1023 / 5
- ; Voltage_Sensor_ADC = (Temperature / 100) * 1023 : 5
- ; Voltage_Sensor_ADC = Temperature * 1023 / 500
- ; For a temperature of 40 °C:
- ; Voltage_Sensor_ADC_Low = 40 * 1023 / 500 = 81.84
- ; Voltage_Sensor_ADC_High = 42 * 1023 / 500 = 85.932
- ; They are more spaced, so it's better.
- ; I'll use the whole 10 bits.
- ; Then match ADRESL with 86 and 81 for the thresholds.
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement