Advertisement
Jugurtha_Hadjar

PCB Etching Tank - Temperature Control - PIC 16F887 & LM35

Jun 24th, 2012
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MPASM 11.32 KB | None | 0 0
  1.     ;*******************************************************************************************
  2.     ;*                   PCB Etching Tank - Temperature Control     v 0.E                      *
  3.     ;*-----------------------------------------------------------------------------------------*
  4.     ;*               Jugurtha Hadjar - Raouf Moualdi - Iheb Renai                              *
  5.     ;*-----------------------------------------------------------------------------------------*
  6.     ;*          Pr. Youcef Smara                       Dr. Samir Boukhenous                    *
  7.     ;*-----------------------------------------------------------------------------------------*
  8.     ;*          Université des Sciences et de la Technologie Houari Boumédiène                 *
  9.     ;*-----------------------------------------------------------------------------------------*
  10.  
  11.  
  12.  
  13.     ; PIC used: PIC 16F887 40 PIN, Dual in line. 10 bit ADC. Only 8 bits will be used.
  14.     ; Sensor  : LM 35 (as of this version) . 10mv/°C slope.
  15.  
  16.  
  17.  
  18.     ; TODO: Project Due for June, 26th 2012. Give to Pr Smara.
  19.     ; TODO: Figure out OPTION_REG.
  20.     ; TODO: Delete the goto START line if there's nothing between
  21.     ;       that line and the START label.     
  22.     ; TODO: Delete the goto Initialize_PIC if there's nothing below it.
  23.  
  24.  
  25.     ; UPDATE 0.D --> 0.E    :   Changing from Left justified, to right justified.
  26.     ;                           We'll be using the lower 8 bits (ADRESL).
  27.  
  28.     ; If the count is 255, then the temperature is 500°C and voltage = 5V.
  29.     ; so 8 bits are enough.                    
  30.  
  31.  
  32.     ; We'll use some subroutines for temperature checks, etc...
  33.  
  34.     ;***********************************************************************************
  35.     ;*                                   THE SETUP                                     *
  36.     ;***********************************************************************************
  37.  
  38.         LIST p=16F887, r=dec, f=inhx8m
  39.  
  40.     #include "p16F887.inc"                                           
  41.                                                                                              
  42.  
  43.      
  44.         __config _CPD_OFF  & _LFOSC & _MCLRE_ON  & _CP_OFF & _WDT_OFF & _INTOSC
  45.  
  46.        
  47.                                                               ;Watchdog Timer  OFF
  48.                                                               ;Power Up Timer  ON
  49.                                                              
  50.     #define Relay_Pin  PORTB,1
  51.     #define Sensor_Pin PORTA,0
  52.    
  53.  
  54.         cblock 0x20      ; General Purpose Registers start here in a PIC16F887.
  55.    
  56.             Delay_Counter_1, Delay_Counter_2, Temp_Sensor, Voltage_Sensor_ADC
  57.  
  58.  
  59.         endc
  60.    
  61.  
  62.  
  63.  
  64.      
  65.     ;******************************************************************************************
  66.     ;*                             OPTION_REG Description                                     *
  67.     ;*----------------------------------------------------------------------------------------*
  68.     ;* Bit7:RBPU(active low) PORTB Pull-Up Enable Bit (1, Disabled)                           *
  69.     ;* Bit6:INTEDG, Interrupt Edge Select Bit(0, Interrupt on falling edge B0/INT)            *
  70.     ;* Bit5:T0CS, TMR0 Clock Source Select Bit (0, Internal Instruction Cycle Clock)          *
  71.     ;* Bit4:T0SE, TMR0 Source Edge Select Bit(1, Increment on Hi-to-Lo transition on RA4)     *
  72.     ;* Bit3:PSA,PRESCALER Assignment Bit(0, Prescaler assigned to TMR0 module)                *
  73.     ;* Bit2-0:PRESCALER Select Bits (110, 1:128)                                              *
  74.     ;******************************************************************************************
  75.  
  76.  
  77.        
  78.  
  79.    
  80.         org 0x00              ;Reset Vector.
  81.    
  82.            
  83.         goto Initialize_PIC
  84.  
  85.            
  86.  
  87. Initialize_PIC
  88.        
  89.         clrf PORTA
  90.         clrf PORTB  ; This includes the Relay_Pin (PORTB, 1 - Heater) which is
  91.                     ; cleared (turned off) by default for security measures.
  92.         clrf PORTC
  93.  
  94.  
  95.         bcf STATUS, RP0
  96.  
  97.         movlw 0x96              
  98.         banksel OPTION_REG
  99.         movwf OPTION_REG      ; Configure OPTION_REG (81h in Bank1).
  100.  
  101.  
  102.  
  103.            
  104.        
  105.           goto START        ; Here we go..
  106.  
  107.  
  108. START    
  109.  
  110.  
  111. Initialize_ADC
  112.    
  113.         banksel ADCON1
  114.         movlw   b'1000000'  ; Right justified. The ADC has a resolution of 10 bits.
  115.                             ; We'll read the higher 8 bits in ADRESL since the temperatures
  116.                             ; we are interested in won't make it to the 9th or 10th bit.
  117.                             ; VDD & VSS for VCFG1 & VCFG0
  118.  
  119.         movwf   ADCON1
  120.         banksel TRISA
  121.         bsf     TRISA, 0    ; Set RA0 (Pin2) to Input
  122.         banksel ANSEL
  123.         bsf     ANSEL, 0    ; Set RA0 as Analog ..
  124.                             ; Now RA0 is Analog, and is Input.
  125.                             ; RA0 is ready to receive information
  126.                             ; from the sensor.
  127.  
  128.    
  129.         banksel ADCON0
  130.         movlw   b'11000001'     ; The ADCON0 Register:
  131.                                 ; ADCS1 ADCS0 CHS2 CHS1 CHS0 GO_DONE - ADON
  132.  
  133.                                 ; ADCS1 ADCS0    : 11 Conversion Clock frequency Frc
  134.                                 ;                  4 us typical.
  135.                                 ; CHS2 CHS1 CHS0 : 000   RA0
  136.                                 ; GO_DONE        : 0 . Setting it to 1 starts conversion.
  137.                                 ;                  automatically cleared when conversion is done.
  138.                                 ; ADON           : 1 . The ADC is enabled.
  139.    
  140.  
  141.         movwf   ADCON0
  142.    
  143.  
  144. ADC_Get
  145.    
  146.         movlw   d'100'          ; A value which will be decreased to lose some time.
  147.         movwf   Delay_Counter_2
  148.  
  149.         call    Delay       ; Acquisition Time : See Datasheet "ADC time requirements".
  150.                             ; Might as well be the best example of Cargo Cult Programming from me.
  151.    
  152.  
  153.         bsf     ADCON0, GO  ; Start Analog to Digital Conversion.
  154.         btfsc   ADCON0, GO  ; Check if the conversion is finished.
  155.         goto    $ - 1
  156.    
  157.         banksel ADRESH
  158.         movf    ADRESH, w             ; Get the ADRESH byte and put it in Voltage_Sensor_ADC
  159.         movwf   Voltage_Sensor_ADC    ; The value is the digitized analog voltage from the sensor.
  160.                                       ; In order to compare it with a temperature, we need to
  161.                                       ; calculate to which temperature in Celsius a certain    
  162.                                       ; voltage from the LM35 corresponds. (10mv/°C).
  163.                        
  164.                                       ; Need to figure out an "easy" way to do multiplication.
  165.  
  166.    
  167.     ;------------------------------------------------------------------------
  168.     ;                              Check_High_Threshold
  169.     ;------------------------------------------------------------------------
  170.  
  171.         movlw   d'86'               ; That's our High Threshold.
  172.         call    Check_Temperature   ; Go to the end of the code
  173.                                     ; in "A Little Story About Conversion" to see
  174.                                     ; where did this value come from.
  175.                                     ; In a nutshell, that's the expected   
  176.                                     ; result a temperature of 42 °C would give
  177.                                     ; after being converted by a 10 bits , 5 V Vref. ADC.
  178.  
  179.  
  180.  
  181.  
  182.  
  183.         btfss   STATUS, C       ; Is the Temperature from the Sensor
  184.                                 ; greater than the High threshold (42°C) ?
  185.  
  186.         call    Temp_Is_High    ; If yes, i.e the temperature is HIGH, then
  187.                                 ; it's time to turn off the heater.
  188.                                 ; If not, i.e the Temperature from the sensor
  189.                                 ; is less than the High threshold and it's more
  190.                                 ; than the Low Threshold, then do nothing.
  191.    
  192.  
  193.  
  194.    
  195.     ;----------------------------------------------------------------------------
  196.     ;                               Check_Low_Threshold
  197.     ;----------------------------------------------------------------------------
  198.  
  199.         movlw   d'81'             ; That's our Low Threshold
  200.  
  201.         call    Check_Temperature ; In order to know if the temperature from
  202.                                   ; the sensor is lesser or greater than our
  203.                                   ; threshold, we need to perform a substraction
  204.                                   ; the Carry flag in the STATUS register tells us
  205.                                   ; something about the sign, thus is it greater or lesser?
  206.    
  207.         btfsc   STATUS, C         ; Is the result of the substraction in Check_Temperature positive?
  208.                                   ; If yes, it means that the temperature from the sensor
  209.         call    Temp_Is_Low       ; is less than our Low Threshold, hence we need to
  210.                                   ; turn the Relay_Pin on. We call the Temp_Is_Low subroutine for that.
  211.      
  212.  
  213.  
  214. Hysteresis
  215.  
  216.         goto    ADC_Get         ; Here land all cases that need to keep the state of the heater.
  217.                                 ; Basically, all cases have been checked (> High Threshold ? < Low Threshold ? Between the two?)
  218.                                 ; And the only thing to do now, is to perform another conversion and
  219.                                 ; start a new cycle.
  220.  
  221.  
  222.     ;      goto START           TODO: Remove that line at the end if it's not necessary.
  223.  
  224.  
  225.  
  226.  
  227.  
  228.     ;----------------------------------------------------------------------------------
  229.     ;                                   SUBROUTINES
  230.     ;----------------------------------------------------------------------------------
  231.  
  232.  
  233.  
  234. ;----------------------------------------------------------
  235.  
  236. Check_Temperature
  237.  
  238.         subwf   Voltage_Sensor_ADC, w
  239.    
  240.         return
  241. ;----------------------------------------------------------
  242.  
  243.  
  244. Temp_Is_Low
  245.  
  246.         btfss   Relay_Pin   ; Is the relay ON ? If it is, then return. (let it that way)
  247.         bsf     Relay_Pin   ; If it's OFF, then turn it ON and return.
  248.                        
  249.         return
  250. ;-----------------------------------------------------------
  251.  
  252.  
  253. Temp_Is_High
  254.  
  255.         btfsc   Relay_Pin   ; Is the Relay OFF? If it is, then return. (let it off).
  256.         bcf     Relay_Pin   ; If it's ON, then turn it OFF and return.
  257.  
  258.         return
  259. ;-----------------------------------------------------------
  260.  
  261.  
  262. Delay
  263.  
  264.         decfsz  Delay_Counter_2, f  ; Teenage wasteland. Lose some time.
  265.         goto    Delay               ; Emo stuff...
  266.  
  267.         return
  268. ;-----------------------------------------------------------
  269.  
  270.  
  271. ;   A Little Story About Conversion
  272.  
  273.  
  274. ;   Let's talk about the conversion a bit:
  275. ;   Let's say we use Vref = 5V of the supply.
  276. ;   The output voltage of the LM35 sensor is
  277. ;   Voltage_Sensor = Temperature * 10 / 1000 V
  278. ;   Voltage_Sensor = Temperature / 100
  279.  
  280. ;   The result of the conversion of Voltage_Sensor
  281. ;   is called Voltage_Sensor_ADC.
  282.  
  283. ;   5 volts input correspond to 255 (8 bits to 1)
  284. ;   Voltage_Sensor corresponds to Voltage_Sensor_ADC (or Count)
  285.  
  286. ;   Voltage_Sensor_ADC = Voltage_Sensor * 255 / 5
  287.     Voltage_Sensor_ADC = Voltage_Sensor * 51
  288.  
  289. ;   Knowing that Voltage_Sensor = Temperature / 100
  290.  
  291. ;   We get:
  292.  
  293. ;   Voltage_Sensor_ADC = (Temperature / 100) * 51
  294.  
  295. ;   Voltage_Sensor_ADC = Temperature * (51/100)
  296.  
  297.  
  298. ;   This means that if the Temperature is 100 °C
  299. ;   The result of the conversion will be:
  300. ;   100 * 51 / 100 = 51.
  301.  
  302. ;   This relation will help translate the "Count" or
  303. ;   Voltage_Sensor_ADC to the corresponding temperature.
  304.  
  305. ;   Temperature = Voltage_Sensor_ADC * (100/51)
  306.  
  307. ;   Which means that when we read ADRESL
  308. ;   Let's say it has a value or 30.
  309. ;   The Temperature which caused this number is
  310. ;   Temperature = 30 * (100/51)
  311. ;   Which is roughly 58 °C.
  312.  
  313. ;   Now I get the idea that I can calculate the Count for
  314. ;   my two thresholds, and instead of having the PIC compute
  315. ;   the corresponding temperature for each acquisition..
  316. ;   I'll have it compare each ADRESL with the count corresponding
  317. ;   to each threshold.
  318.  
  319. ;   Example: Low_Threshold = 40 °C.
  320. ;   Voltage_Sensor_ADC_Low  = 40 * 51 / 100 = 20.4 (we'll worry floating point later).
  321. ;   Voltage_Sensor_ADC_High = 42 * 51 / 100 = 21.42.
  322.  
  323. ;   So I'll just match ADRESL with 20 and 21.
  324.  
  325. ;   However ... 20 and 21 are kind of too close.
  326. ;   We have two values 2 °C apart (that's huge)
  327. ;   Yet, the corresponding counts are very close.
  328. ;   That's not good
  329. ;   I understand why Ericgibbs and Mr RB insisted on using the whole 10 bits.
  330.  
  331.  
  332. ;   Maybe use the whole 10 bits like he suggested.
  333.  
  334. ;   5V ---------------> 1023
  335. ;   Voltage_Sensor --->  Voltage_Sensor_ADC
  336.  
  337. ;   Voltage_Sensor_ADC = Voltage_Sensor * 1023 / 5
  338. ;   Voltage_Sensor_ADC = (Temperature / 100) * 1023 : 5
  339.  
  340. ;   Voltage_Sensor_ADC = Temperature * 1023 / 500
  341.  
  342. ;   For a temperature of 40 °C:
  343. ;   Voltage_Sensor_ADC_Low  = 40 * 1023 / 500 = 81.84
  344. ;   Voltage_Sensor_ADC_High = 42 * 1023 / 500 = 85.932
  345.  
  346. ;   They are more spaced, so it's better.
  347. ;   I'll use the whole 10 bits.
  348. ;   Then match ADRESL with 86 and 81 for the thresholds.
  349.  
  350.         end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement