Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Too many timers

Status
Not open for further replies.

No1Daemon

New Member
Hi there

I have searched the forums and google and done a few tutorials but I am a bit lost in what I want to do.
I have also completed several tutorials such as blinking leds, reading switches, using timers etc.
I have 2 buttons and 1 led.
When I press the button I want the led to blink and each time I press the button I want the led to blink one more time than last.

i.e I want 3 button presses to make the led blink 3 times.

When it gets to 5 I want it to go back to 1 again.

I am using mpasm and a pic12f683.
Any suggestions?
 
What happens with the other button?
Do you want to access the other button at any time?

Do you want to do other things at the same time?
 
Yes I do want the other button to do something but I didn't want to complicate things.
The button in question sets a time. intervalr, the led flashes to indicate the length of the timer set.
The 2nd button activates the timer and also puts the circuit to sleep when held and wakes it up.

I also want to hold the second button when powered on to initiate an analog to digital conversion.
I have written some code for EEPROm, adc, interrupt on change etc but written it as modules.
I am just having a hard time organizing the flow of the timers etc with the button presses. And how to initiate an action when the button is held down instead of pressed.
 
I don't know how to do that. I have only made code for an interrupt on change so I can bring it back out of sleep.
Still taking baby steps.
Could it not be done by just incrementing a count for both button and led on each press?
The held function I guess could be a timer which if it overflows before button release is seen then it can call a subroutine for the adc etc.
Still learning these things so its all guess work at this stage. Some sample code or examples would be great.
 
There's no need for the button to be interrupt driven, that's only one possibility, it probably makes more sense to have the buttons polled, and a timer interrupt routine to flash the LED's - although there's no reason you couldn't do both (or neither) via interrupts.
 
Code:
de1A        equ 20h    ;
delB        equ 21h    ;
temp1        equ 22h    ;
temp2        equ    23h    ; 
pushes        equ    24h    
flashes        equ    25h
Stat_sav    equ 26h
W_sav       equ 27h

;****************************************************************
;Equates
;****************************************************************
status        equ    0x03
rp1            equ    0x06
rp0            equ    0x05


status        equ    03h
option_reg    equ 81h


        
        ;bits
                
rp0        equ    5            ;bit 5 of the status register



;****************************************************************
;Beginning of program
;****************************************************************
        org        0x00
        GOTO    SetUp
        nop
        ORG    4                ;interrupts always vector to here
        GOTO    isr
        nop
SetUp    bsf        status, rp0     ;Bank 1            
           movlw    b'11111000'        ;Set TRIS  GP0,1,2 out   GP3,4,5 input
        movwf    TRISIO               ;    
        bcf     option_reg,7    ;pull-ups enabled        
        MOVLW    b'00000100'        ;prescaler (1:32)
        MOVWF    OPTION_REG 80h    ;TMR0 interrupts = 6 mS apart
        BCF        STATUS, RP0        ;bank 0
        movlw   07h             ;turn off Comparator ports
        movwf   CMCON           ;must be placed in bank 0  
        Clrf    TMR0            ;clear Timer0 register    
        clrf    flashes    
        incf    flashes
        movlw    0xA0            ;set GIE <7> and T0IE <5>
        movwf    INTCON            ;enable Interrupts
        goto     Main    
        
    
isr        MOVWF    W_sav            ;first save critical registers
        SWAPF    STATUS,W
        BCF        STATUS,RP0        ;change to bank 0 
        MOVWF     Stat_sav    
        
        btfss    portA,0        ;test switchA
        call    switchPressed
        
        BCF        INTCON,T0IF
        BCF        INTCON,INTF
        SWAPF    Stat_sav,W
        MOVWF    STATUS        ; restore status 
        SWAPF    W_sav,F    
        SWAPF     W_sav,W        ; restore w without changing status
        RETFIE    
    
;********************
;* Delays             *
;********************

        
_10mS    movlw    0Ah
        movwf    delB
        nop
        decfsz     delA,f
        goto     $-2
        decfsz     delB,f
        goto     $-4    
        retlw     00    
        
        
_250mS    nop
        decfsz     delA,f
        goto     $-2
        decfsz     delB,f
        goto     $-4    
        retlw     00            
                        
            
        
;****************************
;* Sub Routines             *
;****************************
            
switchPressed
        
        movf    flashes,W    
        movwf    temp1
        movlw   06
        xorwf   temp1     ;if flashes=6
        btfss   status,z  ;z=1 if flashes=6
        goto    $+4
        movlw   1
        movwf   flashes
        goto    $-8        
        
        bsf        portA,xx   ;turn on LED    
        call    _250mS
        bcf        portA,xx   ;turn off LED    
        call    _250mS
        decfsz  temp1,f
        goto    $-5
        incf    flashes,f
        btfss    portA,0        ;loop until SwA is released
        goto    $-1
        retlw    00
        
                        
;************************
;* Main                 *
;************************

Main    
        goto    Main        
    
                
;************************
;*EEPROM                 *
;************************
                                
        org        2100h            
                    
                            
        END
 
If you want to poll the switches:

Code:
;****************************
;* Sub Routines             *
;****************************
            
SwA_Pressed
        
        movf    flashes,W    
        movwf    temp1
        movlw   06
        xorwf   temp1     ;if flashes=6
        btfss   status,z  ;z=1 if flashes=6
        goto    $+4
        movlw   1
        movwf   flashes
        goto    $-8        
        
        bsf        portA,xx   ;turn on LED    
        call    _250mS
        bcf        portA,xx   ;turn off LED    
        call    _250mS
        decfsz  temp1,f
        goto    $-5
        incf    flashes,f
        btfss    portA,0        ;loop until SwA is released
        goto    $-1
        retlw    00
        
                        
;************************
;* Main                 *
;************************

Main        
        btfss    portA,0        ;test switchA
        call    SwA_Pressed
        btfss    portA,1        ;test switchB
        call    SwB_Pressed
        goto    $-4
 
Thanks again
I just need to implement this code into it now for each count increment so I can make the delay greater for each press also.
Code:
; Delay = 300 seconds 
; Clock frequency = 4 MHz 
 
; Actual delay = 300 seconds = 300000000 cycles 
; Error = 0 % 
 
   cblock 
   d1 
   d2 
   d3 
   d4 
   count1
   endc 
 
DelayW      movwf   count1 
 
Delay5
         ;299999995 cycles 
   movlw   0x54 
   movwf   d1 
   movlw   0xA1 
   movwf   d2 
   movlw   0xFD 
   movwf   d3 
   movlw   0x02 
   movwf   d4 
Delay_0 
   decfsz   d1, f 
   goto   $+2 
   decfsz   d2, f 
   goto   $+2 
   decfsz   d3, f 
   goto   $+2 
   decfsz   d4, f 
   goto   Delay_0 
 
         ;5 cycles 
   goto   $+1 
   goto   $+1 
   nop 
 
      decfsz   count1   ,f 
      goto   Delay5 
      retlw   0x00
and then I need to make button b activate a relay with that timing.
You have done most of the work already.
Appreciate it.
 
You just use the value in "flashes" to create your delay value.
You don't need such an accurate delay routine.
What is the minimum and maximum delay
 
It is 5 minutes per press up to a maximum of 30 minutes. Hence buttona goes back to zero again and starts again each time.
Timing doesn't need to be hugely accurate just roughly 5 minutes but I thought as long as it was there I could use an exact one.

My device has the timer programmable in 5 minute intervals up to 30 minutes and this setting will be saved in EEPROM and read when the device is first started.So when the device is powered up the timer setting displays by flashing the led to indicate the time setting. Alternatively with pressing buttona a new interval can be set.
buttonb activates a small timer of 1 minute then activates a relay that drives a motor for the time period set with the timer program button. It also puts the device to sleep if held and wakes it from sleep.


Does that make sense? looked logical when I wrote it but logical to me may not work for you. lol
 
Create a 5 minute delay and call it up to 6 times, just as you have done above.
You don't need
;5 cycles
goto $+1
goto $+1
nop

With all of this you will be able to get your hydroponic garden up-and-running very quickly.
 
I think I can see reed switches on the PCB. You need a set of LEDs to show the current delay
 
Last edited:
Mike K8LH
You are correct. I cannot get this line
Code:
MOVWF    OPTION_REG 80h    ;TMR0 interrupts = 6 mS apart

to assemble
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top