Menu

all about electronic and microcontrollers

Sunday, October 17, 2010

Lesson nr.12-Multiplexed 7Segment as counter mode

Hardware setup:
The basic technique is the same like the last lesson except fact that we have added a counter which counts between 0000 and 9999. Our counter increments with 1 second delay.
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.



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.12:
'          Multiplexed 7Segment as counter mode
'  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. Number is incremented for 1 second. 
'          To define this project, a counter is added (counts from 0000 to 9999).
'  Test configuration:
'    MCU:                        PIC16F628A
'    Test.Board:                 WB-106 Breadboard 2420 dots
'    SW:                         MikroC PRO for PIC 2010 (version v4.15)
'  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 > 8u)
 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
 PORTA = 0;                           // Turn off both displays
 TRISA = 0;                           // All port A pins are configured as outputs
 PORTB = 0;                           // Turn off all display segments
 TRISB = 0;                           // All port D pins are configured as outputs
 number = 0;                          //initial value;
 
 do {
     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;

     Delay_ms(1000);                  // 1s delay;

     number ++ ;                      //increment number;
     if (number > 9999u)
     number = 0;
     } while(1);                      //Endless loop;
 }                                    //End.

1 comment:

  1. Hi! For OPTION_REG = 0x80;
    Disable only NOT_RBPU, but don't enable TMR0, to enable TMR0, you must write : OPTION_REG = 0x07;

    thank you!
    marC:)

    ReplyDelete

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