This post explains how to drive a common cathode seven-segment display (SSD) with the PIC18F45Q10 microcontroller. We’ll implement a hexadecimal counter (0-F) that cycles through each digit, showcasing how to manipulate output pins to control the display.
A Seven-Segment Display (SSD) is an electronic display device widely used for showing decimal numbers, hexadecimal values, and even a limited set of alphanumeric characters. It consists of seven LED segments (labeled a to g) arranged in a rectangular pattern and an optional decimal point (DP). By selectively illuminating specific segments, various characters can be displayed.
SSDs are commonly used in digital clocks, calculators, meters, and embedded systems due to their simplicity, low cost, and easy interface with microcontrollers. They are available in common cathode or common anode configurations, depending on whether the common pin is connected to the ground (cathode) or a positive voltage (anode).
Here’s a table that shows the bit patterns for each digit (0-F) in hexadecimal for a common cathode seven-segment display. Each bit corresponds to a segment (a-g and DP). A 1 lights up the segment, and a 0 turns it off.
Hex | a | b | c | d | e | f | g | DP | Binary Pattern | Hex Pattern |
0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 00111111 | 0x3F |
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 00000110 | 0x06 |
2 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 01011011 | 0x5B |
3 | 1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 01001111 | 0x4F |
4 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 01100110 | 0x66 |
5 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 01101101 | 0x6D |
6 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 01111101 | 0x7D |
7 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 00000111 | 0x07 |
8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 01111111 | 0x7F |
9 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 01101111 | 0x6F |
A | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 01110111 | 0x77 |
b | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 01111100 | 0x7C |
C | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 00111001 | 0x39 |
d | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | 01011110 | 0x5E |
E | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 01111001 | 0x79 |
F | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 01110001 | 0x71 |
How to Read the Table:
For example:
The seven-segment display will connect to the PORTD of the PIC18F45Q10. Each segment (a to g and DP) is controlled by one bit of PORTD. Resistors are placed in series with each segment to limit the current. The Pin Configuration for the Seven-Segment Display:
Here’s the simple circuit diagram:
Here is the code to control the seven-segment display. The microcontroller cycles through hexadecimal digits (0-F) and displays them on the SSD with a delay for visibility.
/*
* File: main.c
* Author: erraj
*
* Created on January 5, 2025, 10:08 PM
*/
#include <xc.h> // Include the header file for the PIC18F45Q10
// PIC18F45Q10 Configuration Bit Settings
// CONFIG1L
#pragma config FEXTOSC = HS // External Oscillator mode Selection bits (HS mode for crystal above 8 MHz)
#pragma config RSTOSC = EXTOSC // Power-up default value for COSC bits (Use external oscillator)
// CONFIG2L
#pragma config MCLRE = EXTMCLR // Master Clear Enable bit (MCLR pin (RE3) is MCLR)
// CONFIG3L
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled)
#define _XTAL_FREQ 20000000 // Define crystal frequency (20 MHz)
// Segment patterns for common cathode seven-segment display (0-F)
unsigned char segment[] = {
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F, // 9
0x77, // A
0x7C, // b
0x39, // C
0x5E, // d
0x79, // E
0x71 // F
};
void delay_ms(unsigned int ms);
void main(void) {
// Initialize PORTD as output
TRISD = 0x00; // Set PORTD as output
PORTD = 0x00; // Clear PORTB initially
while (1) {
// Cycle through 0 to F (hexadecimal)
for (unsigned char i = 0; i < 16; i++) {
PORTD = segment[i]; // Display digit on SSD
delay_ms(300); // Delay for visibility
}
}
}
void delay_ms(unsigned int ms) {
// Basic delay loop (adjusted for 20 MHz clock)
while (ms--) {
__delay_ms(1);
}
}
Code Explanation:
When powered, the seven-segment display will start counting from 0 to F in hexadecimal, with each digit displayed for 300 milliseconds before transitioning to the next.
Watch the Demo Video:
Click here to view the video demonstration!
This project showcases how to interface a seven-segment display with the PIC18F45Q10 microcontroller. By controlling the segments via PORTD, we successfully created a hexadecimal counter. This foundation can be expanded to drive multiple displays or implement more complex applications like displaying sensor data or time.
If you have any questions or want to explore more advanced topics, feel free to leave a comment below. Happy coding!