STM8L182内部集成了一个高达320个像素LCD的驱动模块。框图如下:
1. 配置LCD的时钟源、分频比、占空比、偏移电压、启用LCD端口复用功能、清晰度,并使能LCD功能。
void LCD_Config(void)
{
/* Enable RTC CLK */
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
/* Enable RTC CLK */
CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE);
/* Choice CLK Source, HSI_Freq = 16M, RTC_Freq = 500Khz*/
CLK_RTCClockConfig(CLK_RTCCLKSource_HSI,CLK_RTCCLKDiv_32);
/* Frequence = 500K/(32+16) Frame_Freq = Frequence/Duty = 60Hz */
LCD_Init(LCD_Prescaler_32, LCD_Divider_16, LCD_Duty_1_8,
LCD_Bias_1_3, LCD_VoltageSource_External);
/* Enable PM */
LCD_PortMaskConfig(LCD_PortMaskRegister_0, 0xFF);
LCD_PortMaskConfig(LCD_PortMaskRegister_1, 0x0F);
LCD_PortMaskConfig(LCD_PortMaskRegister_2, 0x00);
LCD_PortMaskConfig(LCD_PortMaskRegister_3, 0x00);
LCD_PortMaskConfig(LCD_PortMaskRegister_4, 0x00);
LCD_PortMaskConfig(LCD_PortMaskRegister_5, 0x00);
/* LCD_Contrast_Level_7: Medium Density / High Density Maximum Voltage = 3.30V / 3.51V */
LCD_ContrastConfig(LCD_Contrast_Level_7);
/* No dead time */
LCD_DeadTimeConfig(LCD_DeadTime_0);
/* LCD_PulseOnDuration_7: Pulse ON duration = 7/CLKprescaler */
LCD_PulseOnDurationConfig(LCD_PulseOnDuration_7);
LCD_Cmd(ENABLE);
}
其中LCD_PortMaskRegister: The LCD register index in the port mask matrix.相关的寄存器为:
只用到12个SEG,置位PM0的8位和PM1的低4位。
2. 关闭、打开、清屏操作
void LCD_OFF(void)
{
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, DISABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_LCD, DISABLE);
}
void LCD_ON(void)
{
CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);
CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE);
}
void LCD_Clear(void)
{
uint8_t i=0;
for(i=0;i<LCD_RAMRegister_13;i++)
{LCD_PageSelect(LCD_PageSelection_FirstPage);
LCD->RAM[i]=0;
LCD_PageSelect(LCD_PageSelection_SecondPage);
LCD->RAM[i]=0;}
}
在LCD_Clear();函数中,因为项目中用到8个COM,所以有2个Page(LCD_PageSelection_FirstPage,LCD_PageSelection_FirstPage)。
3. 配置好LCD的相关寄存器,往LCD的RAM里面写数据。
例如这样一块屏:
根据规格书,的出对应的RAM列表
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | PAGE 0 | |||
0 | S0[7:0] | 4D | 3C | 3D | T26 | 2C | 2D | 1C | 1D | ||
1 | S0[15:8] | T31 | T3 | T30 | 4C | ||||||
2 | S0[23:16] | ||||||||||
3 | S1[3:0] | 2G | 2E | 1G | 1E | S0[27:24] | |||||
4 | S1[11:4] | T23 | T2 | T29 | 4G | 4E | 3G | 3E | T25 | ||
5 | S1[19:12] | ||||||||||
6 | S1[27:20] | ||||||||||
7 | S2[7:0] | 4F | 3B | 3F | T24 | 2B | 2F | 1B | 1F | ||
8 | S2[15:8] | LO | T4 | T28 | 4B | ||||||
9 | S2[23:16] | ||||||||||
10 | S3[3:0] | T17 | 2A | T15 | 1A | S3[27:24] | |||||
11 | S3[11:4] | HI | T5 | T27 | T22 | 4A | T21 | 3A | T18 | ||
12 | S3[19:12] | ||||||||||
13 | S3[27:20] |
#define a 0x01
#define b 0x02
#define c 0x04
#define d 0x08
#define e 0x10
#define f 0x20
#define g 0x40
#define NONE 0x00
const unsigned int LCD_MODEL[]=
{
{a+b+c+d+e+f}, //0
{c+b}, //1
{a+b+d+e+g}, //2
{a+c+b+d+g}, //3
{c+b+f+g}, //4
{a+c+f+d+g}, //5
{a+c+e+f+d+g}, //6
{a+c+b}, //7
{a+c+e+b+f+d+g}, //8
{a+c+b+f+d+g}, //9
}
/**
* 假如显示0,0对应的值的二进制位01111111,通过对比表中的位置,进行移位赋值操作
*/
void Display_LCD_Num(u8 NUM)
{
LCD_PageSelect(LCD_PageSelection_FirstPage);
/* 清除C、D段位的显示 */
LCD->RAM[LCD_RAMRegister_0]&=(~0x03);
/* 写入C、D段位的值 */
LCD->RAM[LCD_RAMRegister_0]|=(((LCD_MODEL[Data]>>1)&0x02)+((LCD_MODEL[Data]>>3)&0x01));
/* 清除G、E段位的显示 */
LCD->RAM[LCD_RAMRegister_3]&=(~0x30);
LCD->RAM[LCD_RAMRegister_3]|=(((LCD_MODEL[Data]>>1)&0x20)+((LCD_MODEL[Data])&0x10));
/* 清除B、F段位的显示 */
LCD->RAM[LCD_RAMRegister_7]&=(~0x03);
LCD->RAM[LCD_RAMRegister_7]|=((LCD_MODEL[Data]&0x02)+((LCD_MODEL[Data]>>5)&0x01));
/* 清除A段位的显示 */
LCD->RAM[LCD_RAMRegister_10]&=(~0x10);
LCD->RAM[LCD_RAMRegister_10]|=((LCD_MODEL[Data]<<4)&0x10); //A
}