DELAY and DISPLAY in microcontroller programming

Discussion in 'Embedded Systems and Microcontrollers' started by mailus, Jul 13, 2013.

  1. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    i have difficulty in programming with delays and 7 segment display routines;
    now my doubt is,

    i have data(in bytes) in a variable, i need to check the location of bit(from byte mentioned) which is zero. then i need to display in a single seven segment display(1~8). here i use for loop and bit manipulation function to find the location,on the same time i need to display which location is zero.for this i use delay function in for loop.how to avoid this delay function in for loop and the same time display the output

    i put my code here:
    Code ( (Unknown Language)):
    1.  
    2. #include <16f877a.h>
    3. #fuses HS,PUT,NOWDT,NOPROTECT,NOBROWNOUT
    4.  
    5. #use delay(clock=4000000)
    6.  
    7. #define crystal 4000000
    8. #define time 750
    9. #define relay_time 500
    10. #define debounce 50
    11.  
    12.  
    13. unsigned int8 curr_ipt=0xff,i,sli=0,temp=0;
    14. int1 rd_ipt=1;
    15.  
    16.  
    17.  
    18. int conv(unsigned int8 data)           //function with return value
    19. {
    20.    switch(data)                        //return the converted data to display in the 7-segment
    21.    {
    22.       case 1:
    23.          return(0xf9);
    24.          break;
    25.       case 2:
    26.          return(0xa4);
    27.          break;
    28.       case 3:
    29.          return(0xb0);
    30.          break;
    31.       case 4:
    32.          return(0x99);
    33.          break;
    34.       case 5:
    35.          return(0x92);
    36.          break;
    37.       case 6:
    38.          return(0x82);
    39.          break;
    40.       case 7:
    41.          return(0xf8);
    42.          break;
    43.       case 8:
    44.          return(0x80);
    45.          break;
    46.       case 9:
    47.          return(0x90);
    48.          break;
    49.       default:
    50.          return(0xff);
    51.          break;
    52.  
    53.     }
    54.  
    55. }
    56.  
    57.  
    58. void output()
    59. {
    60.    if((curr_ipt==0xff) && sliver==1)        //if all pins in portc is high
    61.    {
    62.       output_low(pin_A1);  
    63.       output_low(pin_A2);
    64.       output_high(pin_A3); //relay,error_led signal are low and ready signal is high
    65.       delay_ms(relay_time);
    66.  
    67.    } else if((curr_ipt!=0xff) || sliver==0)    //any of the input is low
    68.    {
    69.       rd_ipt=0;
    70.       output_high(pin_A1);  
    71.       output_high(pin_A2);
    72.       output_low(pin_A3);     //relay,error_led signal are high and ready signal is low
    73.       delay_ms(relay_time);
    74.    }
    75.  
    76. }
    77.  
    78.  
    79.  
    80.  
    81. void display()
    82. {
    83.    if(curr_ipt!=0xff)         //check input if any change enter loop
    84.    {
    85.       for(i=0;i<=7;i++)
    86.       {
    87.          if((curr_ipt &(1<<i))==0)     //for each value of i bit location is change to ith location
    88.          {                              //if any particular bit is zero means enter  
    89.             delay_ms(debounce);        //debounce time
    90.             if((curr_ipt &(1<<i))==0)  //check again if still bit 0
    91.             {
    92.             temp=i;                    //save the location i in temp variable
    93.             output_B(conv(temp+1));    //call function "conv" and display in the portB
    94.             delay_ms(time);            //time for display the content
    95.             }
    96.          }
    97.       }
    98.    }
    99.  
    100.    if(sli==0)                       //if sli input is zero means enter here
    101.    {
    102.       delay_ms(debounce);              //debounce time
    103.       if(sli==0)                      //check again still input is zero enter
    104.       {
    105.       output_b((conv(9)));             //call fn"conv" and display digit '9' on display
    106.       delay_ms(time);
    107.       }
    108.    }
    109.    if((curr_ipt==0xff) && sli==1)     //if all inputs are high display empty
    110.    {
    111.       output_b((conv(0)));
    112.    }
    113.  
    114. }
    115.  
    116.  
    117. void main()
    118. {
    119.    while(TRUE)
    120.    {
    121.       start:
    122.       if(rd_ipt==1)        //read port when rd_ipt is enabled
    123.       {
    124.          curr_ipt=input_c();   //assign port c value to variable curr_ipt
    125.          sli=input(pin_a0);
    126.       }
    127.       output();               //call output function
    128.       display();              //call display function
    129.       if(input(pin_A5))
    130.       {
    131.       delay_ms(20);
    132.       if(input(pin_A5))
    133.       {
    134.         rd_ipt=1;
    135.         goto start;
    136.         output_high(pin_E0);
    137.       }
    138.       }
    139.    }
    140.  
    141. }
    142.  
    problems in my code:

    "The goto and continue keywords shall not be used. The break keyword shall not be used outside
    of a switch statement. These keywords lead to spaghetti code."

    "i have implemented delay in a closed loop so it make my code to too lazy one,so controller wait some time until the closed loop has to complete"



    so i keep on searching i found that RTOS concept.
    that means time slicing or time slot method by using cooperative tasking and round-robin technique.is this technique suitable for my problem?

    please give some solution to solve this problem
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,364
    Your code is riddled with problems. You have not learned the concepts of Structured Programming.
    It is best to begin by drawing flow charts.

    1) Your conv( ) routine is wrong. You have input and output interchanged.
    You don't need to use a switch/case structure.

    2) Your output( ) routine is flawed.
    Use a single if-then-else structure.
    sliver is not declared.
    Pass parameters in the function call.

    3) Your display( ) routine is flawed.
    Draw a flowchart.

    4) Your main( ) routine is flawed.
    Draw a flowchart.
    output_high( ) is never reached.

    You don't need RTOS.
     
    mailus likes this.
  3. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    Thank you for point out my problem.
    yes, i am a beginner in microcontroller programming.


    please suggest some books to learn these concepts.
    (Structured Programming,flow chart design & etc.,)
     
  4. MrChips

    Moderator

    Oct 2, 2009
    12,449
    3,364
    Did you Google Structured Programming?
     
  5. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    yes, but i did not find exact one to learn,,,i am still trying.......
     
  6. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    i found some good tutorials
     
  7. blueroomelectronics

    AAC Fanatic!

    Jul 22, 2007
    1,758
    98
    I started learning C just over a month ago. I'm using MPLABX & XC8 and I'm enjoying it immensely.

    What tutorials are you using?
     
  8. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    i am using some books(Programming 8-bit PIC Microcontrollers in C ,The C Programming Language - Ritchie Kernighan).
     
  9. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    what type of tutorials you have?
    please post the tutorials....then i will also enjoy the programming........
     
  10. blueroomelectronics

    AAC Fanatic!

    Jul 22, 2007
    1,758
    98
    Actually the same books, the Microchip forums and the XC8 manual. Of course the MPLAB simulator and my old Junebug kits are very handy.
     
  11. donpetru

    Active Member

    Nov 14, 2008
    186
    25
    What do you do with the above software? I mean, what circuit? I ask this because it's not enough to show only the code.
     
  12. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    i working on a industrial device.
    my requirements are
    1) i have totally 9 sensor inputs and one reset button input.
    when any one of the input pin (or combination of any pin at a same time) falls to zero means the device produce a indication and energize a relay and stop checking the input.
    2) at the same time i want to show that particular pin input is fail.so i use a single 7 segment LED to display.(for more than one input fail the display show the digit for one second and show the other digits likewise)
    3) if reset button is pressed the display check the current status of input.if error exist follow step-1 and step-2 otherwise display will blank and relay de-energize
     
  13. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    can you suggest some ideas about this?????
     
  14. donpetru

    Active Member

    Nov 14, 2008
    186
    25
    @mailus, now, after last post of yours, I understand much better.
    In this application use one common cathode or anod 7-seg. display ?

    First, in your code I don't see any program line declaring input and output pins. That would be a first mistake.

    For example, you use:
    Code ( (Unknown Language)):
    1. int conv(unsigned int8 data)           //function with return value
    2. {    switch(data)                        //return the converted data to display in the 7-segment
    3.    {      
    4. case 1:          return(0xf9);          break;      
    5. case 2:          return(0xa4);          break;      
    6. case 3:          return(0xb0);          break;      
    7. case 4:          return(0x99);          break;
    8.       case 5:          return(0x92);          break;      
    9. case 6:          return(0x82);          break;
    10. case 7:          return(0xf8);          break;      
    11. case 8:          return(0x80);          break;      
    12. case 9:          return(0x90);          break;      
    13. default:          return(0xff);          break;
    14.      }
    15. }
    but the above code does not think it's good.

    Correct code, for example, for common cathode 7-segment displays is:
    Code ( (Unknown Language)):
    1. unsigned short mask(unsigned short num) {
    2.               switch (num) {
    3.                      case 0 : return 0x3F;
    4.                      case 1 : return 0x06;
    5.                      case 2 : return 0x5B;
    6.                      case 3 : return 0x4F;
    7.                      case 4 : return 0x66;
    8.                      case 5 : return 0x6D;
    9.                      case 6 : return 0x7D;
    10.                      case 7 : return 0x07;
    11.                      case 8 : return 0x7F;
    12.                      case 9 : return 0x6F;
    13.                           }
    14.                                              }
    Now, if you want to display a number from 0 to 9 on the display, just assign each input pin numbers from 0 to 9.

    Suppose we choose RA5 and RB0...7 as input port and port RC0...7 and RA0 as output (RA0 for relay de-energize). You have to write something like this (I use mikroC for PIC):
    Code ( (Unknown Language)):
    1. bit oldstate;       // Old state flag
    2.  
    3. void main() {
    4.   ANSELA = 0;                    // Configure PORTA pins as digital
    5.   ANSELB = 0;                    // Configure PORTB pins as digital
    6.   ANSELC = 0;                    // Configure PORTC pins as digital
    7.  
    8.   TRISB = 1;                     // set RB0...7 pins as input 1...8
    9.   TRISA5_bit = 1;                // set RA5 pin as input 9
    10.  
    11.   TRISA0_bit = 0;                // Configure RA0 as output for relay de-energize
    12.   LATA0_bit  = 0;                // Clear PORT RA0
    13.  
    14.   TRISC = 0;                     // Configure PORTC as output
    15.   LATC  = 0;                     // Clear PORTC
    16.  
    17.   do {
    18.  
    19.      for (i=0; i<=7; i++)
    20.         {
    21.                if (Button(&PORTB, i, 1, 1))                      // Detect logical one            
    22.                   {
    23.                      oldstate = 1;                               // Update flag
    24.                      if (oldstate && Button(&PORTB, i, 1, 0))    // Detect one-to-zero transition
    25.                                    {
    26.                                     TRISA0_bit = 1;  // turn off relay
    27.                                     num = i + 1;
    28.                      unsigned short mask(unsigned short num) {
    29.                                   switch (num) {
    30.                                          case 0 : return 0x3F;
    31.                                          case 1 : return 0x06;
    32.                                          case 2 : return 0x5B;
    33.                                          case 3 : return 0x4F;
    34.                                          case 4 : return 0x66;
    35.                                          case 5 : return 0x6D;
    36.                                          case 6 : return 0x7D;
    37.                                          case 7 : return 0x07;
    38.                                          case 8 : return 0x7F;
    39.                                          case 9 : return 0x6F;
    40.                                                 }
    41.                                                       }
    42.                                     LATC = num;
    43.                                     Delay_ms(2000);              // 2 second delay
    44.  
    45.                                     }  
    46.                   }
    47.         }
    48.  
    49.      if (Button(&PORTA, 5, 1, 1))                                 // Detect logical one            
    50.                   {
    51.                      oldstate = 1;                               // Update flag          
    52.                      if (oldstate && Button(&PORTA, 5, 1, 0))    // Detect one-to-zero transition
    53.                                    {
    54.                                     TRISA0_bit = 1;              // turn off relay
    55.                                     LATC = 0x6F;
    56.                                     Delay_ms(2000);              // 2 second delay
    57.                                    }  
    58.                   }
    59.  
    60.    } while(1);
    61. }
    I have not tested the code above, but can be a starting point.
     
    mailus likes this.
  15. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    I have one more doubt,

    in your program the delay is placed inside a closed loop.while execution the once program enters for loop it will not exit until the loop exit.so other function that is reset switch cannot be controlled.
     
  16. donpetru

    Active Member

    Nov 14, 2008
    186
    25
    Delay_ms of the instructions "if" from the main loop allows viewing of the display corresponding digit entry that fell. For example, if intput 5 falls to zero, then the display will show the number 5 for 2 seconds. Then repeat loop is recheck each entry and if input 5 is the problem ---> displays the number 5 only 2 seconds....
    This code can be polished according to how you want. As I said, it's just a small starting point.
     
  17. mailus

    Thread Starter New Member

    Jun 16, 2012
    19
    0
    ok thank you.....
     
Loading...