How to get two buttons to work with the 16f628a - C, Hi-tech comp, mplabx

Discussion in 'Programmer's Corner' started by Bjornk, Jan 29, 2013.

  1. Bjornk

    Thread Starter New Member

    Jan 28, 2013

    I'm just began exploring my new hobby - mcu electronics. I have bought an 16f628a after reading some forumposts suggestion that is a good mcu for beginners. I have download mplabX, the hi-tech compiler and the isis program for simulating my circuit and code.
    I have some knowledge from c# and java development, so I like working with their "mother language" C. I have allready created the "hello world" and "blinking led" project.

    Now I want to add two buttons to my blinking led prosject (one for each led. One pin for each led and one pin for each button, everthing happening programmatically), I have been searching the Internet and found some examples and tutorials but not any that I got to work.

    If any got some links to tutorials / examples, code snippets with schematics or anything else that will help me create this I would appreciate it. I can post my blinking led code and schematics if that would help. thanks
  2. MrChips


    Oct 2, 2009
    I know this is too trivial for you but maybe you need to explain your problem a bit more clearly.

    pseudo code:

    if (button pressed)
    led on
    led off
  3. t06afre

    AAC Fanatic!

    May 11, 2009
    As a PIC programmer, you should take your time. To browse your you PIC header file <pic16f628a.h> Here you will see that many single bits in the register file are defined. As an example this is for PORTB
    Code ( (Unknown Language)):
    1. // Register: PORTB
    2. volatile unsigned char           PORTB               @ 0x006;
    3. // bit and bitfield definitions
    4. volatile bit RB0                 @ ((unsigned)&PORTB*8)+0;
    5. volatile bit RB1                 @ ((unsigned)&PORTB*8)+1;
    6. volatile bit RB2                 @ ((unsigned)&PORTB*8)+2;
    7. volatile bit RB3                 @ ((unsigned)&PORTB*8)+3;
    8. volatile bit RB4                 @ ((unsigned)&PORTB*8)+4;
    9. volatile bit RB5                 @ ((unsigned)&PORTB*8)+5;
    10. volatile bit RB6                 @ ((unsigned)&PORTB*8)+6;
    11. volatile bit RB7                 @ ((unsigned)&PORTB*8)+7;
    12. #ifndef _LIB_BUILD
    13. volatile union {
    14.     struct {
    15.         unsigned RB0                 : 1;
    16.         unsigned RB1                 : 1;
    17.         unsigned RB2                 : 1;
    18.         unsigned RB3                 : 1;
    19.         unsigned RB4                 : 1;
    20.         unsigned RB5                 : 1;
    21.         unsigned RB6                 : 1;
    22.         unsigned RB7                 : 1;
    23.     };
    24. } PORTBbits @ 0x006;
    25. #endif
    It is perfectly OK to code like this in Hi-Tech C
    if(RB0) RB1=1;
    else RB1=0;
  4. takao21203

    Distinguished Member

    Apr 28, 2012
    If you'd have used assembler for a while you'd know it is bad discipline.

    If you can:

    Code ( (Unknown Language)):
    2. PORTBbits.RB1=0;
    3. if((PORTB&0x01)==0x01)PORTBbits.RB1=1;
    Note also the short forms for the port bits do no longer exist on 18F PICs.
  5. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    As you can already see, even a simple task as read a button and turn on a LED can get complicated. Here's the steps you need to do:

    1) define what a button down looks like. Note it may be a high or may be a low when pressed. And one day you will also need to know it has stopped bouncing (but that's for another day).

    2) Define what it takes to turn on a LED. Again, note it may be a high or may be a low that turns on a LED.

    3) adjust the direction of the I/O pins so the buttons go to inputs and the LEDs to outputs.

    Additionally, check if anything else can interfere with the digital pin function, such as an analog function, or some other digital function. Do note that pins with an analog function default to analog when the power is applied. (I hate that too, but it must be so if the pin is to ever work effectively as an analog pin.)

    4) Use the definition from #3 once to set the pin directions.

    5) Make a loop to read the button inputs and drive the LED outputs.

    Code ( (Unknown Language)):
    2. #include <htc.h>    // brings in specific definitions for this PIC
    4. #define LED_ON      1       // LED is connected cathode to ground
    5. #define LED_OFF     0
    7. #define BUTTON_ON   0       // Button input is low when button pressed
    8. #define BUTTON_OFF  1       // (this is how a pull-up resistor button works)
    10. #define I_O_OUT     0       // standard TRIS definitions
    11. #define I_O_IN      1       // zero is 0ut, one is 1n
    13. #define SW_A        RB0     // switch A is on PORTB.0
    14. #define SW_B        RB1
    15. #define SW_A_TRIS   TRISB0  // switch B is on PORTB.1
    16. #define SW_B_TRIS   TRISB1
    18. #define LED_A       RB2     // LED A is on PORTB.2
    19. #define LED_B       RB3     // LED B is on PORTB.3
    20. #define LED_A_TRIS  TRISB2
    21. #define LED_B_TRIS  TRISB3
    23. void main(void)
    24. {
    25.   SW_A_TRIS  = I_O_IN;    // set up I/O pin directions
    26.   SW_B_TRIS  = I_O_IN;
    27.   LED_A_TRIS = I_O_OUT;
    28.   LED_B_TRIS = I_O_OUT;
    30.   // now loop forever to sense buttons
    31.   while(1)
    32.   {
    33.     if (SW_A == BUTTON_ON) // test the first switch
    34.       LED_A = LED_ON;
    35.     else
    36.       LED_A = LED_OFF;
    38.     if (SW_B == BUTTON_ON) // test the second switch
    39.       LED_B = LED_ON;
    40.     else
    41.       LED_B = LED_OFF;
    43.   }
    44. }
    If you use #define statements as this to define your hardware your code becomes self-documenting. "if (SW_B == BUTTON_ON)" has much more meaning then "(RB0 == 0)"

    And should you change compilers and find the defines you used are no longer defined, you can just change your definitions to suit.

    In Microchip examples these defines get grouped together into a file called "HardwareProfile.h" that many code modules can share to know what the hardware looks like.

    Finally, a little C magic: the ?: operator. It's a little obscure but very handy for simple if/then/else decisions like this. The while loop can be replaced by these two lines:

    Code ( (Unknown Language)):
    2.     LED_A = (SW_A == BUTTON_ON) ? LED_ON : LED_OFF;   // test the first switch
    3.     LED_B = (SW_B == BUTTON_ON) ? LED_ON : LED_OFF;   // test the second switch
    Last edited: Jan 30, 2013
    Bjornk likes this.