Cycling through effects with a switch on a pic

Discussion in 'Embedded Systems and Microcontrollers' started by vanaardep, Apr 10, 2010.

  1. vanaardep

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    Hi there

    I am coding in asm. I am currently trying to change the following code to cycle through the effects using one switch triggering RA1. ie. when power is put on the pic(16F627), no leds come on, but when the switch is clicked and let go it changes to effect 1, then when the switch is pressed again it goes to effect 2 and so on. I have no clue how to go about this can someone help please :confused:

    ;==========================================================================
    ; Variable Definition
    ;==========================================================================
    ;INPUTS
    SW1 EQU H'00' ;SW1 is triggering RA0
    SW2 EQU H'01' ;SW2 is triggering RA1
    SW3 EQU H'02' ;SW3 is triggering RA2
    SW4 EQU H'03' ;SW4 is triggering RA3
    TIMER1 EQU H'20' ;Used in delay routine
    TIMER2 EQU H'21' ; " " "
    PATERN EQU H'22' ;Pattern data for effect's


    ORG 0 ;Reset vector address
    GOTO RESET ;goto RESET routine when boot.


    ; *********************************************
    ; * Example of a delay routine *
    ; *********************************************

    DELAY_ROUTINE MOVLW D'10' ;54 Generate approx 10mS delay at 4Mhz CLK
    MOVWF TIMER2
    DEL_LOOP1 MOVLW D'10' ;60
    MOVWF TIMER1
    DEL_LOOP2 BTFSC PORTA,SW1
    GOTO MENU
    BTFSC PORTA,SW2
    GOTO MENU
    BTFSC PORTA,SW3
    GOTO MENU
    BTFSC PORTA,SW4
    GOTO MENU
    DECFSZ TIMER1,F
    GOTO DEL_LOOP2
    DECFSZ TIMER2,F
    GOTO DEL_LOOP1
    RETLW 0


    ; **********************************
    ; ** RESET : main boot routine **
    ; **********************************

    RESET MOVLW B'00000111' ;Disable Comparator module's
    MOVWF CMCON
    ;
    BSF STATUS,RP0 ;Switch to register bank 1
    ;Disable pull-ups
    ;INT on rising edge
    ;TMR0 to CLKOUT
    ;TMR0 Incr low2high trans.
    ;Prescaler assign to Timer0
    ;Prescaler rate is 1:256
    MOVLW B'11010111' ;Set PIC options (See datasheet).
    MOVWF OPTION_REG ;Write the OPTION register.
    ;
    CLRF INTCON ;Disable interrupts
    MOVLW B'11000000'
    MOVWF TRISB ;RB7 & RB6 are inputs.
    ;RB5...RB0 are outputs.
    MOVLW B'11111111' ;all RA ports are inputs
    MOVWF TRISA
    BCF STATUS,RP0 ;Switch Back to reg. Bank 0
    CLRF PORTB
    GOTO EFFECT_4
    ;

    MENU CLRF PORTB
    ;
    BTFSC PORTA,SW1
    GOTO EFFECT_1
    BTFSC PORTA,SW2
    GOTO EFFECT_2
    BTFSC PORTA,SW3
    GOTO EFFECT_3
    BTFSC PORTA,SW4
    GOTO EFFECT_4
    GOTO MENU


    EFFECT_1 BTFSC PORTA,SW1
    GOTO EFFECT_1
    E1 MOVLW B'00100001' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00010010' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00001100' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'11111111' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00001100' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00010010' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00100001' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00000000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00000000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00000000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    GOTO E1


    EFFECT_2 BTFSC PORTA,SW2
    GOTO EFFECT_2
    E2 MOVLW B'00000001' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00000010' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00000100' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00001000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00010000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00100000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00010000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00001000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00000100' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    MOVLW B'00000010' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    GOTO E2

    EFFECT_3 BTFSC PORTA,SW3
    GOTO EFFECT_3
    E3 MOVLW B'00000111' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    CALL DELAY_ROUTINE
    MOVLW B'00111000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    CALL DELAY_ROUTINE
    GOTO E3

    EFFECT_4 BTFSC PORTA,SW4
    GOTO EFFECT_4
    E4 MOVLW B'11111111' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    CALL DELAY_ROUTINE
    MOVLW B'00000000' ;
    MOVWF PORTB
    CALL DELAY_ROUTINE
    CALL DELAY_ROUTINE
    GOTO E4


    END
     
  2. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    You could do it with a main loop (this is pseodocode not real assembler)

    loop
    if state=1 call effect_1
    if state=2 call effect_2
    .
    .
    .
    goto loop

    You can have your switch detection in the delay routine which gets called pretty often (or use an interrupt) and just increases "state" until the max value then resets it.
    To do this you need to put a "return" at the end of each effect routine so it goes through once then returns to the main loop.
    The switch effect wouldn't be instant but I think the patterns are quite short so it would work pretty well.
     
  3. vanaardep

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    Thanks man will give it a try
     
  4. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    Hi vanaardep (and gang),

    I thought you might enjoy studying an example "FX Sequencer" program that uses a slightly different approach. Basically I built your 10-msec sequence interval timing into a simple sequencer loop. The loop grabs an output pattern byte from a table for the currently selected animation sequence and writes it to your LED port. Then it delays 10-msecs and samples the switch on RA0 (10-msecs is just about perfect for a debounce delay). A switch state latch variable and simple logic allows us to detect and act on a "new press" while ignoring the other switch states (no more waiting for a switch release). If a "new press" is detected we jump out of the sequencer loop and 'bump' the effect number variable and run the new effect sequence, otherwise we continue running the current sequence in the 10-msec sequencer loop. When the sequencer gets to the end of the current sequence pattern table it starts over at the beginning of that sequence. Here's an excerpt of the main program loop;

    Code ( (Unknown Language)):
    1. ;******************************************************************
    2. ;  main.loop                                                      *
    3. ;******************************************************************
    4.  
    5. fxbump
    6.         clrf    PORTB           ; blank the LED outputs           |B0
    7.         incf    fxnbr,F         ; increment effect number         |B0
    8.         bcf     fxnbr,2         ; inclusive, 0..3                 |B0
    9.         movf    fxnbr,W         ; W = effect number, 0..3         |B0
    10.         addwf   fxnbr,W         ; W = effect number * 2           |B0
    11.         addwf   fxnbr,W         ; W = effect number * 3           |B0
    12.         addlw   low(fxtbl)      ; add to address table lo         |B0
    13.         movwf   ptrl            ; setup table pointer lo          |B0
    14.         movlw   high(fxtbl)     ; address table hi                |B0
    15.         skpnc                   ; carry? no, skip, else           |B0
    16.         addlw   1               ; account for carry               |B0
    17.         movwf   ptrh            ; setup table pointer hi          |B0
    18.         call    RdTable         ; get effect table addr lo        |B0
    19.         movwf   begl            ; save "begin" table lo           |B0
    20.         call    RdTable         ; get effect table addr hi        |B0
    21.         movwf   begh            ; save "begin" table hi           |B0
    22.         call    RdTable         ; get effect table length         |B0
    23.         movwf   count           ; save length                     |B0
    24. fxprep
    25.         movf    begl,W          ; start/restart fx sequence       |B0
    26.         movwf   ptrl            ; set table/array pointer lo      |B0
    27.         movf    begh,W          ;                                 |B0
    28.         movwf   ptrh            ; set table/array pointer hi      |B0
    29.         movf    count,W         ;                                 |B0
    30.         movwf   steps           ; set # steps in sequence         |B0
    31. fxstep
    32.         call    RdTable         ; get "pattern" byte              |B0
    33.         movwf   PORTB           ; update port                     |B0
    34.         DelayCy(10*msecs-27)    ; 10 msecs -27 cycle loop time    |B0
    35. [COLOR=Blue]        movf    PORTA,W         ; sample active hi switches       |B0
    36.         andlw   b'00000001'     ; on RA0 pin                      |B0
    37.         xorwf   swold,W         ; W = changes, press or release   |B0
    38.         xorwf   swold,F         ; update switch state latch       |B0
    39.         andwf   swold,W         ; filter out "new release" bits   |B0
    40.         bnz     fxbump          ; branch on a "new press", else   |B0
    41. [/COLOR]        decfsz  steps,F         ; sequence complete?              |B0
    42.         goto    fxstep          ; no, branch (next step), else    |B0
    43.         goto    fxprep          ; restart the sequence            |B0
    44. ;
    45.  
    The table read routines and FX sequence tables might look something like this (below). Each sequence pattern is displayed for 10-msecs so you would duplicate patterns for longer delays, or perhaps redesign the program with "pattern" and "duration" bytes for each sequence.

    Code ( (Unknown Language)):
    1. ;******************************************************************
    2. ;  table read routine and "fx" tables                             *
    3. ;******************************************************************
    4.  
    5. RdTable
    6.         call    RdByte          ;                                 |B0
    7.         incf    ptrl,F          ; bump pointer                    |B0
    8.         skpnz                   ;                                 |B0
    9.         incf    ptrh,F          ;                                 |B0
    10.         return                  ;                                 |B0
    11. RdByte
    12.         movf    ptrh,W          ;                                 |B0
    13.         movwf   PCLATH          ;                                 |B0
    14.         movf    ptrl,W          ;                                 |B0
    15.         movwf   PCL             ;                                 |B0
    16. fxtbl
    17.         dt      low(fx1)        ; fx1 array address lo            |B0
    18.         dt      high(fx1)       ; fx1 array address hi            |B0
    19.         dt      fx2-fx1         ; fx1 array length                |B0
    20.         dt      low(fx2)        ; fx2 array address lo            |B0
    21.         dt      high(fx2)       ; fx2 array address hi            |B0
    22.         dt      fx3-fx2         ; fx2 array length                |B0
    23.         dt      low(fx3)        ; fx3 array address lo            |B0
    24.         dt      high(fx3)       ; fx3 array address hi            |B0
    25.         dt      fx4-fx3         ; fx3 array length                |B0
    26.         dt      low(fx4)        ; fx4 array address lo            |B0
    27.         dt      high(fx4)       ; fx4 array address hi            |B0
    28.         dt      fxx-fx4         ; fx4 array length                |B0
    29. fx1
    30.         dt      b'00100001'     ; effect 1 array                  |B0
    31.         dt      b'00010010'     ;                                 |B0
    32.         dt      b'00001100'     ;                                 |B0
    33.         dt      b'11111111'     ;                                 |B0
    34.         dt      b'00001100'     ;                                 |B0
    35.         dt      b'00010010'     ;                                 |B0
    36.         dt      b'00100001'     ;                                 |B0
    37.         dt      b'00000000'     ;                                 |B0
    38.         dt      b'00000000'     ;                                 |B0
    39.         dt      b'00000000'     ;                                 |B0
    40. fx2
    41.         dt      b'00000001'     ; effect 2 array                  |B0
    42.         dt      b'00000010'     ;                                 |B0
    43.         dt      b'00000100'     ;                                 |B0
    44.         dt      b'00001000'     ;                                 |B0
    45.         dt      b'00010000'     ;                                 |B0
    46.         dt      b'00100000'     ;                                 |B0
    47.         dt      b'00010000'     ;                                 |B0
    48.         dt      b'00001000'     ;                                 |B0
    49.         dt      b'00000100'     ;                                 |B0
    50.         dt      b'00000010'     ;                                 |B0
    51. fx3
    52.         dt      b'00000111'     ; effect 3 array                  |B0
    53.         dt      b'00000111'     ;                                 |B0
    54.         dt      b'00111000'     ;                                 |B0
    55.         dt      b'00111000'     ;                                 |B0
    56. fx4
    57.         dt      b'11111111'     ; effect 4 array                  |B0
    58.         dt      b'11111111'     ;                                 |B0
    59.         dt      b'00000000'     ;                                 |B0
    60.         dt      b'00000000'     ;                                 |B0
    61. fxx
    62.  
    The complete "FX Sequencer" example program for 16F628A is attached below. Please let me know if it helps or if you have any questions.

    Kind regards, Mike, K8LH
     
    Last edited: Apr 12, 2010
  5. vanaardep

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    wow thanks man:) but when i compile it with mpasmwin i get one error:confused:
     
  6. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    No errors here... What error are you getting?
     
  7. retched

    AAC Fanatic!

    Dec 5, 2009
    5,201
    312
    Did you cut-and paste or did you retype by hand? Check for 'spelling' errors.
     
  8. vanaardep

    Thread Starter New Member

    Apr 10, 2010
    5
    0
    Fixed, i just made a mistake in the header of the code. Thanks for all the help:)
     
  9. MMcLaren

    Well-Known Member

    Feb 14, 2010
    759
    116
    You're welcome. Did it work? Do you see how to modify the sequences?

    Regards, Mike
     
Loading...