;**********************************************************************
; *
;**********************************************************************
; Filename: oven.asm *
; Date: *
; File Version: *
; *
; Author: *
; Company: *
; *
;**********************************************************************
; Files Required: P16F677.INC *
; *
;**********************************************************************
; PIC 16F677 pinout: *
; |--\/--| *
; Vdd -|1 20|- Vss *
; RA5/T1CKI/OSC1/CLKIN -|2 19|- RA0/AN0/C1IN+/ICSPDAT/ULPWU *
; RA4/AN3/T1G/OSC2/CLKOUT -|3 18|- RA1/AN1/C12IN0-/VREF/ICSPCLK *
; RA3/MCLR/VPP -|4 17|- RA2/AN2/T0CKI/INT/C1OUT *
; RC5 -|5 16|- RC0/AN4/C2IN+ *
; RC4/C2OUT -|6 15|- RC1/AN5/C12IN1- *
; RC3/AN7C12IN3 -|7 14|- RC2/AN6/C12IN2- *
; RC6/AN8/SS -|8 13|- RB4/AN10/SDI/SDA *
; RC7/AN9/SDO -|9 12|- RB5/AN11 *
; RB7 -|10 11|- RB6/SCK/SCL *
; -------- *
; *
;**********************************************************************
;/****************************************************************************
;* DESCRIPTION: System definitions.
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
ERRORLEVEL -302 ;remove message about using proper bank
LIST P=16F677
INCLUDE <P16F677.INC>
__CONFIG _BOR_OFF & _FCMEN_OFF & _IESO_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTOSCIO
;/****************************************************************************
;* DESCRIPTION: Program variables and constant definitions.
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
TEMPER EQU 0x20 ; Store temperature
TEMP EQU 0x21 ; General use variable
W_TEMP EQU 0x22 ; Temporary W register
STATUS_TEMP EQU 0x23 ; Temporary STATUS register
UNITS EQU 0x24 ; UNITS
TENS EQU 0x25 ; TENS
HUNDREDS EQU 0x26 ; HUNDREDS
AUX EQU 0x27 ; GENERAL AUX. REGISTER
TEMPO0 EQU 0x28
TEMPO1 EQU 0x29
T1_CONTA EQU 0x2A ; Aux. Timer1 counter
TMR_1MS EQU 0x2B ; Counter for 1 ms period
TMR_100MS EQU 0x2C ; Counter for 100 ms period
; Leds
#DEFINE LED_CMN PORTC,2 ; Leds Anodes
#DEFINE LED_UP PORTA,4 ; Led UP
#DEFINE LED_TIMER PORTB,6 ; Led TIMER
#DEFINE LED_TEMP PORTB,5 ; Led TEMP
#DEFINE LED_DWN PORTA,2 ; Led DWN
#DEFINE LED_LIGHT PORTB,4 ; Led LIGHT
#DEFINE LED_TOASTER PORTA,5 ; Led TOASTER
#DEFINE LED_ONOFF PORTC,6 ; Led ONOFF
; Displays
#DEFINE DISP1 PORTC,3 ; Anode display DIS0
#DEFINE DISP2 PORTC,4 ; Anode display DIS1
#DEFINE DISP3 PORTC,5 ; Anode display DIS2
;/****************************************************************************
;* DESCRIPTION: Got Start of program.
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************
ORG 0x0000
GOTO START
;*****************************************************************************
ORG 0x0004
MOVWF W_TEMP ; save W content to W_TEMP
SWAPF STATUS,W ; put STATUS in W...
MOVWF STATUS_TEMP ; ... Then save it in STATUS_TEMP
BCF PIR1,TMR1IF ; Clear Timer1 Interrupt flag
MOVLW 0x18 ;
MOVWF TMR1L ;
MOVLW 0xFC ;
MOVWF TMR1H ; Init TIMER1 with decimal 64536 (interrupt every 1ms)
INCF TMR_1MS,F ; Increment TR_1MS (1 ms counter)
MOVLW D'100'
XORWF TMR_1MS,W ; Is TMR_1MS = 100?
BTFSC STATUS,Z ; No, skip if TMR_1MS < 100
GOTO INC100MS ; Yes, zero TMR_1MS and inc TMR_100MS
GOTO END_INT ; No, exit interrupt
INC100MS
MOVLW D'0' ;
MOVWF TMR_1MS ; Zero TMR_1MS
INCF TMR_100MS,F ; Increment TMR_100MS (100 ms counter)
MOVLW D'5' ; 500 ms?
XORWF TMR_100MS,W ; Is TMR_100MS = 5 (500ms)?
BTFSC STATUS,Z ; No, skip if TMR_100MS < 5
GOTO INCCONTA ; Yes, zero TMR_100MS and inc 0,5 seconds counter
GOTO END_INT ; No, Exit interrupt
INCCONTA:
MOVLW D'0' ;
MOVWF TMR_100MS ; Zero 100 ms counter (reached 500ms)
BSF STATUS,RP0 ; Bank 1
BCF STATUS,RP1 ;
BCF LED_ONOFF ; LED_ONOFF output
BCF STATUS,RP0 ; Bank 0
BCF STATUS,RP1 ;
MOVLW D'1' ; Verify if ...
XORWF T1_CONTA,W ; passed 1/2 second ...
BTFSC STATUS,Z ;
GOTO LEDON ; Led ONOFF is ON? Goto LEDON
LEDOFF:
BCF LED_ONOFF ; Turn OFF LEDON_OFF
GOTO LEDOUT ; ok, done...
LEDON:
BSF LED_ONOFF ; Turn ON LED_ONOFF
LEDOUT:
DECFSZ T1_CONTA,F ; Decrement the Counter rRegister
GOTO END_INT ; If diferent of zero, exit interrupt
MOVLW 2 ;
MOVWF T1_CONTA ; Restart Counter Register with 2
END_INT:
SWAPF STATUS_TEMP,W ; Restaure STATUS content...
MOVWF STATUS ; ... from STATUS_TEMP
SWAPF W_TEMP,F ; Restaure W content...
SWAPF W_TEMP,W ; ... from W_TEMP.
RETFIE ; Return from interrupt
;/****************************************************************************
;* DESCRIPTION: Decodes value in W register to display segments for PORTA.
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
DECOD_DISPLAY_A:
MOVWF TEMP ; Put number in displacement variable
MOVLW LOW TABLE_A ; cop to W the 8 LSB bits of the TABLE address
ADDWF TEMP,F ; add the value to the displacement variable
MOVLW HIGH TABLE_A ; copy to W the upper 5 bits of the TABLE ddress
BTFSC STATUS,C ; Test to see if the sum activates the carry bit
ADDLW 0x01 ; if carry, sum 1 to W
MOVWF PCLATH ; sets PCLATH using the TABLE address
MOVF TEMP,W ; copy the displacement value to W
MOVWF PCL ; copy W to PCL
TABLE_A:
; A
; _______
; | |
; F | | B
; | G |
; -------
; | |
; E | | C
; |_______|
; D
; |7|6|5|4|3|2|1|0| - Bits PORTA
; |-|-|B|E|-|A|-|-|
RETLW B'00000000' ; |-|-|B|E|-|A|-|-| - 0
RETLW B'00010100' ; |-|-|B|X|-|X|-|-| - 1
RETLW B'00000000' ; |-|-|B|E|-|A|-|-| - 2
RETLW B'00010000' ; |-|-|B|X|-|A|-|-| - 3
RETLW B'00010100' ; |-|-|B|X|-|X|-|-| - 4
RETLW B'00110000' ; |-|-|X|X|-|A|-|-| - 5
RETLW B'00100000' ; |-|-|X|E|-|A|-|-| - 6
RETLW B'00010000' ; |-|-|B|X|-|A|-|-| - 7
RETLW B'00000000' ; |-|-|B|E|-|A|-|-| - 8
RETLW B'00010000' ; |-|-|B|X|-|A|-|-| - 9
;/****************************************************************************
;* DESCRIPTION: Decodes value in W register to display segments, for PORTB.
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
DECOD_DISPLAY_B:
MOVWF TEMP ; Put number in displacement variable
MOVLW LOW TABLE_B ; cop to W the 8 LSB bits of the TABLE address
ADDWF TEMP,F ; add the value to the displacement variable
MOVLW HIGH TABLE_B ; copy to W the upper 5 bits of the TABLE ddress
BTFSC STATUS,C ; Test to see if the sum activates the carry bit
ADDLW 0x01 ; if carry, sum 1 to W
MOVWF PCLATH ; sets PCLATH using the TABLE address
MOVF TEMP,W ; copy the displacement value to W
MOVWF PCL ; copy W to PCL
TABLE_B:
; |7|6|5|4|3|2|1|0| - Bits PORTB
; |C|F|D|G|-|-|-|-| -
RETLW B'00010000' ; |C|F|D|X|-|-|-|-| - 0
RETLW B'01110000' ; |C|X|X|X|-|-|-|-| - 1
RETLW B'11000000' ; |X|X|D|G|-|-|-|-| - 2
RETLW B'01000000' ; |C|X|D|G|-|-|-|-| - 3
RETLW B'00100000' ; |C|F|X|G|-|-|-|-| - 4
RETLW B'00000000' ; |C|F|D|G|-|-|-|-| - 5
RETLW B'00000000' ; |C|F|D|G|-|-|-|-| - 6
RETLW B'01110000' ; |C|X|X|X|-|-|-|-| - 7
RETLW B'00000000' ; |C|F|D|G|-|-|-|-| - 8
RETLW B'00000000' ; |C|F|D|G|-|-|-|-| - 9
;/****************************************************************************
;* DESCRIPTION: Little Delay to let display show digit.
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
DELAY_MS: ; Delay routine - W is the number of ms of delay.
MOVWF TEMPO1 ; put w in temp variable
MOVLW D'250'
MOVWF TEMPO0
DECFSZ TEMPO0,F
GOTO $-1
DECFSZ TEMPO1,F
GOTO $-5
RETURN
;/****************************************************************************
;* DESCRIPTION: binary_to_bcd - 8-bits
;* INPUT: TEMPER - 8-bit binary number
;* RETURN: CENTENA - the hundreds digit of the BCD conversion
;* DEZENA - the tens digits of the BCD conversion
;* UNIDADE - the ones digits of the BCD conversion
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
BINARY_TO_BCD:
MOVWF AUX ; sve the value to convert in AUX
CLRF UNITS ;
CLRF TENS ;
CLRF HUNDREDS ; RESET variables
MOVF AUX,F ;
BTFSC STATUS,Z ; Is the value to convert = 0?
RETURN ; Yes - Return
; No
INCF UNITS,F ; Increment unit
MOVF UNITS,W ;
XORLW 0X0A ;
BTFSS STATUS,Z ; unit = 10d ?
GOTO $+3 ; No
; yes
CLRF UNITS ; Reset unit
INCF TENS,F ; Increment tens
MOVF TENS,W ;
XORLW 0X0A ;
BTFSS STATUS,Z ; Tens = 10d ?
GOTO $+3 ; No
; Yes
CLRF TENS ; Reset tens
INCF HUNDREDS,F ; Increment hundreds
DECFSZ AUX,F ; End of conertion ?
GOTO $-.14 ; No - go back to continue the convertion
RETURN ; Yes
;/****************************************************************************
;* DESCRIPTION: Program Initialization
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
START:
BCF STATUS,RP0 ; Bank 2
BSF STATUS,RP1 ;
CLRF ANSEL ; digital I/O
CLRF ANSELH ; " " "
BCF STATUS,RP0 ; Bank 2
BSF STATUS,RP1 ;
MOVLW B'00000000'
MOVWF CM1CON0 ; disable comparator
MOVLW B'00000000' ; Not necessary?
MOVWF CM2CON0 ; disable 2nd comparator
MOVLW B'00000000' ; Not necessary?
MOVWF CM2CON1 ; disable 3rd comparator
BSF STATUS,RP0 ; Bank 1
BCF STATUS,RP1 ;
MOVLW B'00001000' ;
MOVWF TRISA ;
MOVLW B'00000000' ;
MOVWF TRISB ;
MOVLW B'10000010' ;
MOVWF TRISC ;
BCF STATUS,RP0 ; Bank 0
BCF STATUS,RP1 ;
BCF SSPCON,SSPEN ; Disable Synchronous Serial Port
; Turn off all reles, displays and leds
BSF LED_CMN ; Leds off
BSF DISP1 ; Display1 off
BSF DISP2 ; Display2 off
BSF DISP3 ; Display3 off
MOVLW D'180' ; Init temperature with 180 degrees Celsius
MOVWF TEMPER
MOVLW 2 ;
MOVWF T1_CONTA ;
; Init Timer1
MOVLW B'00000000' ; Configure TIMER1 for internal clock and prescaler 1:1
MOVWF T1CON ; Init Timer1
MOVLW 0x18 ;
MOVWF TMR1L ;
MOVLW 0xFC ;
MOVWF TMR1H ; Init TIMER1 with decimal 64536 (interrupt every 1ms)
BSF STATUS,RP0 ; Bank 1
BCF STATUS,RP1 ;
MOVLW B'00000001' ; Enable TIMER1 Overflow Interrupt
MOVWF PIE1
BCF STATUS,RP0 ; Bank 0
BCF STATUS,RP1 ;
CLRF PIR1 ; Clear Peripheral Interrupt Flags
BSF INTCON, PEIE ; Enable Peripheral Interrupts
BSF T1CON, TMR1ON ; Start TMR1
BSF INTCON, GIE ; Enable Global Interrupts
;/****************************************************************************
;* DESCRIPTION: Main Program
;* RETURN: none
;* ALGORITHM: none
;* NOTES: none
;*****************************************************************************/
MAIN_LOOP:
MOVF TEMPER,W ; Put temperature in W
CALL BINARY_TO_BCD ; Decode Temperature to bcd
BSF LED_CMN ; Leds off
MOVF UNITS,W ; copy units to W
;MOVLW D'0'
CALL DECOD_DISPLAY_A ; convert
MOVWF PORTA ; put it in PORTA
MOVF UNITS,W ; copy units to W
;MOVLW D'0'
CALL DECOD_DISPLAY_B ; convert
MOVWF PORTB ; put it in PORTA
BCF DISP1 ; display 1 on
MOVLW D'2' ;
CALL DELAY_MS ; delay 2 ms
BSF DISP1 ; display 1 off
MOVF TENS,W ; copy tens to W
;MOVLW D'0'
CALL DECOD_DISPLAY_A ; convert
MOVWF PORTA ; put it in PORTA
MOVF TENS,W ; copy tens to W
;MOVLW D'0'
CALL DECOD_DISPLAY_B ; convert
MOVWF PORTB ; put it in PORTA
BCF DISP2 ; display 1 on
MOVLW D'2' ;
CALL DELAY_MS ; delay 2 ms
BSF DISP2 ; display 1 off
MOVF HUNDREDS,W ; copy hundeds to W
;MOVLW D'0'
CALL DECOD_DISPLAY_A ; convert
MOVWF PORTA ; put it in PORTA
MOVF HUNDREDS,W ; copy hundeds to W
;MOVLW D'0'
CALL DECOD_DISPLAY_B ; convert
MOVWF PORTB ; put it in PORTA
BCF DISP3 ; display 1 on
MOVLW D'2' ;
CALL DELAY_MS ; delay 2 ms
BSF DISP3 ; display 1 off
BCF LED_UP ; led UP ON
BCF LED_DWN ; led DWN ON
BCF LED_TEMP ; led TEMP ON
BSF LED_TIMER ; led TIMER OFF
BSF LED_LIGHT ; led LIGHT OFF
BSF LED_TOASTER ; led TOASTER OFF
BCF LED_CMN ; Leds on
MOVLW D'2' ;
CALL DELAY_MS ; delay 2 ms
BSF LED_CMN ; Leds off
GOTO MAIN_LOOP ; Back to main loop
END