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.
Hi! For OPTION_REG = 0x80;
ReplyDeleteDisable only NOT_RBPU, but don't enable TMR0, to enable TMR0, you must write : OPTION_REG = 0x07;
thank you!
marC:)