1. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    In this program I want to get input from GPIO2 using a momentary switch. I can get input from pin 4 which is GPIO 3 but I want to get input from both. I'm been trying to tackle this for awhile and I feel I could use a couple tips. I pasted the code below and look at the code portion where I call State3 and my condition is that GPIO2 is set high in order for that function to be called.


    Code ( (Unknown Language)):
    1.     list      p=12f629            ; list directive to define processor
    2.     #include <p12f629.inc>        ; processor specific variable definitions
    3.  
    4.     errorlevel  -302              ; suppress message 302 from list file
    5.  
    6.     __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT  
    7.  
    8. ; '__CONFIG' directive is used to embed configuration word within .asm file.
    9. ; The labels following the directive are located in the respective .inc file.
    10. ; See data sheet for additional information on configuration word settings.
    11.  
    12. ;************************** VARIABLE DEFINITIONS ******************************
    13.  
    14.       cblock    0x20           
    15.     STATE_LED           ; LED state machine counter
    16.     STATE_DEBOUNCE          ; button debounce state machine counter
    17.       endc
    18.  
    19. ;*************************** DEFINE STATEMENTS ********************************
    20.  
    21. ; input and output definitions 
    22.  
    23. #define SW1     GPIO,3      ; toggle switch 1
    24. #define SW2     GPIO,2      ; toggle switch 2
    25.  
    26. ; define input/output designation for LEDs (what TRISIO will equal)
    27.  
    28. #define TRIS_D0_D1  B'00001111' ; TRISIO setting for D0 and D1
    29. #define TRIS_D2_D3  B'00101011' ; TRISIO setting for D2 and D3
    30. #define TRIS_D4_D5  B'00011011' ; TRISIO setting for D4 and D5
    31. #define TRIS_D6_D7  B'00111001' ; TRISIO setting for D6 and D7
    32. #define allInputs   B'00111111' ; TRISIO setting D0-D7 as inputs
    33.  
    34. ; define LED state (what GPIO will equal)
    35.  
    36. #define D0_ON   B'00010000'     ; D0 LED
    37. #define D1_ON   B'00100000'     ; D1 LED
    38. #define D2_ON   B'00010000'     ; D2 LED
    39. #define D3_ON   B'00000100'     ; D3 LED
    40. #define D4_ON   B'00100000'     ; D4 LED
    41. #define D5_ON   B'00000100'     ; D5 LED
    42. #define D6_ON   B'00000100'     ; D6 LED
    43. #define D7_ON   B'00000010'     ; D7 LED
    44. #define Blank   B'00000000'     ; All LEDs off
    45.  
    46. ;****************************** Start of Program ******************************
    47.     org     0x000           ; processor reset vector
    48.     goto    Initialize
    49.  
    50. ;******************************************************************************
    51. ; Initialize
    52. ;   Initialize Special Function Registers    
    53. ;******************************************************************************
    54.     org 0x005           ; Start of Programm Memory Vector
    55. Initialize
    56.     ;call    0x3FF      ; retrieve factory calibration value
    57.                         ; comment instruction if using simulator, ICD2, or ICE2000
    58.     bsf     STATUS,RP0      ; Bank 1
    59.     movwf   OSCCAL          ; update register with factory cal
    60.                     ;  value
    61.     movlw   B'00111111'     ; Set all I/O pins as inputs
    62.     movwf   TRISIO         
    63.    
    64.     movlw   B'10000100'     ; Weak pullups: disabled
    65.     movwf   OPTION_REG      ; TMR0 prescaler: 1:32 (TMR0 will
    66.                     ;  overflow in 8.2ms)
    67.     clrf    INTCON          ; disable all interrupts, clear all
    68.                     ;  flags   
    69.     bcf     STATUS,RP0      ; Bank 0
    70.     clrf    GPIO            ; clear all outputs
    71.     clrf    TMR0            ; clear Timer 0
    72.     clrf    STATE_LED       ; clear LED state machine counter
    73.     clrf    STATE_DEBOUNCE      ; clear debounce state machine counter
    74.  
    75. ;******************************************************************************
    76. ; State_Machine
    77. ;   Implements a state machine that lights up the LEDs on the PICkit board
    78. ;       sequentially when SW1 is pressed.    
    79. ;******************************************************************************
    80.  
    81. StateMachine
    82.  
    83.     btfss   SW1
    84.     call    State0          ;   mented by STATE_LED in order
    85.     btfss   SW1
    86.     call    State1
    87.     btfss   SW1
    88.     call    State2
    89.     btfss   SW2
    90.     call    State3
    91.     bsf STATUS, RP0         ; Bank 1
    92.     movlw   allInputs       ; make all inputs in TRISIO
    93.     movwf   TRISIO
    94.     btfsc   SW1
    95.     call    Restart
    96.     goto    StateMachine
    97.  
    98. Restart
    99.     bcf STATUS, RP0         ; Bank 0
    100.     movlw   Blank           ; move predefined value to GPIO
    101.     movwf   GPIO
    102.     return
    103.    
    104. State0                     
    105. ; Turns on D0 LED
    106.     bsf STATUS, RP0     ; Bank 1
    107.     movlw   TRIS_D0_D1      ; move predefined value to TRISIO
    108.     movwf   TRISIO
    109.     bcf STATUS, RP0     ; Bank 0
    110.     movlw   D0_ON           ; move predefined value to GPIO
    111.     movwf   GPIO
    112.     return
    113.  
    114. State1
    115. ; Turns on D1 LED
    116.     bsf STATUS, RP0     ; Bank 1
    117.     movlw   TRIS_D0_D1      ; move predefined value to TRISIO
    118.     movwf   TRISIO
    119.     bcf STATUS, RP0     ; Bank 0
    120.     movlw   D1_ON           ; move predefined value to GPIO
    121.     movwf   GPIO
    122.     return  
    123.    
    124. State2
    125. ; Turns on D2 LED
    126.     bsf STATUS, RP0     ; Bank 1
    127.     movlw   TRIS_D2_D3      ; move predefined value to TRISIO
    128.     movwf   TRISIO
    129.     bcf STATUS, RP0     ; Bank 0
    130.     movlw   D2_ON           ; move predefined value to GPIO
    131.     movwf   GPIO
    132.     return
    133. State3
    134. ; Turns on D3 LED
    135.     bsf STATUS, RP0     ; Bank 1
    136.     movlw   TRIS_D2_D3      ; move predefined value to TRISIO
    137.     movwf   TRISIO
    138.     bcf STATUS, RP0     ; Bank 0
    139.     movlw   D3_ON           ; move predefined value to GPIO
    140.     movwf   GPIO
    141.     return
     
  2. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Have you tried to fire up the dubugger in MPLAB and do some single stepping.
     
    peter_morley likes this.
  3. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,607
    Your state machine switch is not properly coded:

    Code ( (Unknown Language)):
    1.     btfss    SW1
    2.     call    State0            ;   mented by STATE_LED in order
    3.     btfss    SW1
    4.     call    State1
    5.     btfss    SW1
    6.     call    State2
    7.     btfss    SW2
    8.     call    State3
    You test SW1 twice with the same test expecting 2 different destinations. Same with State2. Also, are you sure you want to return back to the middle of the switch?

    Also, GP2 is configured as analog until you clear the ANSEL bit for it.
     
    Last edited: Aug 7, 2011
  4. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    How do I clear the ANSEL bit do I do something like this...clrf ANSEL? I just started programming pics yesterday so I've got a learning curve ahead of me. I have programmed multiple microcontrollers but PICs seem to be a little different than what I'm used to.
     
  5. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
    Have you seen my tips in the sticky here. This will learn you how get up to speed using the debugger. Take a look here http://forum.allaboutcircuits.com/showthread.php?t=44852
    It also correct to use clrf ANSEL. ANSEL is defined in the p12f629.inc file. A common mistake is to not clear this flag. Analog inputs on all PICs turned on by default after power on reset. Easy to forget
     
  6. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    Look at section 3.1 of the datasheet, it shows you how to set up the port.
     
    peter_morley likes this.
  7. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    Good to know thanks

    Thanks for the post that little section helped me out quite a bit.
     
  8. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    Do I need to configure my GPIO inputs to have pullup resistors in the OPTION register?
     
  9. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    I made my code to wait until user presses a momentary switch on GPIO3 or GPIO2. When GPIO3 is pressed GPIO5 should be set to high 5V.
    When GPIO2 is pressed GPIO4 should be set to high 5V. I am getting voltages from the output of both GPIO 4 and 5 whenever I press a certain momentary switch. The voltages are not 5V though they are around 2-2.5 volts. I thought I made all inputs and outputs digital but I guess not. Any suggestions to fix this?

    Code ( (Unknown Language)):
    1.  
    2. list      p=12f675            ; list directive to define processor
    3. #include <p12f675.inc>        ; processor specific variable definitions
    4.  
    5.     __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT  
    6.  
    7. ;*************************** DEFINE STATEMENTS ********************************
    8.  
    9. ; Register Bank Directories
    10.  
    11. #define Bank0   banksel 0x00        ; first registerr bank = Bank 0
    12. #define Bank1   banksel 0x80        ;second register bank = Bank 1
    13.  
    14. ; Momentary switch inputs
    15.  
    16. #define SW1         GPIO,3          ; toggle switch at GPIO 3
    17. #define SW2         GPIO,2          ; toggle switch at GPIO 2
    18. #define I_O         B'00001100'     ; TRISIO setting makes GPIO2/3 inputs and the rest outputs
    19. #define Digital     B'00111111'     ; makes all GPIO digital pins
    20. #define Blank       B'00000000'     ; All LEDs off
    21.  
    22. ;****************************** Start of Program ******************************
    23.     org     0x000           ; processor reset vector
    24.     goto    Initialize
    25.  
    26. ;******************************************************************************
    27. ; Initialize
    28. ;   Initialize Special Function Registers    
    29. ;******************************************************************************
    30.     org 0x005           ; Start of Programm Memory Vector
    31. Initialize
    32.  
    33.     Bank0
    34.     clrf GPIO           ;Init GPIO
    35.     movlw Digital       ;Set GP<2:0> to
    36.     movwf CMCON         ;digital IO
    37.     Bank1               ;Bank 1
    38.     clrf ANSEL          ;Digital I/O   
    39.     movlw 0Ch           ;Set GP<3:2> as inputs
    40.     movwf TRISIO        ;and set GP<5:4,1:
    41.  
    42. ;******************************************************************************
    43. ; State_Machine
    44. ;   Implements a state machine that lights up the LEDs on the PICkit board
    45. ;       sequentially when SW1 is pressed.    
    46. ;******************************************************************************
    47.  
    48. StateMachine
    49.  
    50.     btfss   SW1             ; if GPIO 3 is pulled low then
    51.     call    G5Set           ; call G5Set to make GPIO 5 high
    52.     btfss   SW2             ; if GPIO 2 is pulled low then     
    53.     call    G4Set           ; call G4Set to make GPIO 4 high
    54.     call    Restart
    55.     goto    StateMachine
    56.  
    57. Restart
    58.     bcf STATUS, RP0         ; Bank 0
    59.     movlw   Blank           ; clears pins of GPIO
    60.     movwf   GPIO
    61.     return
    62.    
    63. G5Set                      
    64.  
    65.     Bank0                       ; Bank 0
    66.     movlw   B'00000001'         ; set GPIO5
    67.     movwf   GPIO
    68.     return
    69.  
    70. G4Set
    71.  
    72.     Bank0                       ; Bank 0
    73.     movlw   B'00000010'         ; set GPIO4
    74.     movwf   GPIO
    75.     return  
    76.  
    77.     end                         ; directive 'end of program'
    78.  
     
  10. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,607
    You still have not fixed the state machine code as I mentioned in post #3. Follow the call back thru the return and see you ALWAYS call Restart.
     
  11. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    A floating input can read at about that level. Connect the pin with a 1K resistor to either 0V or 5V and measure the pin voltage again. It should now read 0V or 5V. Floating inputs aren't a good idea and can cause device resets.
     
  12. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    I just changed it, i'm not sure if this will work because I am just starting to use registers and the syntax is weird for me.


    movlw SW1
    andlw SW2
    btfsc SW1
    call Restart

    What I think this does is moves GPIO 3 value to register w so register w looks like this 00000001 if the GPIO is not pressed. Then I would AND w and SW2 which contains GPIO2 value 1 if not pressed. Then only when both are high will the restart function be called to reset. Otherwise we need to evaluate a key press.


    Code ( (Unknown Language)):
    1.  
    2. list      p=12f675            ; list directive to define processor
    3. #include <p12f675.inc>        ; processor specific variable definitions
    4.  
    5.     __CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT  
    6.  
    7. ;*************************** DEFINE STATEMENTS ********************************
    8.  
    9. ; Register Bank Directories
    10.  
    11. #define Bank0   banksel 0x00        ; first registerr bank = Bank 0
    12. #define Bank1   banksel 0x80        ;second register bank = Bank 1
    13.  
    14. ; Momentary switch inputs
    15.  
    16. #define SW1         GPIO,3          ; toggle switch at GPIO 3
    17. #define SW2         GPIO,2          ; toggle switch at GPIO 2
    18. #define I_O         B'00001100'     ; TRISIO setting makes GPIO2/3 inputs and the rest outputs
    19. #define Digital     B'00111111'     ; makes all GPIO digital pins
    20. #define Blank       B'00000000'     ; All LEDs off
    21.  
    22. ;****************************** Start of Program ******************************
    23.     org     0x000           ; processor reset vector
    24.     goto    Initialize
    25.  
    26. ;******************************************************************************
    27. ; Initialize
    28. ;   Initialize Special Function Registers    
    29. ;******************************************************************************
    30.     org 0x005           ; Start of Programm Memory Vector
    31. Initialize
    32.  
    33.     Bank0
    34.     clrf GPIO           ;Init GPIO
    35.     movlw Digital       ;Set GP<2:0> to
    36.     movwf CMCON         ;digital IO
    37.     Bank1               ;Bank 1
    38.     clrf ANSEL          ;Digital I/O   
    39.     movlw 0Ch           ;Set GP<3:2> as inputs
    40.     movwf TRISIO        ;and set GP<5:4,1:
    41.  
    42. ;******************************************************************************
    43. ; State_Machine
    44. ;   Implements a state machine that lights up the LEDs on the PICkit board
    45. ;       sequentially when SW1 is pressed.    
    46. ;******************************************************************************
    47.  
    48. StateMachine
    49.    
    50.     movlw   SW1
    51.     andlw   SW2
    52.     btfsc   SW1
    53.     goto    Restart
    54.    
    55.     btfss   SW1             ; if GPIO 3 is pulled low then
    56.     call    G5Set           ; call G5Set to make GPIO 5 high
    57.     btfss   SW2             ; if GPIO 2 is pulled low then     
    58.     call    G4Set           ; call G4Set to make GPIO 4 high
    59.    
    60.     goto    StateMachine
    61.  
    62. Restart
    63.     bcf STATUS, RP0         ; Bank 0
    64.     movlw   Blank           ; clears pins of GPIO
    65.     movwf   GPIO
    66.     goto          StateMachine
    67.    
    68. G5Set                      
    69.  
    70.     Bank0                       ; Bank 0
    71.     movlw   B'00000001'         ; set GPIO5
    72.     movwf   GPIO
    73.     return
    74.  
    75. G4Set
    76.  
    77.     Bank0                       ; Bank 0
    78.     movlw   B'00000010'         ; set GPIO4
    79.     movwf   GPIO
    80.     goto    StateMachine
    81.    
    82.  
    83.     end                         ; directive 'end of program'
    84.  
     
    Last edited: Aug 7, 2011
  13. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    I'm still getting 2-2.5 volts on those pins with 1k resistors attached to ground.
     
  14. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    In that case it is likely to be an output that is rapidly toggling between 1 and 0. A multimeter will average so you just see a value in between.
     
    peter_morley likes this.
  15. Markd77

    Senior Member

    Sep 7, 2009
    2,803
    594
    The first 2 instructions here aren't doing what you think they are. Most PIC instructions operate on whole bytes.


    Also in the config line I'd recommend _WDT_OFF otherwise the PIC will reset itself regularly and very quickly.
     
  16. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    Your state machine does not have any delays or debouncing!

    So when you press SW1 it will perform state0, State1 etc in extremely rapid succession.

    I suggest you add a debounce routine, the easiest reliable way is after any SW press is detected, you wait until the switch is released for >X amount of time.

    You can do this with code like;
    Code ( (Unknown Language)):
    1.  
    2. ; function to debounce a button (will loop here until SW1 is properly released)
    3. debounce_SW1    
    4.     clrf TMR0   ;  reset timer
    5. debSW1_loop
    6.     btfss SW1   ;   test switch again
    7.     clrf TMR0   ;    keep clearing timer if switch still pressed!
    8.     btfss TMR0,F7  ;exit when TMR0 >=128
    9.     goto debSW1_loop   ;
    10.     return   ;
    11.  
    So at the end of your State0 code you call "debounce_SW1" and it will wait until the SW1 button has been released for at least 128 contiguous counts of timer 0. If you set TMR0 prescaler right in the OPTION_REG register you can make that a nice debounce time of 20mS to 50mS.
     
    Last edited: Aug 7, 2011
  17. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    Great insight about the voltage. Ernie also told me to change that and when I got it working it was fine. And yea I need debouncing.
     
  18. stahta01

    Member

    Jun 9, 2011
    133
    21
    Code ( (Unknown Language)):
    1.  
    2. #define SW1            GPIO,3            ; toggle switch at GPIO 3
    3. #define SW2            GPIO,2             ; toggle switch at GPIO 2
    4.  
    Did you all see how SW1 and SW2 are defined; I guessing this NOT what is normally done or expected.

    Edit: The "movlw SW1" becomes "movlw GPIO,3" which, I guess, should not assemble.

    This is more common in the small amount of code I have read; note putting comments after a define is not standard practice, I am not sure if it is a safe idea.
    Code ( (Unknown Language)):
    1.  
    2. #define SW1            GPIO3
    3. #define SW2            GPIO2
    4.  
    I am far from a PIC expert; so, use my advice with a little caution.

    Edit: If I recall correctly, movlw means move literal to w; so it will not work with either of above defines.

    Tim S.
     
    Last edited: Aug 8, 2011
  19. peter_morley

    Thread Starter Member

    Mar 12, 2011
    179
    0
    It's working fine declared as GPIO,3 or GPIO,2.
     
Loading...