Author Topic: Help with mapping LCD segments to data word in LCD driver  (Read 970 times)

0 Members and 1 Guest are viewing this topic.

Offline djsbTopic starter

  • Frequent Contributor
  • **
  • Posts: 890
  • Country: gb
Help with mapping LCD segments to data word in LCD driver
« on: August 13, 2022, 11:09:09 am »
I have this code running on a PIC16F1847.
Code: [Select]
/*
FILENAME:REVOX_B261_PCE2111_LCD_TEST1.C
REVISION:0.1
Date:05 August 2022
Author: Original Ttelmah CCS INFO FORUM 04th August 2022 with contributions by David J S Briscoe
Purpose: This program is to test the Mullard/Philips PCE2111 Duplex 64 segment LCD driver on a Revox B261 FM tuner.
Status: 10th August:All segments are lit (apart from STORE and ANT-Check LCD connections.
Pin diagram

;         Target Controller - PIC16F1847
;                                                                                                                                 
; RS232-WHITE------RA2 |1 18| RA1-----------
; -----------------RA3 |2 17| RA0-----------
; -----------------RA4 |3 16| RA7-----------
; -----------------RA5 |4 15| RA6-----------
; GND--------------VSS |5 14| VDD-----------+5V
; PCE2111 DLEN-----RB0 |6 13| RB7-----------
; PCE2111 DATA-----RB1 |7 12| RB6-----------
; PCE2111 CLB------RB2 |8 11| RB5-----------
; -----------------RB3 |9 10| RB4-----------
;                           
;
NOTES:




*/


#include <16F1847.H>
#fuses INTRC_IO, NOWDT, NOBROWNOUT, PUT,NOPROTECT,MCLR,NOLVP
#use delay(clock=8000000)
#use RS232(baud=9600, xmit=PIN_A2,ERRORS) //RS232 on Pin A2



// Define pins for CBUS
#define DLEN PIN_B0
#define DATA PIN_B1
#define CLB PIN_B2 //set to suit you

int32 low32 = 0xFFFFFFFF;  //ALL segments ON
int32 high32 = 0xFFFFFFFF; //
//int32 low32 = 0x00000000;  //ALL segments OFF.
//int32 high32 = 0x00000000; //.
//int32 low32 = 0xFFDFFFFF;  //STEREO (SEG 22)OFF (all others ON).
//int32 high32 = 0xFFFFFFFF; //
//int32 low32 = 0xFFFFFF7F;  //25 OFF (SEG 8) ALL others ON.
//int32 high32 = 0xFFFFFFFF; //.
//int32 low32 = 0xFFFFFF7F;  //25 OFF. POINT AND MHZ OFF
//int32 high32 = 0xFFFFFF7F; //
//int32 low32 = 0xFFFFFFFF;  //75 OFF.25 AND 50 ON. 50 AND 75 SEG 32.
//int32 high32 = 0x7FFFFFFF; //
//int32 low32 = 0x7FFFFFFF;  //50 OFF REST ON
//int32 high32 = 0xFFFFFFFF; //



void init(void)
{
    //call at start to ensure lines are low
    output_low(DLEN);
    output_low(CLB);
}

#inline
void clock()
{
    //generate one bit clock
    delay_us(8);
    output_high(CLB);
    delay_us(2);
    output_low(CLB);
    delay_us(8);
}

void send(int32 value, int1 lowhigh)
{
    int ctr;
    int32 mask=1; //data is output LSb first
    output_high(DLEN);
    delay_us(8);
    //output 32bit value to either low or high register
    output_low(DATA);
    clock(); //first send a 0
    for (ctr=0;ctr<32;ctr++)
    {
        if (value & mask)
           output_high(DATA);
        else
           output_low(DATA);
        clock();
        mask*=2; //Modern compiler should optimise this to shift
    }
    if (lowhigh)
       output_high(DATA);
    else
       output_low(DATA);
    clock(); //clock out the bit to specify high/low register
    output_low(DLEN);
    clock(); //now clock this into the latches.
    delay_us(8); //do not do anything else for 8uSec
}

void main(void)
{
    int32 loop_cntr;
    for( loop_cntr = 0; loop_cntr < 0xffff; loop_cntr++)
    {
    init(); //ensure bus is initialised
    delay_us(100);
    //low32--;
    send(low32, 0); //load the low 32bits
    send(high32, 1); //load the high 32bits.
//delay_us(100);
    //printf("Loop count: %8LX\r\n", loop_cntr);
//printf("low32 value: %8LX\r\n", low32);
delay_ms(1000);
//printf("high32 value: %8LX\r\n", high32);
    printf("WORKING...\r\n");
    }
}


As you can see in the comments above, I have got some code turning on/off a few segments by random experimentation as follows

Code: [Select]
int32 low32 = 0xFFFFFFFF;  //ALL segments ON
int32 high32 = 0xFFFFFFFF; //
//int32 low32 = 0x00000000;  //ALL segments OFF.
//int32 high32 = 0x00000000; //.
//int32 low32 = 0xFFDFFFFF;  //STEREO (SEG 22)OFF (all others ON).
//int32 high32 = 0xFFFFFFFF; //
//int32 low32 = 0xFFFFFF7F;  //25 OFF (SEG 8) ALL others ON.
//int32 high32 = 0xFFFFFFFF; //.
//int32 low32 = 0xFFFFFF7F;  //25 OFF. POINT AND MHZ OFF
//int32 high32 = 0xFFFFFF7F; //
//int32 low32 = 0xFFFFFFFF;  //75 OFF.25 AND 50 ON. 50 AND 75 SEG 32.
//int32 high32 = 0x7FFFFFFF; //
//int32 low32 = 0x7FFFFFFF;  //50 OFF REST ON
//int32 high32 = 0xFFFFFFFF; //



However, I'd like to get the digits working, and I'm struggling to understand how the data words relate to the segments. If I understood this then I'd be able to get the mapping done quicker. Can someone help me to understand how this works? Thanks.
« Last Edit: August 13, 2022, 12:28:03 pm by djsb »
David
Hertfordshire,UK
University Electronics Technician, London PIC,CCS C,Arduino,Kicad, Altium Designer,LPKF S103,S62 Operator, Electronics instructor. Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime. Credited Kicad French to English translator.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: Help with mapping LCD segments to data word in LCD driver
« Reply #1 on: August 13, 2022, 12:29:11 pm »
I assume you found a PCE2111 datasheet.  If not, there's one here: https://www.eevblog.com/forum/testgear/philips-pm3295-and-pm3295a/?action=dlattach;attach=205895

What's the problem?  The mapping is documented on the schematic you attached.
There are two columns, one for the PCE2111 A latches (pin BP1 (38) => LCD COM2 (26) ) and the other for the BN latches (pin BP2 (37) => LCD COM1 (52) ).  Each segment is either described by name for the various annunciators or by digit number + segment letter for the four starburst digits and leading '1' - see LCD on schematic.  Unfortunately, it isn't annotated which column is which set of latches so you'll have to figure out the CBUS bit 33 level for yourself and add column headings accordingly.
 
The following users thanked this post: djsb, Andy Watson

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 2082
Re: Help with mapping LCD segments to data word in LCD driver
« Reply #2 on: August 13, 2022, 01:05:23 pm »
The only difficulty is the"ANT", which appears to be hard-wired.

Also, you probably want to use unsigned ints - otherwise unexpected things might happen depending on the state of the most significant bit.
 
The following users thanked this post: djsb

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5895
  • Country: es
Re: Help with mapping LCD segments to data word in LCD driver
« Reply #3 on: August 13, 2022, 01:28:51 pm »
Why create a new message? Better you continue your existing thread, the segments were described there.


Code: [Select]
                  HighLow     Value(32 bits)
                              31  30  29  28  27  26  25  24  23  22  21  20  19  18  17  16  15  14  13  12  11  10  09  08  07  06  05  04  03  02  01  00
           
Segments 32-01    0           32  31  30  29  28  27  26  25  24  23  22  21  20  19  18  17  16  15  14  13  12  11  10  09  08  07  06  05  04  03  02  01
Segments 64-33    1           64  63  62  61  60  59  58  57  56  55  54  53  52  51  50  49  48  47  46  45  44  43  42  41  40  39  38  37  36  35  34  33

You can send the value in any format, ex. hexadecimal (You can use any convertex, ex. this one),
or binary right away, but for 32 bit it'll quite long, ex. 0b111100001111100001111000011110000

To display "12345":
Display 1: bc =  S22H (They're connected together)
Display 2: abdehm = S21L S15H S25H S24H S16L S24L
Display 3: abcdhm = S20L S9H S10H S12H S10L S13L
Display 4: bcfhm = S2H S3H S7H S3L S6L
Display 5: acdfhm = S17L S30H S28H S1H S30L S27L

As you see, everything is part of everything, you can't just write to a single digit without affecting others.
So you must know all the segments beforehand, then prepare the data.
In this case, after tidying, we have this (Might have some errors, lots of bits flying around):

S30H S28H S25H S24H S22H S15H  S12H S10H S9H S7H  S3H S2H S1H
0b00101001101000000100101101000111 = 0x29A04B47

S30L S27L S24L S21L S20L S17L S16L S13L S10L S6L S3L
0b00100100100110011001001000100100 = 0x24999224

Finally:
Code: [Select]
send(0x29A04B47, 1);
send(0x24999224, 0);

High and low might be reversed, if looking weird try:
Code: [Select]
send(0x29A04B47, 0);
send(0x24999224, 1);

This all needs to be done using some sort of tables and parsing to make it efficient.
« Last Edit: August 13, 2022, 01:41:41 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: djsb

Offline djsbTopic starter

  • Frequent Contributor
  • **
  • Posts: 890
  • Country: gb
Re: Help with mapping LCD segments to data word in LCD driver
« Reply #4 on: August 13, 2022, 02:14:19 pm »
Thanks everyone for your replies.
I was going to add this to my existing thread, but I wanted the post to be more specific to the task to avoid confusion.
I'll plough on with the mapping. I'm going to start with one digit and map the segments for numbers 0-9. Then I'll try moving the same numbers to another digit. Later I'll have to do letters as well, as the display shows letters to indicate stations.





PS Can a moderator merge this thread with my previous related thread if preferred?

https://www.eevblog.com/forum/projects/14-segment-lcd-emulation-on-a-128x32-ssd1306-based-oled-display/

Thanks.
« Last Edit: August 13, 2022, 02:20:35 pm by djsb »
David
Hertfordshire,UK
University Electronics Technician, London PIC,CCS C,Arduino,Kicad, Altium Designer,LPKF S103,S62 Operator, Electronics instructor. Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime. Credited Kicad French to English translator.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: Help with mapping LCD segments to data word in LCD driver
« Reply #5 on: August 13, 2022, 03:42:47 pm »
I posted a 7 bit ASCII 14 segment starburst font table here:
https://www.eevblog.com/forum/projects/vacuum-fluorescent-display-multiplexing-problem/msg1034886/#msg1034886

As usual for starburst displays upper and lower case are identical.  At the time I said:
Quote
That's a usable 7 bit ASCII character set with some lamp test segment patterns down in the control codes. Notable ommissions are . ; : ! and of course the lower case alphabet is in upper case.

Segment sequence is MSB first clockwise,  outside starting at the top, then all the inside radials starting with the left middle one.

You need a 64 bit buffer in RAM for the display, organized as two 32 bit words for the A and B latches  (or possibly simply as eight bytes).   You also need a lookup table for which segment goes where, organized by digit position.   Due to limited program memory, its probably best to store the segment position as two nibbles (as nibble swaps are efficient on PIC16) in a byte, using one as an index into the display buffer and the other as an index into a lookup table of one bit set bytes (as PIC16 doesn't have a barrel shifter):
Code: [Select]
const uint8_t mask1bit[8]={
        0b00000001,
        0b00000010,
        0b00000100,
        0b00001000,
        0b00010000,
        0b00100000,
        0b01000000,
        0b10000000
};

To write a character to the display at position x, you look up the segment pattern in the font table, then loop through the pattern word one bit at a time, looking up each segment in your position table to get a character position specific byte and bit no. converting the bit no. to a mask from the above array, and if the bit in the segment pattern was 1, ORing the mask with the buffer byte, otherwise, it was 0 so invert the mask and AND it.
« Last Edit: August 13, 2022, 03:56:57 pm by Ian.M »
 
The following users thanked this post: djsb

Offline djsbTopic starter

  • Frequent Contributor
  • **
  • Posts: 890
  • Country: gb
Re: Help with mapping LCD segments to data word in LCD driver
« Reply #6 on: August 13, 2022, 03:53:26 pm »
Thanks Ian.M,
This post in the CCS Forum was also recommended to me

https://www.ccsinfo.com/forum/viewtopic.php?t=33377&start=11

So, a lot of work ahead of me, but I'm making some progress. And most importantly I'm learning new stuff and that's really the whole point.

I'll pop back later if I get stuck. Thanks everyone again.
David
Hertfordshire,UK
University Electronics Technician, London PIC,CCS C,Arduino,Kicad, Altium Designer,LPKF S103,S62 Operator, Electronics instructor. Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime. Credited Kicad French to English translator.
 

Offline Ian.M

  • Super Contributor
  • ***
  • Posts: 12852
Re: Help with mapping LCD segments to data word in LCD driver
« Reply #7 on: August 13, 2022, 03:58:00 pm »
Edit above: fixed the mask1bit[] lookup table.

I also forgot to mention the final step: After you've written all the characters you want to the buffer array using the above segment at a time method, you finally send the buffer to the PCE2111, as two CBUS transfers of half the buffer at a time, to update the A and B latches respectively.
« Last Edit: August 14, 2022, 03:59:27 am by Ian.M »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf