HT1621液晶驅動

1. 概述
HT1621是128點內存映象和多功能的LCD驅動器,HT1621的軟件配置特性使它適用於多種LCD應用場合,包括LCD模塊和顯示子系統。用於連接主控制器和HT1621的管腳只有4或5條,HT1621還有一個節電命令用於降低系統功耗。
在虎風所做的這個系統中ht1621用於驅動一個靜態的LCD液晶顯示器。液晶顯示的方式分爲靜態顯示和動態顯示。靜態與動態的區別在於靜態顯示是持續供電的,而動態顯示是利用人的視覺停留效果,快速掃描數碼管各個段,讓人在視覺上感覺到數碼管是同時顯示的。
2. HT1621接線原理圖

3. 靜態LCD結構圖

4. 幾個曾經糾結的概念
Time base:時基,即時間基準,可以用來輸出,作爲外部時鐘的時間基準。
佔空比:將所有公共電極(COM)各施加一次掃描電壓的時間叫一幀,單位時間內掃描多少幀的頻率叫幀頻,將掃描公共電極(COM)選通的時間與幀週期之比叫佔空比。通常佔空比等於公共電極數N的倒數,即1/N。這就是說假如你要驅動4個液晶,就需要4個COM,那麼你的佔空比就要設定爲1/4。
偏壓比:指的是液晶的偏壓係數,可以看看專業技術文章,偏壓目的是克服交叉效應,通過把半選擇點與非選擇點的電壓平均,適度提高非選擇點的電壓來抵消半選擇點上的一部分電壓,使半選擇點上的電壓下降,從而提高顯示對比度;後來行半選擇點和非選擇點上的電壓均爲顯示電壓的1/a,1/a就稱爲偏壓係數,也稱爲偏壓。此方法稱爲1/a偏壓的平均電壓法,簡稱爲1/a偏壓法。
VLCD(LCD驅動電壓): LCD的驅動電壓爲加在點亮部分的段電壓與公共電壓之差(峯-峯值)。
5. 關於RAM地址映射的概念
爲了這個問題困擾了很久,虎風太愚鈍啦……
Ht1621有一個324的LCD驅動,映射到324的RAM地址。

上圖中寫命令101後面跟6位RAM地址,那麼這個地址是如何確定的呢?其實說白了也很簡單,RAM地址就是SEG的序號。我們要點亮一段液晶管需要給他提供一個電平,而這個電平是由SEG管腳提供的,SEG管腳電平的輸出又取決於對應RAM地址中的值。
驅動一個8段數碼管的順序是A,B,C,D,E,F,G,DP,我們認爲前面LCD結構圖中的數碼管3爲我們要顯示的低位,那麼連接原理圖中A3的是SEG12,我們就說此時的RAM地址爲0b001100,連接B3的是SEG11,對應的RAM地址爲0b001011,依次類推,首位數碼管的所有地址爲:
0b001100,0b001011,0b001010,0b001001,0b001000,0b001101,0b001110,0b000111//DP2;
其餘地址類似,在此不再解釋。
6. 程序
Unsigned char LCD_ADD[]={0b00001100,0b00110100,0b00010100,0b00100100,0b00000100,0b00101100,0b00011100,0b00111000,0b00000010,

0b00111100,0b00011000,0b00101000,0b00001000,0b00100010,0b00010010,0b00110000,0b00001010,0b00110010,

0b00010000,0b00100000,0b00000000,0b00101010,0b00011010};

void HT1621_Dis_Char(unsigned char d,unsigned char d_loca)
{
unsigned char j;
unsigned char seg_cnt=8 ;
if (d_loca==(HT1621_DATA_NUM-1))
seg_cnt=7;
//送3位模式碼101及6位首地址000000 0b000000101
for (j=0; j<seg_cnt; j++) //送cache_size組數據
{ HT1621_PORT&=~_BV(HT1621_CS);
HT1621_Send_Bits(0x05,3); //送寫命令代碼101,高到低
HT1621_Send_Bits(LCD_ADD[d_loca*8+j],6); //送每段對應的地址
HT1621_Send_Bits(d&0x01,4); //送數據,com0對應的低位,低到高
d=d>>1;//右移位
HT1621_PORT|=_BV(HT1621_CS);
}
}

/*=顯示小數點=
輸入參數:Poi_loca,爲小數點的位置(0是首位,1是次位)
/
void HT1621_Pri_Point(unsigned char Poi_loca)
{
unsigned char seg_cnt=8;
if (Poi_loca<2)
{ HT1621_PORT&=~_BV(HT1621_CS);
HT1621_Send_Bits(0x05,3); //送寫命令代碼101
HT1621_Send_Bits(LCD_ADD[Poi_locaseg_cnt+7],6); //送點對應的地址
//送數據
HT1621_Send_Bits(1,4);
HT1621_PORT|=_BV(HT1621_CS);
}
}

/********************************************************
=======顯示INT型數據
dat–待顯示數據
********************************************************/
void HT1621_Print_onlyInt(unsigned long dat)
{
unsigned char i;
unsigned char data[HT1621_DATA_NUM];
if (dat>=HT1621_DATA_max)
dat=dat%HT1621_DATA_max;
for(i=0;i<HT1621_DATA_NUM;i++) data[i]=LCD_CODE[HT1621_NoPrint_Loc];//初始化爲不顯示
if(dat<10) data[0] = LCD_CODE[(unsigned char) (dat)]; //個位數
else if(dat<100) {data[1] =LCD_CODE[(unsigned char) (dat/10)];
data[0] =LCD_CODE[(unsigned char) (dat%10)] ;} //十位數
else {
data[2] =LCD_CODE[(unsigned char) (dat/100%10)];
data[1] =LCD_CODE[(unsigned char) (dat/10%10)] ;
data[0] =LCD_CODE[(unsigned char) (dat%10)];
} //百位數
for(i=0;i<HT1621_DATA_NUM;i++)//從低位到高位,調用顯示每個數的函數HT1621_Dis_Char
HT1621_Dis_Char(data[i],i);
}

/*********************************************************/
//打印INT型數據
//dat–待顯示數據
//chk–顯示的數據位數: 0–關閉 1~3時,顯示對應的數據;大於3時只顯示3位;(從左到右)
//point_loc–顯示的小數點的位置:0以及大於2時:不顯示小數點;1-顯示首位,2-顯示次位;(從左到右)
/*********************************************************/
void HT1621_Print_Int(unsigned long dat,unsigned char chk,unsigned char point_loc)
{
unsigned char i;
unsigned char data[HT1621_DATA_NUM];

//chk爲0,則屏幕不顯示
for(i=0;i<HT1621_DATA_NUM;i++) data[i]= LCD_CODE[HT1621_NoPrint_Loc];

if(chk>0) {data[0] =  LCD_CODE[(unsigned char) (dat%10)];
       dat=dat/10;    }
if(chk>1) {data[1] =  LCD_CODE[(unsigned char) (dat%10)];
      dat=dat/10;    }
1
2
3
4
if(chk>2) {data[2] = LCD_CODE[(unsigned char) (dat%10)];
}
//顯示小數點
if (point_loc1)
data[0]|=0x80;
else if (point_loc2)
data[1]|=0x80;
//從低位到高位,調用顯示每個數的函數HT1621_Dis_Char
for(i=0;i<HT1621_DATA_NUM;i++)
HT1621_Dis_Char(data[i],i);

}

/*********************************************************/
//送d_count位數據d;從低位開始送
/*********************************************************/
void HT1621_Send_Bits(unsigned char d, unsigned char d_count)
{
unsigned char j;

for (j=0; j<d_count; ++j)
{

    HT1621_PORT&=~_BV(HT1621_WR);       //wr置低;
    HT1621_Delay(50);

  if (d & 0x01==1)    //置數據位;
1
2
3
4
{ HT1621_PORT|=_BV(HT1621_DATA); //data置0
}
else
{ HT1621_PORT&=~_BV(HT1621_DATA); //data置1
}
HT1621_PORT|=_BV(HT1621_WR); //wr置高;
HT1621_Delay(50);
d =(d>>1); //右移位
}
}

/*********************************************************/
//HT1621初始化
/*********************************************************/
void HT1621_Init()
{

DDRC |= _BV(4)|_BV(5)|_BV(7); //定義端口PC4-PC5-PC7輸出
HT1621_PORT&=~_BV(HT1621_CS); //CS端清零
HT1621_Send_Bits(0x01,3); //送3位命令模式碼100 0x80=0b10000000
HT1621_Send_Bits(0x18,9); //系統時鐘選用片內RC
HT1621_Send_Bits(0x80,9); //打開系統振盪器
HT1621_Send_Bits(0x94,9); //1/2偏置,2個公共口 1000 0100
HT1621_Send_Bits(0xc0,9); //打開LCD偏置發生器
HT1621_PORT|=_BV(HT1621_CS); //CS端置1
HT1621_NoPrint( ); //液晶不顯示
}
7. 結束
HT1621作爲液晶驅動芯片,功能十分靈活,而液晶在我們的學習項目中會經常用到,所以學好它的操作是十分必要的。
如果你看了這篇文章還不明白,可以留言互相討論哦,嘎嘎!
--------------------- 
作者:晶拓 
來源:CSDN 
原文:https://blog.csdn.net/qq_43188920/article/details/82773994 
版權聲明:本文爲博主原創文章,轉載請附上博文鏈接!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章