Menu

all about electronic and microcontrollers

Sunday, October 17, 2010

Lesson nr.13-7Segment and Push Button

Hardware setup:
Today Lesson is different from the last one, by the presence of two buttons and manually increment .
All 7-segment displays are connected to PORTB (RB0..RB7, segment A to RB0, segment B to RB1, etc.) with refresh via pins RA0..RA3 on PORTA.
If button on RA6 is presed the current number will be incremented by "1" and if button on RA7 is pressed the current number will be decremented by "1". Minimum number is 0000 and maximum number is 9999.



Circuit Diagram:
For those who want to build it on their own breadboard or other platform, here is the electronic scheme built in Eagle Cad, free version:



Software:
Here is the C program written for MikroC PRO for PIC 2010 (version v4.15).
/*
'*******************************************************************************
'  Lesson nr.13:
'          Push Button & 7 Segment Display
'  Done by:
'          Aureliu Raducu Macovei, 2010.
'  Description:
'          This code demonstrates  displaying number on four 7-segment display (common
'          cathode), in multiplex mode. All 7-segment displays are connected to PORTB
'          (RB0..RB7, segment A to RB0, segment B to RB1, etc.) with refresh via pins
'          RA0..RA3 on PORTA. If button on RA6 is presed the current number will be
'          incremented by "1" and if button on RA7 is pressed the current number will
'          be decremented by "1".
'
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         mikroC PRO for PIC
'  Configuration Word
'    Oscillator:                 INTOSC:I/O on RA.6, I/O on RA.7
'    Watchdog Timer:             OFF
'    Power up Timer:             Disabled
'    Master Clear Enable:        Enabled
'    Browun Out Detect:          Enabled
'    Low Voltage Program:        Disabled
'    Data EE Read Protect:       Disabled
'    Code Protect:               OFF
'*******************************************************************************
*/
//***********Header*************/
unsigned short mask(unsigned short num)
{
 switch (num) 
 {
  case 0 : return 0x3F;
  case 1 : return 0x06;
  case 2 : return 0x5B;
  case 3 : return 0x4F;
  case 4 : return 0x66;
  case 5 : return 0x6D;
  case 6 : return 0x7D;
  case 7 : return 0x07;
  case 8 : return 0x7F;
  case 9 : return 0x6F;
  }
}
/*******Endless mask***********/
unsigned short shifter, portb_index;
unsigned int digit, number;
unsigned short portb_array[4];

void interrupt()
{
 PORTA = 0;                           // Turn off all 7seg. displays;
 PORTB = portb_array[portb_index];    // Bring appropriate value to PORTB;
 PORTA = shifter;                     // Turn on appropriate 7seg. display;

 //move shifter to next digit;
 shifter <<= 1;
 if(shifter > 15u)
 shifter = 1;

 //increment portb_index;
 portb_index ++ ;
 if (portb_index > 3u)
 portb_index = 0;                     //turn on 1st, turn off 2nd 7 seg.;
 TMR0 = 0;                            //reset TIMER0 value;
 INTCON = 0x20;                       //clear T0IF, Bit T0IF=0, T0IE=1;
 }

void main()
{
 CMCON |= 7;                          // Set AN pins to Digital I/O;
 OPTION_REG = 0x80;                   // Set timer TMR0;
 digit = 0;
 portb_index = 0;
 shifter = 1;
 TMR0 = 0;
 INTCON = 0xA0;                       // Disable interrupt PEIE,INTE,RBIE,T0IE
 TRISA = 0;
 TRISA6_bit = 1;
 TRISA7_bit = 1;                      // All port A pins are configured as outputs
 PORTA = 0;                           // Turn off displays
 TRISB = 0;                           // All port D pins are configured as outputs
 PORTB = 0;                           // Turn off all display segments
 
 number = 0;                          //initial value;
 
 do {
     if(Button(&PORTA,6,1,0)){
                              Delay_ms(200);
                              digit++ ;
                              number = number +1;
                              PORTB = number;
                              }
     if(Button(&PORTA,7,1,0)){
                              Delay_ms(200);
                              digit = digit -1;
                              number = number -1;
                              PORTB = number;
                              }
     if (number > 9999u)
     number = 0;

     digit = number % 10u;            //extract ones digit;
     portb_array[0] = mask(digit);    //and store it to PORTB array;
     digit = (number / 10u) % 10u;    //extract tens digit;
     portb_array[1] = mask(digit);    //and store it to PORTB array;
     digit = (number / 100u) % 10u;   //extract hundreds digit;
     portb_array[2] = mask(digit);    //and store it to PORTB array;
     digit = number / 1000u;          //extract thousands digit;
     portb_array[3] = mask(digit);    //and store it to PORTB array;
     } while(1);                      //Endless loop;
}                                     //End.

5 comments:

  1. Hi Radu, I am Harsha from India i recently learnt and did the 7Segment and Push Button from www.electronicexperiments.com.And now i want to add an extra feature to the existing 7Segment and Push Button experiment. The additional feature i want to add is the 7 segment should hold the count value even if the power supply is turned off and turned on,but it should reset only if the reset button is pressed .I understand that i can use the internal eeprom in 16f628a.But i need some help in program flow which i need to use.I would like to know if you could help me out in writing the program that would implement the above mentioned feature.Looking forward for your reply. Regards Harsha

    ReplyDelete
  2. Dear Ducu,

    Hi and Happy New Year 2016 in advance.

    I also wish to thank you so much for this awesome project and your wonderful site. Really nice job you are doing here. Keep it up please.

    I have a project that needs two separate 2 digits manual up/down counters. Is it possible to turn this project into that? I tried and it is filing as two separate digits. 4 digits are Ok.
    I can send you the MikroC and Proteus files in you needed to see them.

    Much appreciated in advance.

    massam

    ReplyDelete
  3. Sorry, about, uC PRO PIC + " portb_array[0] = mask(digit);" there was a small mistake, it's working now, thank you

    ReplyDelete
  4. please,
    I found the design of this digital counter incredible. I'm trying on the arduino UNO, but in the compilation it presents some errors, can you help me ???
    My best regards to everyone

    ReplyDelete
  5. Hi Ducu, you did a great job. I`m having same trouble with this exercise. Could you tell me the clock frequecy? My uC pro is 7.2 version.

    ReplyDelete

If you do not understand something, or if you make some aplication helped by this blog, let me know.