4.2. PICDEM Liquid Crystal Display

• LCD layout and connections

• LCD test program

• BCD count program

The plain 3.5-digit parallel liquid crystal display (LCD) is driven directly from the MCU, occupying 15 of the I/O pins. The usual alternative to this arrangement is to use a serial LCD, which can be driven via the RS232 port. This occupies only one or two pins, but it is more expensive, as it contains its own microcontroller.

LCD Connections

The parallel LCD is operated by specific combinations of inputs that enable the segments as required (Figure 4.7). The segments are designated A to G for each seven-segment digit, with digits numbered 1 to 4 from the right. The most significant half digit (4) has only segments B and C, displaying only ‘1’. Four common connections (COM1–COM4) enable groups of segments such that each has a unique address.

Figure 4.7. (a) LCD Segment Connections (courtesy of Varitronix Ltd.); (b) Segment Labels; (c) MCU to LCD Connection; (d) LCD Connection Map


Note that this is a standard DMM display, so additional symbols are available that are not needed in the mechatronics board applications. The data for the display segments are stored in dedicated set of 12 registers in the PIC 16F917 (Table 4.5

Table 4.5. PIC 16F917 LCD RAM Data Register Bits
AddressCOM0+AddressCOM1+
00+-- 06 -- -- 03 -- -- --24+-- 06 -- -- 03 -- -- --
LCDDATA0xx 2 A xx xx 3 A xx xx xxLCDDATA3xx 2F xx xx 3F xx xx xx
08+-- -- -- -- 11 -- -- --32+-- -- -- -- 11 -- -- --
LCDDATA1xx xx xx xx 3B xx xx xxLCDDATA4xx xx xx xx 3G xx xx xx
016+23 22 21 -- -- -- -- --40+23 22 21 -- -- -- -- --
LCDDATA21B 1 A 2B XX XX XX XX XXLCDDATA51G 1F 2G xx xx xx xx xx

AddressCOM2+AddressCOM3+
48+-- 06 -- -- 03 02 -- --72+-- 06 -- -- 03 02 -- --
LCDDATA6xx 2E xx xx 3E 4x xx xxLCDDATA9xx 2D xx xx 3D P3 xx xx
56+-- -- -- -- 11 -- -- --80+-- -- -- -- 11 -- -- --
LCDDATA7xx xx xx xx 3C xx xx xxLCDDATA10xx xx xx xx P2 xx xx xx
64+23 22 21 -- -- -- -- --88+-- 22 21 -- -- -- -- --
LCDDATA81C 1E 2C xx xx xx xx xxLCDDATA11xx 1D P1 xx xx xx xx xx

), called LCDDATAx, where ‘x’ is 0 to 11 (SFR addresses 110 h–11 Bh, bank 1). These registers contain 12×8=96 bits, which are identified individually, bits 0–95. If one of these bits is high, the corresponding LCD segment or pixel is on.

The LCD has a total of 26 numerical segments, comprising three seven-segment digits, two segments for the MSD, and three decimal points. The MSD bits are controlled by the same bit, as they always come on together, giving only 25 bits actually required. Therefore, only some bits in the registers are used, but the spare capacity allows more complex displays to be operated by the ‘917 in other applications. We see that the bits that are used are not arranged very logically, so they will be mapped by the LCD display function to simplify the output process.

The bits in the first three registers (LCDDATA0–LCDDATA2) are associated with COM0 output, the next three with COM1, and so on to COM3 (see Table 4.5). Unfortunately, the common inputs on the LCD are identified as COM1–COM4, so COM1 is controlled from the MCU output COM0, and so on, with COM4 being connected to COM3 MCU output pin.

The 16F917 MCU can provide up to 24 segment drive outputs (SEG0–SEG23), with four common connections (COM0–COM3). These are used in defined combinations to control up to 24×4=96 segments or pixels in the display. In this way, 1 bit in the LCDDATAx registers controls one element of the display. This display needs only 25 bits and ten of the available segment outputs (SEG0, 1, 2, 3, 6, 11, 16, 21, 22, and 23). These outputs are encoded to allow individual bit control within the program.

LCD Test Program

Listing 4.3 shows a test program, LCD1, which displays the numerals 0 to 9 on each digit in turn, then flashes on the MSD and three decimal points, so that correct operation of each can be checked.

Listing 4.3. Test Program for Mechatronics Board LCD

//LCD1.C MPB 20-4-07

//Test program for mechatronics board LCD

//Displays count 0 to 9 on Digits1,2,3 and 1 on Digit4

#include “16F917.h”

#use delay(clock=8000000)

//LCD DISPLAY DATA: (3 numerals * 7 segments)+MSD * 1 segment+3 decimal points

//Bit map for numerals 0–9 and blank..................................

//Numeral: 0 1 2 3 4 5 6 7 8 9 blank

byte const DigMap[11]={0xFD,0×60,0xDB,0xF3,0×66,0xB7,0xBF,0xE0,0xFF,0xE7,0×00};

//Bit addressess in LCD RAM locations LCDDATA0 to LCDDATA11=12*8 bits

//Numbered 0-95 with offsets COM0=0, COM1=24, COM2=48, COM3=72

//Segment: A B C D E F G

#define DIG1 COM0+22,COM0+23,COM2+23,COM3+22,COM2+22,COM1+22,COM1+23

//Bit addresses

♯define DIG2 COM0+6, COM0+21,COM2+21,COM3+6, COM2+6, COM1+6, COM1+21

//Bit addresses

♯define DIG3 COM0+3, COM0+11,COM2+11,COM3+3, COM2+3, COM1+3, COM1+11

//Bit addresses

#define DIG4 COM2+2 //Both bits

#define DP1 COM3+21 //Decimal point 1

#define DP2 COM3+11 //Decimal point 2

#define DP3 COM3+2 //Decimal point 3

void main()

{

int8 n;

setup_lcd(LCD_MUX14,0); //Initialize 14-pin LCD, no clock divide

for(n=0;n<11;n++) //Display numerals 0–9 at digit 1

{lcd_symbol(DigMap[n],DIG1); //Send digit bits to segment addresses

delay_ms(300);

}

for(n=0;n<11;n++) //Display numerals 0–9 at digit 2

{lcd_symbol(DigMap[n],DIG2); //Send digit bits to segment addresses

delay_ms(300);

}

for(n=0;n<11;n++) //Display numerals 0–9 at digit 3

{lcd_symbol(DigMap[n],DIG3); //Send digit bits to segment addresses

delay_ms(300);

}

lcd_symbol(0X80,DIG4); //Switch on MSD digit 4

delay_ms(1000);

lcd_symbol(00X00,DIG4); //Switch off MSD digit 4

lcd_symbol(0XFF,DP1); //Switch on decimal point 1

delay_ms(500);

lcd_symbol(0X00,DP1); //Switch off decimal point 1

lcd_symbol(0XFF,DP2); //Switch on decimal point 2

delay_ms(500);

lcd_symbol(0X00,DP2); //Switch off decimal point 2

lcd_symbol(0XFF,DP3); //Switch on decimal point 3

delay_ms(500);

lcd_symbol(0X00,DP3); //Switch off decimal point 3

while(1){}; //Done

}

Each group of segments associated with each common connection on the LCD is operated in turn by the program. The LCD functions used are setup_lcd()and lcd_symbol(). The arguments of the setup function specify a 14-pin display module and 0 clock divide factor. The clock rate controls the display multiplexing rate, which can be modified for best visibility.

The arguments of the output function comprise an 8-bit map for the numeral to be displayed as a hex number (Table 4.6

Table 4.6. Bit Maps for LCD Numerals
NumeralSegmentABCDEFGLSBCode
Bit76543210
0 111111010xFD
1 011000000x6 0
2 110110100xDB
3 111100110xF3
4 011001100x6 6
5 101001110xB7
6 101011110xBF
7 111000000xE0
8 111111110xFF
9 111001110xE7
 00000000Blank

) and a list of the corresponding bits in the LCDDATAx locations for that digit. The 8-bit numeral codes are shown in Figure 4.7. Because of the interaction of the control lines, the LSB for each code was determined by inspecting the results on the display. Otherwise, the mapping is as normally required for seven segment codes.

The mapping data for each segment is provided to the output function in the form of a list of segment bit addresses, 0–95. To include information about which COM line is active for each bit, the address is supplied as the sum of the start address of each COM block and the bit number within that block. Therefore, the bit address of segment A of digit 1 (DIG1) is COM0+22. COM0 has the value 0, COM1=24, COM2=48, and COM3=72. Therefore, COM0+22=22. By the same process, the single-bit address controlling the MSD (DIG4) is COM2+2=50, and the first decimal point (DP1) is addressed at COM3+21=93.

For convenience, the lists of segment bit addresses for each digit are defined at the top of the program, using the replacement text labels DIG1, DIG2, DIG3, and DIG4plus the three decimal point addresses. The lcd_symbol() function is then supplied with the constant array element number for the numeral to be displayed and the bit address list as DIGx. A ‘for’ loop outputs each numeral at each position in turn, including the blank digit, while the MSD and decimal points are switched on and off individually.

BCD Count Program

Listing 4.4 shows a program that displays a decimal count on the LCD. The count is generated as binary coded decimal (BCDx) digits. Each digit is initialized to 0, then incremented until it reaches 10, when it is cleared back to 0 and the next most significant digit incremented. The three digits are then displayed together. The MSD (DIG4) is not used. The LCD data block is now concealed in a separate source code file lcd.inc, which is included at the top of the program.

Listing 4.4. LCD Counting Program

/////////////////////////////////////////////////////////////////////

//LCD2.C MPB 20-4-07

//LCD program to count up when SW2 on

//Hardware: Connect SW2 to RA4

/////////////////////////////////////////////////////////////////////

#include “16F917.h”

#include “lcd.inc” //Include file with LCD data

#use delay(clock=8000000)

void main() //////////////////////////////////////////////////

{

int8 BCD1=0, BCD2=0, BCD3=0; //BCD count digits

setup_lcd(LCD_MUX14,0); //Initialize 14-pin LCD

while(1)

{ //GENERATE DECIMAL COUNT

if(!input(PIN_A4)) //Test Switch 2

{

delay_ms(10); //Debounce and slow

BCD1++; //Increment ones

if(BCD1==10) //..up to 9

{

BCD1=0; //Reset ones

BCD2++; //Increment tens

if(BCD2==10) //..up to 90

{

BCD2=0; //Reset tens

BCD3++; //Increment hundreds

if(BCD3==10) //..up to 900

BCD3=0; //All reset to zero

}

}

}

//DISPLAY BCD DIGITS

lcd_symbol(DigMap[BCD1],DIG1); //Display Digit 1

lcd_symbol(DigMap[BCD2],DIG2); //Display Digit 2

lcd_symbol(DigMap[BCD3],DIG3); //Display Digit 3

} //Loop always

}/////////////////////////////////////////////////////////END

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.117.167.230