Easy to program this flowcart in ASM?

Thread Starter

tigerapna

Joined Dec 14, 2011
73
I purchased a 16F690 PICKIT 2 starter kit and wish to program it in assembler (not familar with C) with the following flow cart.

Can this easily be done?

DHW and RADIANT are two input switches and the PUMPs are the output.

I am rusty with my assembler but can I improve my design anywhere on the flow chart?
 

Attachments

t06afre

Joined May 11, 2009
5,934
Should not be that hard. Your flowchart will be a good help. Will the timing be critical? From the look of your problem. I would probably have used the same approach as programming a clock. Putting the time keeping in an interrupt service routine. Maybe using a watch crystal. The 16f690 do have an internal oscillator. But it is not good for accurate timing
 

Thread Starter

tigerapna

Joined Dec 14, 2011
73
Should not be that hard. Your flowchart will be a good help. Will the timing be critical? From the look of your problem. I would probably have used the same approach as programming a clock. Putting the time keeping in an interrupt service routine. Maybe using a watch crystal. The 16f690 do have an internal oscillator. But it is not good for accurate timing
Yes the timing accuracy isn't soo important. Anywhere from 50-70 min would be okay. are there examples anywhere for this timing ISR?
 

Thread Starter

tigerapna

Joined Dec 14, 2011
73
The internal oscillator should be fine, most of them are specified to be better than 2% accuracy.
So do I just then have a counter to count Timer0 flag and scale it to my approximate time requirements?

What bit can be used to enable and disable the timer?
 

t06afre

Joined May 11, 2009
5,934
So do I just then have a counter to count Timer0 flag and scale it to my approximate time requirements?

What bit can be used to enable and disable the timer?
All that information can be found in the datasheet. It is better that you do some research. And then post for comments.
 

Markd77

Joined Sep 7, 2009
2,806
Here's some code that uses Timer0 interrupts to keep track of time. It does a bit more as well but after you've studied the datasheet you should be able to find the relevant parts.
http://forum.allaboutcircuits.com/showpost.php?p=452093&postcount=87
<ed> I've copied the code here, it makes more sense. </ed>
Rich (BB code):
    list      p=16f876            ; list directive to define processor
    #include <p16f876.inc>        ; processor specific variable definitions
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _XT_OSC & _WRT_ENABLE_ON & _LVP_OFF & _DEBUG_OFF & _CPD_OFF
w_temp        EQU     0x7E        ; variable used for context saving
status_temp   EQU     0x7F        ; variable used for context saving
    cblock 0x20
    PORTAtemp
    PORTBtemp
    digit1pins
    digit0pins            ;right digit
    LOOPCOUNT
    multiplexcount
    microsecondsH
    microsecondsM
    microsecondsL
    second_flag
    seconds
    minute_tens
    minute_units
    endc


    ORG     0x000             ; processor reset vector
    clrf PCLATH
      goto    init              ; go to beginning of program


    ORG     0x004             ; interrupt vector location
    movwf   w_temp            ; save off current W register contents
    movf    STATUS,w          ; move status register into W register
    movwf    status_temp       ; save off contents of STATUS register
    bcf STATUS, RP0            ;bank 0

    movf multiplexcount, W
    addwf PCL, F
    goto digit1
    goto digit0
digit1
    bcf PORTAtemp, 7            ;toggle transistor pins
    bsf PORTAtemp, 6
    movf digit1pins, W            ;display digit
    movwf PORTB
    incf multiplexcount, F
    goto digitdone
digit0
    bcf PORTAtemp, 6            ;toggle transistor pins
    bsf PORTAtemp, 7
    movf digit0pins, W            ;display digit
    movwf PORTB
    clrf multiplexcount
digitdone
    movf PORTAtemp, W
    movwf PORTA
    bcf INTCON, TMR0IF


;Interrupt gets here every 1024 cycles, so subtract 1024 from a
;counter that was preset to 1000000.
;When the counter overflows add 1000000 so there are no cumulative
;errors
    movlw 4
    subwf microsecondsM, F        ;microseconds - 1024
    btfsc STATUS, C
    goto ISR_end
    movf microsecondsH, W    ;check if zero
    btfsc STATUS, Z
    goto reset_timer            ;1 second is up
    decf microsecondsH, F
    goto ISR_end
reset_timer        ;just add 1000000 (0x0F4240) to microseconds
    movlw 0x0F  
    addwf microsecondsH            ;no need to check for overflow
    movlw 0x42
    addwf microsecondsM            ;no need to check for overflow
    movlw 0x40
    addwf microsecondsL, F
    btfsc STATUS, C
    incf microsecondsM, F
    bsf second_flag, 0


ISR_end
    movf    status_temp,w     ; retrieve copy of STATUS register
    movwf    STATUS            ; restore pre-isr STATUS register contents
    swapf   w_temp,f
    swapf   w_temp,w          ; restore pre-isr W register contents
    retfie                    ; return from interrupt

;table is at start to avoid page crossing 
bcdto7seg            ;bit 2 not used here (decimal point)
    addwf    PCL, F    ; Jump into the lookup table
    retlw    B'11101011'    ; Return segment code for 0
    retlw    B'00100001'    ; Return segment code for 1
    retlw    B'10111010'    ; Return segment code for 2
    retlw    B'10110011'    ; Return segment code for 3
    retlw    B'01110001'    ; Return segment code for 4
    retlw    B'11010011'    ; Return segment code for 5
    retlw    B'11011011'    ; Return segment code for 6
    retlw    B'10100001'    ; Return segment code for 7
    retlw    B'11111011'    ; Return segment code for 8
    retlw    B'11110011'    ; Return segment code for 9
    return

init


    MOVLW 0x20                    ;clear files
    MOVWF FSR
NEXT
    CLRF INDF
    INCF FSR, F
    BTFSS FSR, 7
    GOTO NEXT

    clrwdt
    banksel OPTION_REG
    movlw b'11000001'
    movwf OPTION_REG
    banksel INTCON
    movlw b'10100000'        ;timer0 on interrupts on
    movwf INTCON            ;prescaler 4 so interrupt every 1024 cycles

    banksel TRISA

    movlw b'00010001'
    movwf TRISA
    clrf TRISB

    movlw b'10001110'
    movwf ADCON1
    bcf STATUS,RP0                    ;bank0
    movlw 0x0F
    movwf microsecondsH
    movlw 0x42
    movwf microsecondsM
    movlw 0x40
    movwf microsecondsL


main
    btfss second_flag, 0
    goto normal
    bcf second_flag, 0
    incf seconds, F            ;just increment seconds and digits to display
    movlw d'60'
    subwf seconds, W
    btfss STATUS, Z
    goto update_display
    clrf seconds
    incf minute_units, F        ;easier to store digits separately
    movlw d'10'
    subwf minute_units, W
    btfss STATUS, Z
    goto update_display
    clrf minute_units
    incf minute_tens, F

;do some more checks to see if total time elapsed



update_display
;calculate digit0pins and digit1pins
    movf minute_units, W
    call bcdto7seg
    movwf digit0pins
    movf minute_tens, W
    call bcdto7seg
    movwf digit1pins

normal
; remaining code goes here (needs to take less than 1 second)
    goto main 


        END                       ; directive 'end of program'
 
Last edited:
Top