First of all, you don't have all the display control lines defined. There are 15 of them total:
- segments a b c d e f g dp
- group select inputs D C B A for U11 to select a U1-U10 latch to load its segment data (set to 15 when not loading)
- digit select inputs C B A to select digit 0-3 in each group or 7 to blank the display
You seem to have the eight segments doubled up on P2.0 to P2.3 (that won't work), and the digit selects on P2.4 to P2.6, but you don't have anything to select U1-U10.
You will probably want a subroutine for each of the sets of bits: write_segments, write_digit (U12), write_group (U11)
It would look something like this:
(note that "!!" turns zero/non-zero into 0/1, and I'm assuming the P1/P2 bit layout)
(I might have the segment ordering mixed up too, but really it's just a bunch of pins on J3 that you need to get in the right order. And I had to look up that sbit thing, it's specific to 8051 stuff.)
Code:
sbit seg_a = P1^0; sbit seg_b = P1^1; sbit seg_c = P1^2; sbit seg_d = P1^3;
sbit seg_e = P1^4; sbit seg_f = P1^5; sbit seg_g = P1^6; sbit seg_dp = p1^7;
void write_segments(char data)
{
seg_a = !!(data & 0x01);
seg_b = !!(data & 0x02);
seg_c = !!(data & 0x04);
seg_d = !!(data & 0x08);
seg_e = !!(data & 0x10);
seg_f = !!(data & 0x20);
seg_g = !!(data & 0x40);
seg_dp = !!(data & 0x80);
}
sbit group_A = P2^0; sbit group_B = P2^1; sbit group_C = P2^2; sbit group_D = P2^3;
#define GROUP_NONE 15
void write_group(char data)
{
group_A = !!(data & 0x01);
group_B = !!(data & 0x02);
group_C = !!(data & 0x04);
group_D = !!(data & 0x08);
}
sbit digit_A = P2^4; sbit digit_B = P2^5; sbit digit_C = P2^6;
#define DIGIT_BLANK 7
void write_digit(char data)
{
digit_A = !!(data & 0x01);
digit_B = !!(data & 0x02);
digit_C = !!(data & 0x04);
}
That might not make the most efficient code, but it should be the most readable code.
I think the process is listed in Chapter 3 Page 22, but here is my interpretation of a full display scan by looking at the hardware:
You have with 10x4 bytes of memory to store the LED and segment bits. This gets updated by the comm routines.
start with the U12 digit set to 7 (blank) and the U11 group select set to 15
then for each of the four digit positions (0-3):
- for each group (0-9 / U1-U10):
- - select the group (U1-U10) latch by sending the group number (0-9) to U11
- - send the segment data for the current digit position in the group, probably mem[group*4+digit]
- - send 15 to U11 to lock the latch
- set the U12 digit select to the current digit (0-3) to light up that digit from every group
- wait about 25ms or so for the display to show
- set the U12 digit select to 7 (blank)
so...
Code:
char display_mem[4*10];
void scan_display()
{
char group, digit;
write_digit(DIGIT_BLANK);
write_group(GROUP_NONE);
for (digit = 0; digit < 4; digit++) {
for (group = 0; group < 10; group++) {
write_group(group);
write_segments(display_mem[group*4 + digit]);
write_group(GROUP_NONE);
}
write_digit(digit);
delay_ms(25);
write_digit(DIGIT_BLANK);
}
}