Home > front end >  How to increment or decrement a 7-segment display 00-99 using button
How to increment or decrement a 7-segment display 00-99 using button

Time:12-10

i'm using code composer studio and data signals(D0-7) are obtained from tms320f28335 i have incremented and decremented specific led on 7-segment using switch statement. but that is kind if manual incrementing( where i already provide values as shown below)

   void display(void)
   {
    B1  =1;
    if(B1 > B1_lim) { B1 = 0; }

    switch(B1)
    {
     case  0:  Display[0] = 0xf7; break;  //9
     case 1:  Display[0] = 0xfF; break;   //8
     case 2:  Display[0] = 0xf0; break;   //7
     case 3:  Display[0] = 0x9F; break;
    }

i have also tried to run counter but it never comes out of the loop because of while(1) statement and then i cant use other buttons, the code is shown below it works for 00-99 with never ending. furthermore, i tried to use button in below code but it loops like button can just start the increment/decrement process

    void display(void)
    {
    unsigned char a[]={0xfb,0xb0,0xeD,0xf5,0xb6,0xd7,0x9F,0xf0,0xfF,0xf7}; //[0,1,2,3,4,5,6,7,8,9]
    unsigned char b[]={0xfb,0xb0,0xeD,0xf5,0xb6,0xd7,0x9F,0xf0,0xfF,0xf7}; //[0,1,2,3,4,5,6,7,8,9]
    int k,j;
     while(1)
       {
        Display[0] = 0xfb;
        Display[1] = 0xfb;
        DELAY_US(200000L);
        for(j=0;j<=9;j  )
        {
            Display[1]=b[j];
            led_display(0x00);    DELAY_US(200000L);
              for(k=0;k<=9;k  )
            {
                Display[0] = a[k];
                led_display(0x00);    DELAY_US(200000L);
                DELAY_US(2L);
            }
        }
    }
    }

on my 7-segment driver board, I have 4 buttons, and i want to use two of them for incrementing and decrementing. I would like to know if there is any logical way to use a switch statement such that for each button press I can increment or decrement. the simplest way show increment is shown in above code but i want to using second code.

CodePudding user response:

I think you should use interrupt for button, don't use while(1) in your function. Create a function to update value for 7-segment. When you press button, interrupt function will call. In this, you update your value to display.

CodePudding user response:

First of all you need a coherent design following the tight cohesion, loose coupling principles. Your display function is attempting to doo too much - it is not cohesive - it contains logic related to your specific application and unrelated to display. It should do only what its name suggests and display a desired value. For example:

void display( uint8_t value )
{
    //                              0    1    2    3    4    5    6    7    8    9
    static const uint8_t digits[]={0xfb,0xb0,0xeD,0xf5,0xb6,0xd7,0x9F,0xf0,0xfF,0xf7}; 
    if( value < 100 )
    {
        uint8_t display[2] = {0,0} ;
        display[0] = value % 10u ; // least significant digit
        display[1] = value / 10u ; // most significant digit
        led_display( 0x00 ) ;
    }
}

Then let's assume (because you have not told us) that you have some GPIO input for the button and a clock source, hypothetically I will call these getSwitchState() and getClockMillisec(), then you might have a button state function something like:

bool getButtonState()
{
    static const uint32_t DEBOUNCE_MILLIS = 20 ;
    static uint32_t timestamp = getClockMillisec() ;
    static bool debounced_button_state = getSwitchState() ;
    
    uint32_t now = getClockMillisec() ;
    uint32_t button_state = getSwitchState() ;
    
    if( now - timestamp > DEBOUNCE_MILLIS &&
        button_state != debounced_button_state )
    {
        debounced_button_state = button_state ;
        timestamp = now ;
    }
    
    return debounced_button_state ;
}

Then you will want to act only on a button change of state, so you might have:

bool isButtonDownEvent()
{
    static bool button_state = getButtonState() ;
    bool button_down_event = false ;
    
    // On change of state
    if( getButtonState() != button_state )
    {
        button_state = !button_state ;
        
        // True if button change was released to pressed (down event)
        button_down_event = button_state ; 
    }
    
    return button_down_event ;
}

Then your application loop can be built from those primitives thus:

uint8_t num = 0 ;

for(;;)
{
    display( num ) ;
    if( isButtonDownEvent() )
    {
        num   ;
        num %= 99 ;
    }
}

Clearly if you have more than one button for separate increment/decrement that will need some modification to handle separate buttons, but since you have provided no information on the button hardware or software interface to it, I'll leave that to you to consider.

Also of course that is not the only possible solution to button input and debounce - you may already have suitable code. Usefully perhaps this method does not need a dedicated h/w timer or interrupt. It does however require regular polling to avoid missing events.

Critically note that the solution has no delays and no blocking, you can do other useful work in the loop whilst maintaining the display (so long as that too is non-blocking and does not take excessive CPU time such that button events might be missed.

  • Related