MSP430FR6989系列教程之LCD
由于MSP430以追求低功耗的特性,所以在MSP430FR6989上搭载的LCD并不是我们通常意义上的LCD显示屏(TFT LCD),而是段式 LCD
MSP430FR6989系列教程之流水灯
MSP430FR6989系列教程之串口通信
MSP430FR6989系列教程之定时器
MSP430FR6989系列教程之PWM波
MSP430FR6989系列教程之LCD
前言
这次学习MSP430主要是为了备战电赛,虽然不确信一定会用到MSP430FR6989这块板子,但还是想尝试一下,毕竟未来的事谁也说不准。
MSP430系列教程之PWM波
一、LCD
-
段式LCD本质上,它由两个互成 90 度的偏光板(偏振入射到显示屏的 光线)、带通电电极的液晶(两个偏光片之间)和一个反射背板(反射穿过显示屏所有层的光线)组成。
-
当某个特定段的电极不通电时,该段“截止”或呈灰色。 在此正常状态下,液晶具有可以将光偏转 90 度的扭 曲结构。 所以在未通电时,光线首先入射到第一层偏光板上并在偏转后从同一方向射出。 然后,在光线通 过液晶时,液晶使光线偏转 90 度 - 由于此时的光线相对于经过第一层偏光板时发生了偏转,因此光线能够 穿过第二层偏光板。 最后,光线经反射背板反射并经过相同的过程返回。由于光线反射回来,所以该段看 起来是亮的或者灰色的。
-
当某个段的电极通电时,该段“导通”或呈黑色。 在通电状态下液晶不发生扭转,从而光线通过时不会发生偏 转。 所以在通电时,光线首先入射到第一层偏光板上并在偏转后从同一方向射出。 然后,光线这次只是直 接通过液晶而不发生偏转。 由于第二层偏光板与第一层成 90 度夹角,所以光线无法通过并被吸收。 这使得 该段看起来是暗的。
那么问题来了,我们如何才能驱动LCD呢?
-
必须使用交流信号驱动 LCD。 施加到 LCD 段上的直流电平可能损坏 LCD - 通常允许低于 50 mV 的直流电 压。 MSP430LCD 模块将自动生成这些类型的交流波形,使用户仅需要指定段的导通与截至 - 内部硬件将完成余下的工作。
-
LCD 段具有一个施加到两个电极(COMx 线和 Sx 段线)之间液晶的电荷。 这两个电极施加的电势差即为通过 LCD 段观察到的波形。
-
LCD 段上是否存在 RMS 电压将决定此段为导通还是截止。 图 2 中的示例波形给出了一个导通段和一个截 止段的波形(COMx 和 Sx 引脚信号的组合)。 导通段比截止段上施加了更大的 RMS 电压。 注意,这两个 段都具有净零直流电压的波形,但导通段上的 RMS 电压较高,这使得该段导通并且看起来是暗的。
在了解了这一点后,就可以开始coding了
二、代码编写
这里附上完整main.c的代码
#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;
}
三、总结
以上就是今天要讲的内容,本文仅仅简单介绍了LCD,及如何在LCD上实现显示函数和方法。
参考
[1].TI https://www.ti.com/tool/MSP-EXP430FR6989
[2].TI MSP430FR6989用户指南