Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] 7 Segment Code issues

Status
Not open for further replies.

junkie_

Junior Member level 2
Junior Member level 2
Joined
Oct 9, 2005
Messages
24
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,477
Hello board:

I am sort of returning and relearning C for PIC, I visited gooligum, downloaded the tutorial and code for 7 segement multiplexing.

I have tried to modify the code for Common Anode, and PIC16F877A instead of 16F506 (both common cathode and PIC16F506 are not available at my place)

It seems there is something wrong with the code, I am attaching Proteus .dsn file, along c code and the .cof and .hex file, I 'll be greatful once again to this community of nice people.

BTW: forgot to mention the code is in XC8
 

Attachments

  • My Experiment.rar
    34.9 KB · Views: 131

Re: 7 Segment Code issues - Help requested

If you wish, you can also turn a common cathode display into a common anode type...

By attaching inverter gates to all 7 segments, as well as each digit's activation wire.
 

Re: 7 Segment Code issues - Help requested

Brad:
you mean something like CD4049?
This could be an option but 7 segments plus 3 anodes, that 'll be 10 gates or two CD4049. I think it would complicate the circuitary.

But thanks anyway, I'll keep it in mind.

Appreciate if any one could evaluate the code?
 

Re: 7 Segment Code issues - Help requested

This should get you going, much easier code although it is in C18 intended for PIC18F4520 but could easily be ported to others.

**broken link removed**
 
Re: 7 Segment Code issues - Help requested

abidr thanks a lot for providing the link, this is a very helpful link.
However, I am still having trouble, I cannot seem to make this code work for PIC16F876A or PIC18F2550, can anyone please help in porting the code to PIC16F876A.

Here is the code.
Code:
//
// Designed by www.MCUExamples.com
// rasika0612@gmail.com
// http://www.mcuexamples.com/PIC-Seven-Segment-Displays.php
// Using seven segments, multiplexed mode with 4 seven segment display units
// Timer2 used with interrupt to generate 10mS intervals
// Program will count seconds from 0 to 9999 and roll back
//
//#include <htc.h>
#include <p18f4520.h>

#pragma config OSC 		=	HS 	// 20MHz Crystal, (HS oscillator)
#pragma config PBADEN	=	OFF // PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config WDT 		=	OFF // watch dog timer off
#pragma config LVP 		=	OFF // Low voltage program off

#define SegmentPORT PORTD  // Seven segment LEDS connected to PORTD
#define SEG1 PORTBbits.RB0 // define common pins for each seven segment unit
#define SEG2 PORTBbits.RB1
#define SEG3 PORTBbits.RB2
#define SEG4 PORTBbits.RB3


void InterruptHandlerLow ();
void init_Timer2(void);
void DisplayDigit(unsigned char digit);

unsigned char Segments[4]={0,0,0,0}; // initial values of 4 segments are zeros
unsigned char next_segment=0; //We will start with segment1
unsigned char ticks_10mS=0;

//7Segment LED patterns for digits 0 to 9
							/*  0	 1 	  2    3	4	 5	  6	   7	8	 9  */
unsigned char Value2Pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98}; 

void main()
{	
	unsigned int number=0,temp;
	TRISD=0;    //make PORTD all out put
	TRISB=0xf0; //make PORTB pins 0:4 o/p and others input( we need only 0:4 pins)
	
	init_Timer2(); //init timer2

	while (1) // count seconds from 0 to 9999 and roll back to 0
	{
		if(ticks_10mS==100)
		{
			ticks_10mS=0; //Start from zero again			
			if(number<9999)
				number++;
			else
				number=0;
			
			Segments[0]=number/1000; // gets 1000's value of number to Segments[0]
			temp=number%1000;
			Segments[1]=temp/100;	 // gets 100's of number value to Segments[1]
			temp=temp%100;
			Segments[2]=temp/10;	// gets 10's value of number to Segments[2]
			Segments[3]=temp%10;	// gets 1's value of number to Segments[3]				
		}	
	}
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow //jump to interrupt routine
  _endasm
}

//----------------------------------------------------------------------------
//----------------Low priority interrupt routine------------------------------

#pragma code
#pragma interrupt InterruptHandlerLow

void InterruptHandlerLow ()
{
	if(PIR1bits.TMR2IF==1)    //is this interrupr is due to Timer2 
	{ //Yes this is due to timer2
		PIR1bits.TMR2IF	= 0;  // We must clear timer2 int flag by software, sodoing it here
		DisplayDigit(next_segment++); // call seven segment handler which will display digits
		ticks_10mS++;	 // we count 10mS units so that we know when ticks_10mS reach 100 we have 1S time
	}
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

void init_Timer2(void)
{
	PR2=223; // with 20Mhz Crystal, this value will generate 9.99mS interrupts
	T2CON=0b01101110; //Turn on timer2 with 1:14 post scale and 1:16 prescale
	
	/*Configure interrupt for Timer2 module*/
	RCONbits.IPEN=1;  //Enable interrupt priority levels
	IPR1bits.TMR2IP=0;//Enable interrupt priority levels for Timer2 module with low priority to timer2
	PIE1bits.TMR2IE=1;//Enable Interrupt for Timer2 Module
	INTCONbits.GIEL=1;//Enable global interrupts
	INTCONbits.GIEH=1;//Enable global interrupts
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

// Seven segment display handler function
// this function takes seven segment number to display as parameter (1 to 4 for this example)
// then will take appropiate number to display from array Segments[]
// Segments[] array has four elements which represents each segment and can have numer 0 to 9
// This function uses Value2Pattern array to resolve 
// 7segment display pattern for given number with in 0 to 9

void DisplayDigit(unsigned char digit)
{
	switch (digit)
	{
		case 0:
				SEG4=0;// turn off last segment
				SEG1=1;// turn on this segment
				break;
		case 1:
				SEG1=0;// turn off last segment
				SEG2=1;// turn on this segment
				break;
		case 2:
				SEG2=0;
				SEG3=1;
				break;
		case 3:
				SEG3=0;
				SEG4=1;
				break;
	}

	/*now we have selected correct seven segment unit for this turn*/
	SegmentPORT=Value2Pattern[Segments[digit]];//Display respective digit pattern
	
	if(digit==3)//If we displayed on 7segment unit 4 we have to reset next_segment counter to start over
		next_segment=0;
}
 

Re: 7 Segment Code issues - Help requested

I think your skills are too rusty at the moment: LOL

open a windows command prompt and type the following

Code:
mcc18 -p18f2550 --help-config

note down the configuration settings

then do the same for 18F4520

you'll note the difference between the config setting of both.
for the scope of this project I think TMR and INT settings are the same for both 18F mcus.
You should however change the code from:

Code:
#define SegmentPORT PORTD  // Seven segment LEDS connected to PORTD
#define SEG1 PORTBbits.RB0 // define common pins for each seven segment unit
#define SEG2 PORTBbits.RB1
#define SEG3 PORTBbits.RB2
#define SEG4 PORTBbits.RB3
to

Code:
#define SegmentPORT PORTB  // Seven segment LEDS connected to PORTB
#define SEG1 PORTAbits.RA0 // define common pins for each seven segment unit
#define SEG2 PORTAbits.RA1
#define SEG3 PORTAbits.RA2
#define SEG4 PORTAbits.RA3

I have selected PORT B because of the fact that there is no PORT D on 18F2550 and PORT C is only 7 bits, also set the TRIS registers accordingly. I suggest to change "OSC" to "FOSC" for 18F2550.
I am sure the code will now compile without any issues, as for porting to 16F87xA, hopefully someone else in this community will be able to help.
 
Re: 7 Segment Code issues - Help requested

That was fast abidr, thanks a lot, can someone else please help to port this code to PIC16F87xA?
 

Re: 7 Segment Code issues - Help requested

Jayanth:

Thanks a lot appreciate your support, here is the code:

Code:
//
// Designed by www.MCUExamples.com
// rasika0612@gmail.com
// http://www.mcuexamples.com/PIC-Seven-Segment-Displays.php
// Using seven segments, multiplexed mode with 4 seven segment display units
// Timer2 used with interrupt to generate 10mS intervals
// Program will count seconds from 0 to 9999 and roll back
//

//For PIC18F4520 
//#pragma config OSC = HS
#pragma config FOSC 		=	HS 	// 20MHz Crystal, (HS oscillator) this is for PIC18Fx550
//#pragma config PBADEN   =	OFF // PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config WDT 		=	OFF // watch dog timer off
#pragma config LVP 		=	OFF // Low voltage program off

#define SegmentPORT PORTB  // Seven segment LEDS connected to PORTB
#define SEG1 PORTAbits.RA0 // define common pins for each seven segment unit
#define SEG2 PORTAbits.RA1
#define SEG3 PORTAbits.RA2
#define SEG4 PORTAbits.RA3


void InterruptHandlerLow ();
void init_Timer2(void);
void DisplayDigit(unsigned char digit);

unsigned char Segments[4]={0,0,0,0}; // initial values of 4 segments are zeros
unsigned char next_segment=0; //We will start with segment1
unsigned char ticks_10mS=0;

//7Segment LED patterns for digits 0 to 9
							/*  0	 1 	  2    3	4	 5	  6	   7	8	 9  */
unsigned char Value2Pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98}; 

void main()
{	
	unsigned int number=0,temp;
	TRISB=0;    //make PORTB all out put
	TRISA=0; //make PORTA all outputs
	
	init_Timer2(); //init timer2

	while (1) // count seconds from 0 to 9999 and roll back to 0
	{
		if(ticks_10mS==100)
		{
			ticks_10mS=0; //Start from zero again			
			if(number<9999)
				number++;
			else
				number=0;
			
			Segments[0]=number/1000; // gets 1000's value of number to Segments[0]
			temp=number%1000;
			Segments[1]=temp/100;	 // gets 100's of number value to Segments[1]
			temp=temp%100;
			Segments[2]=temp/10;	// gets 10's value of number to Segments[2]
			Segments[3]=temp%10;	// gets 1's value of number to Segments[3]				
		}	
	}
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow //jump to interrupt routine
  _endasm
}

//----------------------------------------------------------------------------
//----------------Low priority interrupt routine------------------------------

#pragma code
#pragma interrupt InterruptHandlerLow

void InterruptHandlerLow ()
{
	if(PIR1bits.TMR2IF==1)    //is this interrupr is due to Timer2 
	{ //Yes this is due to timer2
		PIR1bits.TMR2IF	= 0;  // We must clear timer2 int flag by software, sodoing it here
		DisplayDigit(next_segment++); // call seven segment handler which will display digits
		ticks_10mS++;	 // we count 10mS units so that we know when ticks_10mS reach 100 we have 1S time
	}
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

void init_Timer2(void)
{
	PR2=223; // with 20Mhz Crystal, this value will generate 9.99mS interrupts
	T2CON=0b01101110; //Turn on timer2 with 1:14 post scale and 1:16 prescale
	
	/*Configure interrupt for Timer2 module*/
	RCONbits.IPEN=1;  //Enable interrupt priority levels
	IPR1bits.TMR2IP=0;//Enable interrupt priority levels for Timer2 module with low priority to timer2
	PIE1bits.TMR2IE=1;//Enable Interrupt for Timer2 Module
	INTCONbits.GIEL=1;//Enable global interrupts
	INTCONbits.GIEH=1;//Enable global interrupts
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

// Seven segment display handler function
// this function takes seven segment number to display as parameter (1 to 4 for this example)
// then will take appropiate number to display from array Segments[]
// Segments[] array has four elements which represents each segment and can have numer 0 to 9
// This function uses Value2Pattern array to resolve 
// 7segment display pattern for given number with in 0 to 9

void DisplayDigit(unsigned char digit)
{
	switch (digit)
	{
		case 0:
				SEG4=0;// turn off last segment
				SEG1=1;// turn on this segment
				break;
		case 1:
				SEG1=0;// turn off last segment
				SEG2=1;// turn on this segment
				break;
		case 2:
				SEG2=0;
				SEG3=1;
				break;
		case 3:
				SEG3=0;
				SEG4=1;
				break;
	}

	/*now we have selected correct seven segment unit for this turn*/
	SegmentPORT=Value2Pattern[Segments[digit]];//Display respective digit pattern
	
	if(digit==3)//If we displayed on 7segment unit 4 we have to reset next_segment counter to start over
		next_segment=0;
}
 

Re: 7 Segment Code issues - Help requested

Jayanth:

thanks again, mikro is good one but if you'd be kind enough to make it for XC8.
 

Re: 7 Segment Code issues - Help requested

This is not working... Maybe somebody can fix it. I guess ISR is not working. Code compiles fine in XC8.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <stdio.h>
#include <stdlib.h>
#include <pic16f877a.h>
 
#define _XTAL_FREQ 20000000
 
#pragma config FOSC =   HS  // 20MHz Crystal, (HS oscillator) this is for PIC18Fx550
#pragma config LVP  =   OFF     // Low voltage program off
 
#define SegmentPORT PORTB
#define SEG1 PORTDbits.RD0 
#define SEG2 PORTDbits.RD1
#define SEG3 PORTDbits.RD2
#define SEG4 PORTDbits.RD3
 
void InterruptHandlerLow ();
void InitTimer2 (void);
void DisplayDigit (unsigned char digit);
 
unsigned char Segments[4] = {0, 0, 0, 0};
unsigned char next_segment = 0; 
unsigned int step = 0;
 
//7Segment LED patterns for digits 0 to 9
/*                                0    1    2    3    4    5    6    7    8    9  */
unsigned char Value2Pattern[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
 
#pragma code InterruptVectorLow = 0x18
 
void InterruptVectorLow (void)
{
    #asm(goto InterruptHandlerLow)
    #endasm
   
}
 
#pragma code
#pragma interrupt InterruptHandlerLow
 
void InterruptHandlerLow ()
{
    if(PIR1bits.TMR2IF)
    {   PIR1bits.TMR2IF = 0;
        DisplayDigit(next_segment++);
                step++;
    }
}
 
//Timer2
//Prescaler 1:4; Postscaler 1:5; TMR2 Preload = 250; Actual Interrupt Time : 1.001 ms
void InitTimer2(void)
{
    T2CON = 0x25;
        PR2 = 250;
        PIE1bits.TMR2IE  = 1;
        INTCON = 0xC0;
}
 
void DisplayDigit(unsigned char digit)
{
    PORTD = PORTD  | 0x0F;
 
    SegmentPORT = Value2Pattern[Segments[digit]];
 
    switch (digit)
    {
        case 0:
            SEG1 = 0;
            break;
        case 1:
            SEG2 = 0;
            break;
        case 2:
            SEG3 = 0;
            break;
        case 3:
            SEG4 = 0;
            break;
    }
 
    if(digit == 3)next_segment = 0;
}
 
 
 
int main(int argc, char** argv) {
 
    unsigned int number = 0;
 
    TRISB = 0x00;
    TRISD = 0x00;
    PORTB = 0x00;
    PORTD = 0x00;
 
    InitTimer2(); 
 
    while (1) {
        
    if(step == 1000) {
            if(number < 9999)
        number++;
            else
        number = 0;
 
            Segments[0] = number / 1000;
            Segments[1] = (number / 100) % 10;
            Segments[2] = (number / 10) % 10;
            Segments[3] = number % 10;
            step = 0;
        }
 
         
 
        
    }
 
    return (EXIT_SUCCESS);
}

 

Attachments

  • mC 2.rar
    40.3 KB · Views: 126
  • mC.rar
    39.2 KB · Views: 109
Last edited:
Re: 7 Segment Code issues - Help requested

This same code (mikroC version) works just fine but don't know why XC8 version doesn't work.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* 
 * File:   main.c
 * Author: Jayanth Devarayanadurga
 *
 * Created on December 20, 2013, 8:11 PM
 */
 
#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#include <pic16f877a.h>
 
#define _XTAL_FREQ 20000000
 
#pragma config FOSC =   HS  // 20MHz Crystal, (HS oscillator) this is for PIC18Fx550
#pragma config LVP  =   OFF     // Low voltage program off
 
#define SegmentPORT PORTB
#define SEG1 PORTDbits.RD0 
#define SEG2 PORTDbits.RD1
#define SEG3 PORTDbits.RD2
#define SEG4 PORTDbits.RD3
 
void InitTimer2 (void);
void DisplayDigit (unsigned char digit);
 
unsigned char Segments[4] = {0, 0, 0, 0};
unsigned char next_segment = 0; 
unsigned int step = 0;
 
//7Segment LED patterns for digits 0 to 9
/*                                0    1    2    3    4    5    6    7    8    9  */
unsigned char Value2Pattern[] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98};
 
void interrupt isr (void)
{
    if(PIR1bits.TMR2IF)
    {
                DisplayDigit(next_segment);
                if(next_segment++ == 4)next_segment = 0;
                step++;
                PR2 = 250;
                PIR1bits.TMR2IF = 0;
    }
}
 
//Timer2
//Prescaler 1:4; Postscaler 1:5; TMR2 Preload = 250; Actual Interrupt Time : 1.001 ms
void InitTimer2(void)
{
    T2CON = 0x25;
        PR2 = 250;
        PIE1bits.TMR2IE  = 1;
        INTCON = 0xC0;
}
 
void DisplayDigit(unsigned char digit)
{
    PORTD |= 0x0F;
 
    SegmentPORT = Value2Pattern[Segments[digit]];
 
        switch (digit)
        {
                case 0:
                        SEG1 = 0;
                        break;
                case 1:
                        SEG2 = 0;
                        break;
                case 2:
                        SEG3 = 0;
                        break;
                case 3:
                        SEG4 = 0;
                        break;
        };
}
 
int main(int argc, char** argv) {
 
    unsigned int number = 0;
 
    TRISB = 0x00;
    TRISD = 0x00;
    PORTB = 0xFF;
    PORTD = 0x0F;
 
    InitTimer2();
 
    Segments[0] = number / 1000;
    Segments[1] = (number / 100) % 10;
    Segments[2] = (number / 10) % 10;
    Segments[3] = number % 10;
 
    while (1) {
 
        if(step == 1000) {
            if(number < 9999)
                number++;
            else
                number = 0;
 
            Segments[0] = number / 1000;
            Segments[1] = (number / 100) % 10;
            Segments[2] = (number / 10) % 10;
            Segments[3] = number % 10;
            step = 0;
        }
    }
 
    return (EXIT_SUCCESS);
}

 
Re: 7 Segment Code issues - Help requested

Jayanth:

you support is just unbelievable, you are of great help. Thanks a million.

XC8 is not working, but the MikroC one is working just fine.

Thanks again, & this solves my initial query and problem.
 

Re: 7 Segment Code issues - Help requested

Here is the working XC8 version. There is some ghost effect or maybe it is some other problem. WDT was resetting. I disabled it.
 

Attachments

  • 7Seg.X.rar
    73.3 KB · Views: 113
Re: 7 Segment Code issues - Help requested

Jayanth:

man you are unbelievable, exceptionally helpful.

Ok what I am trying to achieve is multiplex 7 segments, I found this tutorial on gooligum for 7 segment multiplexing. I edited to code, changed the mcu type, successfully compiled it but somehow I am still getting problems which are:
no multiplexing achieved.
digits giving incomplete display.

I know I am missing something very basic, would someone point out in the right direction, here's the code:

Code:
/************************************************************************
*                                                                       *
*   Filename:      BC_L5-Count_7seg_x3-HTC.c                            *
*   Date:          8/8/12                                               *
*   File Version:  1.5                                                  *
*                                                                       *
*   Author:        David Meiklejohn                                     *
*   Company:       Gooligum Electronics                                 *
*                                                                       *
*************************************************************************
*                                                                       *
*   Architecture:  Baseline PIC                                         *
*   Processor:     16F506                                               *
*   Compiler:      MPLAB XC8 v1.01 (Free mode)                          *
*                                                                       *
*************************************************************************
*                                                                       *
*   Files required: none                                                *
*                                                                       *
*************************************************************************
*                                                                       *
*   Description:    Lesson 5, example 2                                 *
*                                                                       *
*   Demonstrates use of multiplexing to drive multiple 7-seg displays   *
*                                                                       *
*   3-digit 7-segment LED display: 1 digit minutes, 2 digit seconds     *
*   counts in seconds 0:00 to 9:59 then repeats,                        *
*   with timing derived from int 4 MHz oscillator                       *
*                                                                       *
*************************************************************************
*                                                                       *
*   Pin assignments:                                                    *
*       RB0-1,RB4,RC1-4 = 7-segment display bus (common cathode)        *
*       RC5             = minutes enable (active high)                  *
*       RB5             = tens enable                                   *
*       RC0             = ones enable                                   *
*                                                                       *
************************************************************************/

#include <xc.h>
#include <stdint.h>


/***** CONFIGURATION *****/
// ext reset, no code protect, no watchdog, 4 MHz int clock
//__CONFIG(MCLRE_ON & CP_OFF & WDT_OFF & IOSCFS_OFF & OSC_IntRC_RB4EN);

// CONFIG
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = OFF        // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)
// Pin assignments
#define HOURS   PORTBbits.RB4
#define MINUTES PORTBbits.RB5   // minutes enable
#define TENS    PORTBbits.RB6   // tens enable
#define ONES    PORTBbits.RB7   // ones enable


/***** PROTOTYPES *****/
void set7seg(uint8_t digit);    // display digit on 7-segment display


/***** MACROS *****/
#define TMR0_2  (TMR0 & 1<<2)   // access to TMR0<2>


/***** MAIN PROGRAM *****/
void main()
{
    uint8_t     mpx_cnt;            // multiplex counter
    uint8_t     mins, secs;         // time counters
    
    //*** Initialisation
    
    // configure ports
    TRISB = 0;                      // configure PORTB and PORTC as all outputs
    TRISC = 0;
    ADCON0 = 0;                     // disable AN0, AN1, AN2 inputs
 //   CM1CON0bits.C1ON = 0;           //     and comparator 1 -> RB0,RB1 digital
 //   CM2CON0bits.C2ON = 0;           // disable comparator 2 -> RC1 digital
    
    // configure timer
    OPTION_REG = 0b11010111;            // configure Timer0:
             //--0-----                 timer mode (T0CS = 0) -> RC5 usable
             //----0---                 prescaler assigned to Timer0 (PSA = 0)
             //-----111                 prescale = 256 (PS = 111)
             //                         -> increment every 256 us
             //                            (TMR0<2> cycles every 2.048 ms) 

        
    //*** Main loop
    for (;;)
    {
        // count in seconds from 0:00 to 9:59
        for (mins = 0; mins < 10; mins++)
        {
            for (secs = 0; secs < 60; secs++)
            {
                // for each time count, multiplex display for 1 second
                // (display each of 3 digits for 2.048 ms each,
                //  so repeat 1000000/2048/3 times to make 1 second) 
                for (mpx_cnt = 0; mpx_cnt < 1000000/2048/3; mpx_cnt++)
                {
                    // display minutes for 2.048 ms
                    while (!TMR0_2)         // wait for TMR0<2> to go high
                        ;
                    set7seg(mins);          // output minutes digit
                    MINUTES = 1;            // enable minutes display
                    while (TMR0_2)          // wait for TMR0<2> to go low
                        ;
                        
                    // display tens for 2.048 ms
                    while (!TMR0_2)         // wait for TMR0<2> to go high
                        ;
                    set7seg(secs/10);       // output tens digit
                    TENS = 1;               // enable tens display
                    while (TMR0_2)          // wait for TMR0<2> to go low
                        ;
                        
                    // display ones for 2.048 ms
                    while (!TMR0_2)         // wait for TMR0<2> to go high
                        ;
                    set7seg(secs%10);       // output ones digit
                    ONES = 1;               // enable ones display
                    while (TMR0_2)          // wait for TMR0<2> to go low
                        ;
                }
            }
        }  
    }      
}


/***** FUNCTIONS *****/

/***** Display digit on 7-segment display *****/
void set7seg(uint8_t digit)
{
    // pattern table for 7 segment display on port B
    const uint8_t pat7segC[10] = {
        // RB4 = E, RB1:0 = FG
		0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67
     //   0b010010,   // 0
     //   0b000000,   // 1
     //   0b010001,   // 2
     //   0b000001,   // 3
     //   0b000011,   // 4
     //   0b000011,   // 5
     //   0b010011,   // 6
     //   0b000000,   // 7
     //   0b010011,   // 8
     //   0b000011    // 9    
    }; 

    // pattern table for 7 segment display on port C
    //const uint8_t pat7segC[10] = {
        // RC4:1 = CDBA
     //   0b011110,   // 0
     //   0b010100,   // 1
     //   0b001110,   // 2
     //   0b011110,   // 3
     //   0b010100,   // 4
     //   0b011010,   // 5
     //   0b011010,   // 6
     //   0b010110,   // 7
     //   0b011110,   // 8
     //   0b011110    // 9
    //};
    
    // Disable displays
    PORTB = 0;                  // clear all digit enable lines on PORTB
  //  PORTC = 0;                  //  and PORTC
    
    // Output digit pattern
    PORTC = pat7segC[digit];    // lookup and output port B and C patterns
    //PORTC = pat7segC[digit];
}

I have also included proteus .dsn file
 

Attachments

  • 7 Segment.rar
    10.2 KB · Views: 110

Re: 7 Segment Code issues - Help requested

Thanks for the reply.

Original code along proteus file attached.
 

Attachments

  • Gooligum 7 segments MPX.rar
    7 KB · Views: 97

Re: 7 Segment Code issues - Help requested

What is the problem. The original code works fine. It is written for PIC16F609 which has fewer pins. If you use any othe PIC which has 2 ports then you don't have to use such code.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top