加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專(zhuān)業(yè)用戶(hù)
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 段碼液晶分類(lèi)
    • 段碼液晶重要參數(shù)
    • 段碼液晶如何驅(qū)動(dòng)
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

STM8L052C6單片機(jī)驅(qū)動(dòng)段碼屏實(shí)例

11/01 10:12
2413
閱讀需 28 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

不得不吐槽一下,現(xiàn)在找點(diǎn)兒技術(shù)資料真是挺難的!就拿段碼液晶屏來(lái)說(shuō),這是一種很成熟而古老的技術(shù)。但是當(dāng)你項(xiàng)目里要用,想找點(diǎn)而資料,就會(huì)發(fā)現(xiàn),似乎唾手可得,可偏偏又會(huì)浪費(fèi)掉很多時(shí)間。

就拿某著名搜索引擎來(lái)說(shuō),輸入段碼液晶一搜,首先得欣賞洋洋灑灑的廣告,然后一個(gè)個(gè)鏈接點(diǎn)進(jìn)去,一會(huì)兒是只言片語(yǔ),一會(huì)兒提醒打開(kāi)另一個(gè)APP,一會(huì)兒要注冊(cè)后繼續(xù)瀏覽,有的更直接,要從此處過(guò),留下買(mǎi)路財(cái)!唉,都人工智能時(shí)代了,怎么感覺(jué)有點(diǎn)兒人工智障。

吐槽完畢,跟大家做一些分享。如果用到時(shí)希望能節(jié)省點(diǎn)兒時(shí)間。段碼屏是一種廣泛使用的低成本,低功耗顯示設(shè)備,我們留心看一下就會(huì)發(fā)現(xiàn)不少。比如遙控器,電表,電子時(shí)鐘,電動(dòng)汽車(chē)儀表盤(pán)。特別是在電池供電,而又需要顯示的場(chǎng)合,段碼液晶屏可以說(shuō)是不二之選。我們簡(jiǎn)要介紹一下段碼液晶屏的顯示原理,并以STM8L052給出一個(gè)上手即用的參考實(shí)例。

段碼液晶分類(lèi)

斷碼液晶的基本顯示原理很簡(jiǎn)單,就是利用液晶這種物質(zhì)在電場(chǎng)作用下會(huì)扭曲的特性,讓光線(xiàn)通過(guò)或不通過(guò),從而實(shí)現(xiàn)顯示。它的技術(shù)也在不斷地進(jìn)步,性能越來(lái)越好。主要分為下面幾大類(lèi):

TN(Twisted Nematic):

- 特點(diǎn):TN扭轉(zhuǎn)式向列場(chǎng)效應(yīng)是將入射光旋轉(zhuǎn)90度。

這是最為常見(jiàn)的一種液晶顯示器件,制造成本相對(duì)較低,液晶分子偏轉(zhuǎn)速度快,響應(yīng)時(shí)間較快;但視角表現(xiàn)相對(duì)較弱,一般視角范圍在50度左右。

- 應(yīng)用場(chǎng)景:廣泛應(yīng)用于計(jì)算器、遙控器、電子鬧鐘等對(duì)視角要求不是特別高、顯示內(nèi)容較為簡(jiǎn)單的小型電子設(shè)備中。

HTN(High Twisted Nematic):

- 特點(diǎn):在TN液晶屏的基礎(chǔ)上進(jìn)行了改進(jìn),液晶分子的取向扭轉(zhuǎn)角度更大,通常在110至130度。它的對(duì)比度有所提高,視角范圍也比TN更寬,可達(dá)到70度左右,并且具有功耗低、驅(qū)動(dòng)電壓低等特點(diǎn),但動(dòng)態(tài)驅(qū)動(dòng)性能較差。

- 應(yīng)用場(chǎng)景:適用于對(duì)視角范圍有一定要求,但對(duì)顯示效果要求不是特別高的設(shè)備,比如一些簡(jiǎn)單的儀器儀表等。

STN(Super Twisted Nematic):

- 特點(diǎn):顯示原理與TN相類(lèi)似,但扭轉(zhuǎn)角度更大,可以實(shí)現(xiàn)更高的對(duì)比度和更豐富的色彩顯示。普通的STN液晶屏,液晶分子可以旋轉(zhuǎn)180-270度。不過(guò),其響應(yīng)時(shí)間相對(duì)較長(zhǎng),在快速變化的畫(huà)面顯示上可能會(huì)有一定的滯后。

- 應(yīng)用場(chǎng)景:能夠滿(mǎn)足需要顯示較為復(fù)雜圖形或文字的需求,常用于一些中低端的電子設(shè)備,如電子詞典、早期的手機(jī)顯示屏等。

FSTN(Film Compensated Super Twisted Nematic):

- 特點(diǎn):在STN的基礎(chǔ)上進(jìn)一步優(yōu)化,通過(guò)在偏光片上增加補(bǔ)償膜來(lái)消除色散,實(shí)現(xiàn)更清晰的黑白顯示。其視角更寬,顯示效果更佳,對(duì)比度也較高。

- 應(yīng)用場(chǎng)景:適用于對(duì)顯示效果有較高要求的設(shè)備,如多功能電表、電力檢測(cè)儀器等。

VATN(Vertical Alignment Twisted Nematic):

- 特點(diǎn):也稱(chēng)為VA(BTN)液晶屏,具有更高的對(duì)比度和更寬廣的可視角度,顯示效果較為出色。

- 應(yīng)用場(chǎng)景:常用于一些高端顯示設(shè)備,不過(guò)由于其成本相對(duì)較高,應(yīng)用范圍相對(duì)較窄。

段碼液晶重要參數(shù)

視角

何為視角呢?以一掛時(shí)鐘來(lái)作為參考說(shuō)明視角的方向,6 點(diǎn)為仰視,3點(diǎn)為左側(cè)視,9點(diǎn)為右側(cè)視,12點(diǎn)為俯視。行業(yè)內(nèi)的名詞參數(shù):6H,9H,3H,12H.也就是我們所說(shuō)的6點(diǎn)鐘方向、9點(diǎn)鐘方向、3點(diǎn) 鐘方向、12點(diǎn)鐘方向的意思了。下圖為一個(gè)6點(diǎn)鐘視角的液晶示意圖。

視角范圍

視角范圍是指在某個(gè)特定視角內(nèi),圖像保持清晰的最大范圍。例如,TN材質(zhì)的段碼液晶屏視角范圍是50度,意味著在上下50度以?xún)?nèi)圖像清晰?。

Segment

是組成液晶顯示圖案的基本單元。比如要顯示一個(gè)數(shù)字“8”,它是由多個(gè)段組成的,這些段通過(guò)組合可以形成不同的數(shù)字、字母或者簡(jiǎn)單的圖形符號(hào)??梢园阉胂蟪善磮D的小碎片,通過(guò)點(diǎn)亮不同的片段組合出想要的形狀。

Common

公共電極。液晶顯示器的工作原理是通過(guò)在段電極SEG和公共電極COM之間施加電壓,來(lái)控制液晶分子的排列,從而實(shí)現(xiàn)顯示。多個(gè)segment會(huì)共享一個(gè)common電極,通過(guò)控制每個(gè)“segment”與“common”之間的電壓,就能控制各個(gè)“segment”是否顯示,以此來(lái)構(gòu)成完整的顯示內(nèi)容。

Duty

每個(gè)COM端掃描時(shí)間占一次完整掃描的比例,比如有4個(gè)COM,Duty就是1/4。

Bias

表明電極的驅(qū)動(dòng)電壓有幾個(gè)電平。如1/3bias表明有VSS,1/3Vlcd,2/3Vlcd,Vlcd這4個(gè)電平。兩個(gè)相鄰電平之間的差是1/3Vlcd。這里Vlcd是段碼屏的工作電壓。

還要注意屏的工作電壓,和工作溫度范圍。

段碼液晶如何驅(qū)動(dòng)

有的段碼屏自身集成驅(qū)動(dòng)芯片,對(duì)外接口常用IIC,SPI等串行總線(xiàn),這種屏成本稍高一些。有的屏不帶驅(qū)動(dòng)芯片,對(duì)外接口為COM,和SEG引腳。驅(qū)動(dòng)這種屏,需要用驅(qū)動(dòng)芯片,如HT1621,CNV1792S等。段碼屏的每個(gè)段,點(diǎn)亮的條件是在COM和SEG引腳之間施加一個(gè)壓差,壓差超過(guò)一定門(mén)限就會(huì)點(diǎn)亮。但是要注意給液晶不能施加直流信號(hào),比如COM加0V,SEG加3.3V,雖然這樣能顯示,但時(shí)間長(zhǎng)了后會(huì)由于電泳現(xiàn)象導(dǎo)致液晶損壞,顯示模糊。正確的做法是,隔一小段時(shí)間就把電壓翻轉(zhuǎn)一次,COM加3.3V,SEG變?yōu)?V,這樣交替進(jìn)行。

如果想更深入的了解原理和驅(qū)動(dòng)方法,可以參考ST的一篇官方文檔:

AN3114 How to use the STM8AL3Lxx, STM8L152xx and STM8L162xx LCD controllers

寫(xiě)的非常好。

    斷碼液晶實(shí)例

STM8L052C6是一款帶段碼液晶驅(qū)動(dòng)模塊的單片機(jī),提供了驅(qū)動(dòng)庫(kù),可以通過(guò)調(diào)用庫(kù)函數(shù),設(shè)置DUTY和BIAS,段碼顯示與否,調(diào)節(jié)對(duì)比度,閃爍頻率等。

我們用的這個(gè)段碼屏,是大連奇耘的QYT13264S(T)P10V3T,TN型,1/4Duty,1/3Bias,工作電壓3V。淘寶上可以買(mǎi)到,5塊錢(qián)左右。管腳圖,1-4管腳是COM0-COM3,5-13管腳是SEG0-SEG8。

下圖是屏和單片機(jī)的接線(xiàn)圖,stm8L052和stm8L152管腳兼容。注意VLCD這個(gè)引腳,如果配置段碼屏使用內(nèi)部電壓時(shí),斷碼屏的工作電壓VLCD由內(nèi)部的升壓電路MCU電源VDD產(chǎn)生,VLCD外接一個(gè)0.1-2uF的小電容,可以使電壓更穩(wěn)定。此引腳的電壓可以在一定范圍內(nèi)通過(guò)程序調(diào)節(jié),從而改變屏的對(duì)比度。

下面是初始化的子程序

void LCD_GLASS_Init(void)

{

/* Enable LCD/RTC clock */

CLK_PeripheralClockConfig(CLK_Peripheral_RTC, ENABLE);

CLK_PeripheralClockConfig(CLK_Peripheral_LCD, ENABLE);

#ifdef USE_LSE

CLK_RTCClockConfig(CLK_RTCCLKSource_LSE, CLK_RTCCLKDiv_1);

#else

CLK_RTCClockConfig(CLK_RTCCLKSource_LSI, CLK_RTCCLKDiv_1);

#endif

/* Initialize the LCD */

LCD_Init(LCD_Prescaler_1, LCD_Divider_31, LCD_Duty_1_4,

LCD_Bias_1_3, LCD_VoltageSource_Internal);

/* Mask register

For declare the segements used.

in the Discovery we use 0 to 8 segments. */

// 使用0-8 segments

LCD_PortMaskConfig(LCD_PortMaskRegister_0, 0xFF);

LCD_PortMaskConfig(LCD_PortMaskRegister_1, 0x01);

LCD_PortMaskConfig(LCD_PortMaskRegister_2, 0x00);

/* To set contrast to mean value */

LCD_ContrastConfig(LCD_Contrast_3V0);

LCD_DeadTimeConfig(LCD_DeadTime_0);

LCD_PulseOnDurationConfig(LCD_PulseOnDuration_1);

/* Enable LCD peripheral */

LCD_Cmd(ENABLE);

}

//設(shè)置實(shí)例使用LCD_Duty_1_4, LCD_Bias_1_3代表1/4DUTY,1/3BIAS

//LCD_PortMaskRegister_0 設(shè)置LCD_PM0寄存器,啟用的SEG對(duì)應(yīng)位置1。

如何點(diǎn)亮一個(gè)液晶的段?比如小數(shù)點(diǎn)P。下面是實(shí)現(xiàn)的子程序

void LCD_GLASS_SetP(bool P ) // P "." 小數(shù)點(diǎn)

{

if(P)

LCD->RAM[LCD_RAMRegister_0] |= 0x10; // 亮 (7:0) LCD_RAM0第4位

else

LCD->RAM[LCD_RAMRegister_0] &= 0xEF; // 滅 (7:0) LCD_RAM0第4位

}

下圖LCD_RAM0寄存器 S0[7:0] (COM0 or COM4) 內(nèi)容的每一位的值對(duì)應(yīng)著圖5 COM0和SEG0-SEG7交叉位置的元素被點(diǎn)亮還是熄滅。

小數(shù)點(diǎn)P是COM0和PIN9交叉位置。PIN9 對(duì)應(yīng)的SEG為SEG4

LCD_RAM0=0x10;代表P(小數(shù)點(diǎn)) 元素被點(diǎn)亮。

其它元素的點(diǎn)亮原理與此相同

下面是電池電量顯示部分的子程序

void LCD_GLASS_SetT(uint8_t T) //電池電量顯示

{

switch (T)

{

case 0: //PD2_LCDSEG8

LCD->RAM[LCD_RAMRegister_1] &= 0xFE; //S9清零 S0(15:8) 外框

LCD->RAM[LCD_RAMRegister_4] &= 0xEF; //S10清零 S1(11:4)

LCD->RAM[LCD_RAMRegister_8] &= 0xFE; //S12清零 S2(15:8)

LCD->RAM[LCD_RAMRegister_11] &= 0xEF; //S11清零 S3(11:4)

break;

case 1: //PD2_LCDSEG8

LCD->RAM[LCD_RAMRegister_1] |= 0x01; //S9亮 S0(15:8) 外框

LCD->RAM[LCD_RAMRegister_4] |= 0x10; //S10亮 S1(11:4)

LCD->RAM[LCD_RAMRegister_8] &= 0xFE; //S12清零 S2(15:8)

LCD->RAM[LCD_RAMRegister_11] &= 0xEF; //S11清零 S3(11:4)

break;

case 2: //PD2_LCDSEG8

LCD->RAM[LCD_RAMRegister_1] |= 0x01; //S9亮 S0(15:8) 外框

LCD->RAM[LCD_RAMRegister_4] |= 0x10; //S10亮 S1(11:4)

LCD->RAM[LCD_RAMRegister_8] &= 0xFE; //S12清零 S2(15:8)

LCD->RAM[LCD_RAMRegister_11] |= 0x10; //S11亮 S3(11:4)

break;

case 3: //PD2_LCDSEG8

LCD->RAM[LCD_RAMRegister_1] |= 0x01; //S9亮 S0(15:8) 外框

LCD->RAM[LCD_RAMRegister_4] |= 0x10; //S10亮 S1(11:4)

LCD->RAM[LCD_RAMRegister_8] |= 0x01; //S12亮 S2(15:8)

LCD->RAM[LCD_RAMRegister_11] |= 0x10; //S11亮 S3(11:4)

break;

}

}

下面是字段S1 S2 S3 S4 顯示的子程序

void LCD_GLASS_SetS(bool S1,bool S2,bool S3,bool S4) // S1 S2 S3 "%"S4 " ℃"

{

if(S1)

LCD->RAM[LCD_RAMRegister_0] |= 0x04; // 亮 (7:0) 第2位

else

LCD->RAM[LCD_RAMRegister_0] &= 0xfB; // 滅 (7:0) 第2位

if(S2)

LCD->RAM[LCD_RAMRegister_0] |= 0x01; // 亮 S0(7:0) 第1位

else

LCD->RAM[LCD_RAMRegister_0] &= 0xfE; // 滅 S0(7:0) 第1位

if(S3)

LCD->RAM[LCD_RAMRegister_11] |= 0x04; // 亮 S3(11:4) 第1位

else

LCD->RAM[LCD_RAMRegister_11] &= 0xFB; // 滅 S3(11:4) 第1位

if(S4)

LCD->RAM[LCD_RAMRegister_7] |= 0x40; // 亮 S2(7:0) 第6位

else

LCD->RAM[LCD_RAMRegister_7] &= 0xBF; // 滅 S2(7:0) 第6位

}

3個(gè)數(shù)字的顯示需要一些技巧,下面是數(shù)字部分顯示的子程序

/* =========================================================================

LCD MAPPING

A



D

An LCD character coding is based on the following matrix:

{ S , G }

{ D , B }

{ E , F }

{ C , A }

The character '9' for example is:


LSB { 0 , 1 }

{ 1 , 1 }

{ 0 , 1 }

MSB { 1 , 1 }


The character '8' for example is:


LSB { 0 , 1 }

{ 1 , 1 }

{ 1 , 1 }

MSB { 1 , 1 }


The character '7' for example is:


LSB { 0 , 0 }

{ 0 , 1 }

{ 0 , 0 }

MSB { 1 , 1 }


The character '6' for example is:


LSB { 1 , 1 }

{ 0 , 0 }

{ 1 , 1 }

MSB { 1 , 1 }


The character '5' for example is:


LSB { 0 , 1 }

{ 1 , 0 }

{ 0 , 1 }

MSB { 1 , 1 }


The character '4' for example is:


LSB { 0 , 1 }

{ 0 , 1 }

{ 0 , 1 }

MSB { 1 , 0 }


The character '3' for example is:


LSB { 0 , 1 }

{ 1 , 1 }

{ 0 , 0 }

MSB { 1 , 1 }


The character '2' for example is:


LSB { 0 , 1 }

{ 1 , 1 }

{ 1 , 0 }

MSB { 0 , 1 }


The character '1' for example is:


LSB { 0 , 0 }

{ 0 , 0}

{ 1, 1 }

MSB { 0, 0 }


The character '0' for example is:


LSB { 0 , 0 }

{ 1 , 1}

{ 1 , 1 }

MSB { 1 , 1 }


*/

const uint8_t NumberMap[10]=

{

0xEE ,0x44 ,0xB6, 0xBA, 0x78, 0xDA, 0xDD, 0xA8, 0xFE, 0xFA

};

static void LCD_Conv_Char_Seg(uint8_t* c, uint8_t* digit)

{

uint16_t ch = 0 ;

uint8_t i,j;

switch (*c)

{

case 0:

case 1:

case 2:

case 3:

case 4:

case 5:

case 6:

case 7:

case 8:

case 9:

ch = NumberMap[*c];

break;

default:

break;

}

//下面是大連奇耘段碼屏的順序

digit[0] = (ch ) & 0x03;//D S 每個(gè)digit[ ]用最低兩位

digit[1] = (ch >> 2) & 0x03;//C E

digit[2] = (ch >> 4) & 0x03;//B G

digit[3] = (ch >> 6 ) & 0x03;//A F

}

//在第position位置 顯示1個(gè)* ch 字符

void LCD_GLASS_WriteChar(uint8_t* ch, uint8_t position) {

uint8_t digit[4]; /* Digit frame buffer */

LCD_Conv_Char_Seg(ch, digit);

switch (position)

{

case 1: //十位數(shù)字

LCD->RAM[LCD_RAMRegister_0] &= 0x0fd;

LCD->RAM[LCD_RAMRegister_0] |= (uint8_t)(digit[0]& 0x02); // 1D

LCD->RAM[LCD_RAMRegister_3] &= 0x0cf;

LCD->RAM[LCD_RAMRegister_3] |= (uint8_t)(digit[1]<<4 & 0x30); // 1C 1E

LCD->RAM[LCD_RAMRegister_7] &= 0x0fc;

LCD->RAM[LCD_RAMRegister_7] |= (uint8_t)(digit[2]&0x03); // 1B 1G

LCD->RAM[LCD_RAMRegister_10] &= 0xcf;

LCD->RAM[LCD_RAMRegister_10] |= (uint8_t)((digit[3]<<4)& 0x30); // 1A 1F

break;

/* Position 2 on LCD (Digit2)*/

case 2: //個(gè)位數(shù)字

LCD->RAM[LCD_RAMRegister_0] &= 0x0f7;

LCD->RAM[LCD_RAMRegister_0] |= (uint8_t)((digit[0]<<2)&0x08); // 2D

LCD->RAM[LCD_RAMRegister_3] &= 0x3f;

LCD->RAM[LCD_RAMRegister_3] |= (uint8_t)((digit[1]<<6) & 0xc0); // 2C 2E

LCD->RAM[LCD_RAMRegister_7] &= 0xf3;

LCD->RAM[LCD_RAMRegister_7] |= (uint8_t)((digit[2]<<2)& 0x0c); // 2B 2G

LCD->RAM[LCD_RAMRegister_10] &= 0x3f;

LCD->RAM[LCD_RAMRegister_10] |= (uint8_t)((digit[3]<<6)& 0xC0); // 2A 2F

break;

/* Position 3 on LCD (Digit3)*/

case 3: //小數(shù)點(diǎn)后1位數(shù)字

LCD->RAM[LCD_RAMRegister_0] &= 0xdf;

LCD->RAM[LCD_RAMRegister_0] |= (uint8_t)(digit[0]<<4) & 0x20; // 3D

LCD->RAM[LCD_RAMRegister_4] &= 0xfc;

LCD->RAM[LCD_RAMRegister_4] |= (uint8_t)(digit[1]) & 0x03; // 3C 3E

LCD->RAM[LCD_RAMRegister_7] &= 0xcf;

LCD->RAM[LCD_RAMRegister_7] |= (uint8_t)(digit[2]<<4)&0x30; // 3B 3G

LCD->RAM[LCD_RAMRegister_11] &= 0xfc;

LCD->RAM[LCD_RAMRegister_11] |= (uint8_t)(digit[3]) & 0x03 ; // 3A 3F

break;

default:

break;

}

}

//在主函數(shù)里調(diào)用上面子函數(shù)測(cè)試一下效果

void main(void)

{

uint8_tchar_tmp;

char_tmp = 1;

LCD_GLASS_WriteChar(&char_tmp, 1);

char_tmp = 2;

LCD_GLASS_WriteChar(&char_tmp, 2);

char_tmp = 3;

LCD_GLASS_WriteChar(&char_tmp, 3);

LCD_GLASS_SetT(2);

LCD_GLASS_SetS(1,1,1,1);

//LCD_GLASS_SetS(0,0,1,1);

LCD_GLASS_SetP(1) ;

}

下面是實(shí)際效果


參考:

記一次段碼屏調(diào)試總結(jié)

AN3114 How to use the STM8AL3Lxx, STM8L152xx and STM8L162xx LCD controllers(ST官方資料)

AN1447 SOFTWARE DRIVER FOR 4-MULTIPLEXED LCD WITH A STANDARD ST62(ST官方資料)

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

TopSemic,讓芯片使用更簡(jiǎn)單。 專(zhuān)注分享:嵌入式,單片機(jī),STM32,ARM,RTOS,Linux, 軟硬件,半導(dǎo)體,電子技術(shù)等相關(guān)內(nèi)容。