段式液晶程序設計技巧
一、段式液晶的基本參數
1.Duty:佔空比
該項參數一般也稱爲Duty數或者com數,段式液晶一般採用時分動態掃描的驅動模式,此模式下,每個com的有效選通時間與整個掃描週期的比值即佔空比是固定的,等於1/com數。
2.Bias:偏置
LCD的SEG/COM的驅動波形爲模擬信號,而各檔模擬電壓相對於LCD輸出的最高電壓的比例稱爲偏置,而一般來講,Bias是以最低一檔與輸出最高電壓的比值來表示。一般而言,bias和duty之間是有一定聯繫的,duty數越多,每根com對應的掃描時間變短,而要達到同樣的顯示亮度和顯示對比度,von的電壓就要提高,選電平和非選電平的差異需要加大,即Bias需要加大,Duty和Bias間有一個經驗公式,即:
Bias = 1/(√Duty + 1)
3.VDD:工作電壓
液晶分子是需要交流信號來驅動的,長時間的直流電壓加在液晶分子兩端,會影響液晶分子的電氣化學特性,引起顯示模糊,壽命減少,其破壞性不可恢復。
4.Frame:掃描幀頻
掃描頻率,直接驅動液晶分子的交流電壓的頻率一般在60~100Hz之間,具體是依據LCDPanel的面積和設計而定,頻率過高,會導致驅動功耗的增加,頻率過低,會導致顯示閃爍,同時如果掃描頻率同光源的頻率之間有整數倍關係,則顯示也會有閃爍現象出現。
其他諸如可視角度,連接方式,工作溫度範圍之類的,那就根據具體需求讓供應商做就好了;
二、段碼液晶屏真值表
這個如果設計好了,程序寫起來也會方便很多,以下面的爲例:
主要是中間8個顯示數字的段碼,所有的最好按照同樣的規律排布:
這樣我們就好計算出顯示不同數字所需要的數組:
然後將數組寫到程序中:
至於如何控制段碼屏顯示,有的MCU如MSP4304152支持段碼驅動,如果不支持可以使用專門的驅動IC如HT1621B/HT1622等,驅動搞定之後,無非就是寫入數據,每個數據位控制對應的段碼顯示還是不顯示;
道理都一樣,但是使用一些C語言的技巧會使程序更簡潔,效率更高;
下面要介紹的就是一個結構體和一個數組組合爲一個共用體:
typedef union _DISPLAY{
struct{
unsigned NUM4:8;
unsigned NUM5_3:3;//低位開始
unsigned S14_KBIT:1;
unsigned NUM5_4:4;
unsigned NUM6_3:3;
unsigned S13_RH:1;
unsigned NUM6_4:4;
unsigned NUM7_3:3;
unsigned S10_BOT_P:1;
unsigned NUM7_4:4;
unsigned NUM0:8;
unsigned NUM1_3:3;
unsigned S12_F:1;
unsigned NUM1_4:4;
unsigned NUM2_3:3;
unsigned S11_C:1;
unsigned NUM2_4:4;
unsigned NUM3_3:3;
unsigned S9_TOP_P:1;
unsigned NUM3_4:4;
unsigned S5_BAUD:1;
unsigned S6_ADR:1;
unsigned S7_TX:1;
unsigned S8_RX:1;
unsigned S1_WARNNING:1;
unsigned S2_HI:1;
unsigned S3_LO:1;
unsigned S4_SET:1;
}Segment;
//段碼真值表中對應到SEG18*4 = 72 ,共72個段碼,這裏是以一個字節(8bit)爲單位寫數據,所以數組大小爲72/8 = 9
UINT8 Content[9];
}DISPLAY;
void AppLCDShowVersionAddr(void)
{
UINT8 i,*Point;
CommSet.Addr = ParaRO.Item.Serial[0];
UINT8 temp = CommSet.Addr;
for (i = 0; i < DISP_LEN; i++)//Clear Display
Display.Content[i] = 0;
Display.Segment.S9_TOP_P = ON; //單獨控制某一個段碼
Display.Content[4] |= NUMBER[BLANK];//控制整個數碼顯示對應內容
Display.Content[5] |= NUMBER[CHAR_U];
Display.Content[6] |= NUMBER[ParaRO.Item.Version[3]-48];
Display.Content[7] |= NUMBER[ParaRO.Item.Version[4]-48];
Display.Content[3] |= NUMBER[temp % 10];
temp /= 10;
Display.Content[2] |= NUMBER[temp % 10];
Display.Content[1] |= NUMBER[temp /= 10];
/*********************LCDUpdate**********************/
Point = (void *)&LCDM1;
for(i=0;i<DISP_LEN;i++)//填充完數組後直接用數組刷新所有顯示內容
*Point++ = Display.Content[i];
}