MSP430FR6989 series tutorial LCD

Posted by pedro84 on Wed, 05 Jan 2022 08:38:11 +0100

MSP430FR6989 series tutorial LCD

Since MSP430 pursues the characteristics of low power consumption, the LCD mounted on MSP430FR6989 is not our usual LCD display (TFT LCD), but a segment LCD

MSP430FR6989 series tutorial water lamp
MSP430FR6989 series tutorial serial communication
MSP430FR6989 series tutorial timer
MSP430FR6989 series tutorial PWM wave
MSP430FR6989 series tutorial LCD

preface

The purpose of learning MSP430 this time is to prepare for the video game. Although I'm not sure I will use MSP430FR6989, I still want to try. After all, no one is sure about the future.

1, LCD

  • In essence, the segmented LCD consists of two polarizing plates (polarizing the light incident on the display screen), a liquid crystal with an energized electrode (between the two polarizers) and a reflective back plate (reflecting the light passing through all layers of the display screen).

  • When the electrode of a specific section is not energized, the section is "cut-off" or gray. In this normal state, the liquid crystal has a twisted structure that can deflect light by 90 degrees. Therefore, when it is not powered on, the light first enters the first layer of polarizing plate and emits from the same direction after deflection. Then, when the light passes through the liquid crystal, the liquid crystal deflects the light by 90 degrees - because the light at this time deflects relative to passing through the first polarizing plate, the light can pass through the second polarizing plate. Finally, the light is reflected through the reflection backplane and returns through the same process. Because the light is reflected back, the segment looks bright or gray.

  • When the electrode of a segment is energized, the segment is "on" or black. In the energized state, the liquid crystal does not twist, so that the light will not deflect when passing through. Therefore, when energized, the light first enters the first layer of polarizing plate and emits from the same direction after deflection. Then, this time, the light passes directly through the liquid crystal without deflection. Since the second polarizing plate forms an angle of 90 degrees with the first layer, the light cannot pass through and be absorbed. This makes the segment look dark.

So the question is, how can we drive the LCD?

  • The LCD must be driven by an AC signal. The DC level applied to the LCD segment may damage the LCD - DC voltages below 50 mV are usually allowed. MSP430LCD module will automatically generate these types of AC waveforms, so that the user only needs to specify the conduction and stop of the section - the internal hardware will complete the rest of the work.

  • The LCD segment has a charge applied to the liquid crystal between two electrodes (COM X-ray and Sx segment lines). The potential difference applied by the two electrodes is the waveform observed through the LCD segment.

  • The presence of RMS voltage on the LCD segment will determine whether the segment is on or off. The example waveform in Figure 2 shows the waveform of one on segment and one off segment (the combination of COMx and Sx pin signals). The on segment applies a greater RMS voltage than the off segment. Note that both segments have a waveform of net zero DC voltage, but the RMS voltage on the on segment is higher, which makes the segment on and look dark.

With this in mind, you can start coding

2, Code writing

Attached here is the complete main C code

#include <msp430.h> 
#include "lcd.h"
#include "pmm.h"
#include "wdt.h"
/**
 * main.c
 */
int main(void)
{
	WDT_A_hold(WDT_A_BASE);

	    // Disable the GPIO power-on default high-impedance mode to activate
	    // previously configured port settings
	PMM_unlockLPM5();

	//enable interrupts
    __enable_interrupt();

    LCD_C_setPinAsLCDFunctionEx(LCD_C_BASE, LCD_C_SEGMENT_LINE_0, LCD_C_SEGMENT_LINE_21);
    LCD_C_setPinAsLCDFunctionEx(LCD_C_BASE, LCD_C_SEGMENT_LINE_26, LCD_C_SEGMENT_LINE_43);

    LCD_C_initParam initParams = {0};
    initParams.clockSource = LCD_C_CLOCKSOURCE_ACLK;
    initParams.clockDivider = LCD_C_CLOCKDIVIDER_1;
    initParams.clockPrescalar = LCD_C_CLOCKPRESCALAR_16;
    initParams.muxRate = LCD_C_4_MUX;
    initParams.waveforms = LCD_C_LOW_POWER_WAVEFORMS;
    initParams.segments = LCD_C_SEGMENTS_ENABLED;

    LCD_C_init(LCD_C_BASE, &initParams);

    // LCD Operation - VLCD generated internally, V2-V4 generated internally, v5 to ground
    LCD_C_setVLCDSource(LCD_C_BASE, LCD_C_VLCD_GENERATED_INTERNALLY, LCD_C_V2V3V4_GENERATED_INTERNALLY_NOT_SWITCHED_TO_PINS,
         LCD_C_V5_VSS);

    // Set VLCD voltage to 2.60v
    LCD_C_setVLCDVoltage(LCD_C_BASE, LCD_C_CHARGEPUMP_VOLTAGE_2_60V_OR_2_17VREF);

    // Enable charge pump and select internal reference for it
    LCD_C_enableChargePump(LCD_C_BASE);
    LCD_C_selectChargePumpReference(LCD_C_BASE, LCD_C_INTERNAL_REFERENCE_VOLTAGE);

    LCD_C_configChargePump(LCD_C_BASE, LCD_C_SYNCHRONIZATION_ENABLED, 0);

    // Clear LCD memory
    LCD_C_clearMemory(LCD_C_BASE);

	// Display "123456"
       // LCD Pin18-Pin19 for '1'
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_18, 0x0);
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_19, 0x6);

       // LCD Pin10-Pin11 for '2'
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_10, 0xB);
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_11, 0xD);

       // LCD Pin6-Pin7 for '3'
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_6, 0x3);
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_7, 0xF);

       // LCD Pin36-Pin37 for '4'
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_36, 0x7);
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_37, 0x6);

       // LCD Pin28-Pin29 for '5'
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_28, 0x7);
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_29, 0xB);

       // LCD Pin14-Pin15 for '6'
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_14, 0xF);
       LCD_C_setMemory(LCD_C_BASE, LCD_C_SEGMENT_LINE_15, 0xB);

       // Turn LCD on
       LCD_C_on(LCD_C_BASE);
       // Set breakpoint here to see the "123456"
       __no_operation();
       // Prepare LCD for adding new segments to old letters to make new letters
       LCD_C_off(LCD_C_BASE);
       /**
        * Rough picture representation of hex value representation to physical lines on a LCD_C
        * lower    upper
        * line     line
        * segment  segment
        *    \ 0x8
        * 0x4 |____0x4
        *   0x2  0x1 |
        * 0x8 ___/ 0x2
        *    / 0x1
        */
       // Display "Ue9A68"
       // LCD Pin18-Pin19 for changing '1' to 'U'
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_18, 0xC);
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_19, 0x1);

       // LCD Pin10-Pin11 for changing '2' to 'e'
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_10, 0x4);

       // LCD Pin6-Pin7 for changing '3' to '9'
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_6, 0x4);

       // LCD Pin36-Pin37 for changing '4' to 'A'
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_36, 0x8);
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_37, 0x8);

       // LCD Pin28-Pin29 for changing '5' to '6'
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_28, 0x8);

       // LCD Pin14-Pin15 for changing '6' to '8'
       LCD_C_setMemoryWithoutOverwrite(LCD_C_BASE, LCD_C_SEGMENT_LINE_15, 0x4);

       //Turn LCD on
       LCD_C_on(LCD_C_BASE);

      __bis_SR_register(LPM3_bits | GIE);

	return 0;
}

3, Summary

The above is what I want to talk about today. This paper only briefly introduces LCD and how to realize the display function and method on LCD.

reference resources

[1].TI https://www.ti.com/tool/MSP-EXP430FR6989
[2].TI MSP430FR6989 User Guide

Topics: Embedded system Single-Chip Microcomputer