One SSD takes up 7 i/o ports of the microcontroller, that means 2 SSD will consume 14 i/o ports and 3 will take up 21 i/o ports excluding the decimal connection. This is not reasonable, being that the SSD unit can be just a part of a big project you intend to build.
There's a technique that can be used to serve up i/o ports of the microcontroller. This is called multiplexing.
Multiplexing uses Persistence of Vision of human eyes. Human eyes cannot detect visual changes at a rate of 25 frames/sec. This means any transition effect in which the time difference is less than 1/25 sec, the human eye will not notice it.
This concept is used in Multiplexing of SSD. Only one out the 4 SSD units used in this project comes ON at a time, but they change their ON/OFF condition very fast creating the impression that all the digits are ON at the same time. The Proteus Schematic is shown below
Proteus Schematic |
The 1st byte which represent Unit digit is sent to the SSD via PORT B and the 1st transistor is activated at the same time, after a short time it is turned OFF.
The tens digit is sent to the SSD, and the corresponding transistor is activated at the same time, after a short time, it is turned OFF. This same is repeated for the hundred and thousand byte.
The whole process is continuously repeated at high speed for all digit and their corresponding transistors.
*** Please note on Easy PIC V7, the SSD unit is connected to PORT D. In our Proteus design we used PORTB. Also the code below is for 18F45K22 which is the chip that comes with Easy PIC V7. To use with 16F877A comment out ANSELA and ANSELD
MikroC Code:
/**********************************
Project Name :
Multiplexing of 7 segment display with PIC 18F45K22
Author : Promise
Description :
This project demonstrate multiplexing of 4 7 segment display. it counts from 0000 - 9999
Test configuration:
MCU: PIC 18F45K22
Oscillator: XT 8.0000 MHz
Dev Board : Easy Pic v7
turn on switches SW4.0, SW4.1, SW4.2, SW4.3
***********************************/
unsigned int unit,tens,hundreds,thousand ;
unsigned int counter = 0;
unsigned int digit = 0;
unsigned int display(unsigned int digit1) {
unsigned int my_digit;
unsigned int array[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // array holding common cathode 7 segment look up table for 0-9
my_digit = array[digit1];
return (my_digit) ;
}
void short_delay(){ // delay function to control how digit is incremented
if(counter<100){
counter++ ;
if(counter==100){
digit++ ;
counter = 0; }
if(digit==9999){
digit = 0;
}
}
}
void main() {
ANSELA = 0;
ANSELD = 0;
TRISD = 0x00; // set PORTD as output
TRISA = 0x00;
TRISA.F0 = 0; // set PORTA bit 0-3 as output
TRISA.F1 = 0;
TRISA.F2 = 0;
TRISA.F3 = 0;
PortA.F0 = 0; //turn off PORTA bit 0-3
PortA.F1 = 0;
PortA.F2 = 0;
PortA.F3 = 0;
while(1) {
short_delay(); // call delay function
unit = digit % 10 ; //extract unit from digit
PORTD = display(unit); // send unit value to PORTD
PortA.F0 = 1; // turn ON 1st 7 segment (LSD 7 Segment display)
PortA.F1 = 0;
PortA.F2 = 0;
PortA.F3 = 0;
delay_ms(1);
PortA.F0 = 0;
tens = (digit / 10) % 10 ; //extract tens from digit
PORTD = display(tens); // send tens value to PORTD
PortA.F0 = 0;
PortA.F1 = 1; // turn ON 2nd 7 segment
PortA.F2 = 0;
PortA.F3 = 0;
delay_ms(1);
PortA.F1 = 0;
hundreds = (digit / 100) % 10; //extract hundreds from digit
PORTD = display(hundreds); // send hundreds value to PORTD
PortA.F0 = 0;
PortA.F1 = 0;
PortA.F2 = 1; // turn ON 3rd 7 segment
PortA.F3 = 0;
delay_ms(1);
PortA.F2 = 0;
thousand = digit / 1000 ; //extract thousand from digit
PORTD = display(thousand); // send thousand value to PORTD
PortA.F0 = 0;
PortA.F1 = 0;
PortA.F2 = 0;
PortA.F3 = 1; // turn ON 4th 7 segment
delay_ms(1);
PortA.F3 = 0;
}
}
MikroC Code:
/**********************************
Project Name :
Multiplexing of 7 segment display with PIC 18F45K22
Author : Promise
Description :
This project demonstrate multiplexing of 4 7 segment display. it counts from 0000 - 9999
Test configuration:
MCU: PIC 18F45K22
Oscillator: XT 8.0000 MHz
Dev Board : Easy Pic v7
turn on switches SW4.0, SW4.1, SW4.2, SW4.3
***********************************/
unsigned int unit,tens,hundreds,thousand ;
unsigned int counter = 0;
unsigned int digit = 0;
unsigned int display(unsigned int digit1) {
unsigned int my_digit;
unsigned int array[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // array holding common cathode 7 segment look up table for 0-9
my_digit = array[digit1];
return (my_digit) ;
}
void short_delay(){ // delay function to control how digit is incremented
if(counter<100){
counter++ ;
if(counter==100){
digit++ ;
counter = 0; }
if(digit==9999){
digit = 0;
}
}
}
void main() {
ANSELA = 0;
ANSELD = 0;
TRISD = 0x00; // set PORTD as output
TRISA = 0x00;
TRISA.F0 = 0; // set PORTA bit 0-3 as output
TRISA.F1 = 0;
TRISA.F2 = 0;
TRISA.F3 = 0;
PortA.F0 = 0; //turn off PORTA bit 0-3
PortA.F1 = 0;
PortA.F2 = 0;
PortA.F3 = 0;
while(1) {
short_delay(); // call delay function
unit = digit % 10 ; //extract unit from digit
PORTD = display(unit); // send unit value to PORTD
PortA.F0 = 1; // turn ON 1st 7 segment (LSD 7 Segment display)
PortA.F1 = 0;
PortA.F2 = 0;
PortA.F3 = 0;
delay_ms(1);
PortA.F0 = 0;
tens = (digit / 10) % 10 ; //extract tens from digit
PORTD = display(tens); // send tens value to PORTD
PortA.F0 = 0;
PortA.F1 = 1; // turn ON 2nd 7 segment
PortA.F2 = 0;
PortA.F3 = 0;
delay_ms(1);
PortA.F1 = 0;
hundreds = (digit / 100) % 10; //extract hundreds from digit
PORTD = display(hundreds); // send hundreds value to PORTD
PortA.F0 = 0;
PortA.F1 = 0;
PortA.F2 = 1; // turn ON 3rd 7 segment
PortA.F3 = 0;
delay_ms(1);
PortA.F2 = 0;
thousand = digit / 1000 ; //extract thousand from digit
PORTD = display(thousand); // send thousand value to PORTD
PortA.F0 = 0;
PortA.F1 = 0;
PortA.F2 = 0;
PortA.F3 = 1; // turn ON 4th 7 segment
delay_ms(1);
PortA.F3 = 0;
}
}
ANSELA and ANSELD
ReplyDeleteANSELA and ANSELD is used to configure the adc pins of PORT A and PORT D to be digital for 18F45K22. For 16F877A comment that line of code and replace with ADCON1 =0x07; thank you
Delete