我發現前面幾篇對圖畫顯示RAM (GDRAM)介紹的不是很詳細,我就在下面再詳細地介紹一下:圖畫顯示RAM(GDRAM)
本文引用地址:http://www.j9360.com/article/201611/322842.htm提供64*256位元的GDRAM提供64*32個位元組的記憶空間(由擴充指令設定繪圖RAM地址),最多可以控制256*64點的二維繪圖緩存空間。在更改繪圖RAM時,由擴充指令設定GDRAM地址,先設垂直地址,再設水平地址(連續寫入兩個位元組的資料來完成垂直與水平的坐標地址)。再寫入兩個8位元的資料到繪圖RAM,而地址計數器(AC)會自動加一,整個寫入繪圖RAM的步驟如下:
(1),先將垂直的位元組坐標(Y)寫入繪圖RAM地址
(2),再將水平坐標(X)寫入繪圖RAM地址
(3),將D15~D8寫入RAM中(寫入第一個bytes)。
(4),將D7~D0寫入到RAM中(寫入第二個bytes)。
當顯示圖形的時候,默認的將128*64的液晶模塊分成了32*16的16塊,地址分別是80H-8FH,顯示時候可分為兩個部分給數據.這時就可以看為32*128的兩塊。
注意圖形顯示時候的每一個字節地址所對應的位置。每行共八個模塊,共送兩次,開始地址分別為80H和88H。
也就是顯示的時候會只用到GDRAM的前0~31行,共有0~255列,列又分每16列為一個大列,所以有0~15共16大列。也可以像上面那樣理解為分成了32*16的16個模塊,地址分別為80H-8FH。
然后把這16個模塊分成兩行顯示,所以每一行是8個32*16模塊,也就是32*128。所以這兩行的起始地址分別為80H和88H。所以在寫入圖形數據的時候會分兩次寫入,先寫入第一行的8個32*16模塊,再寫入第二行的8個32*16模塊。
在寫入數據的時候要注意,要先輸入垂直地址,再輸入水平地址。
上面的對GDRAM進行分塊及分行進行顯示都是液晶出廠時默認設定好的,我們用的時候就直接對相應位置的RAM進行寫入數據就可以了。
所以由上面顯示圖片的原理的介紹就可以看出12864液晶只能顯示GDRAM的一半,只用了全部GDRAM的一半。
清除了上面GDRAM的工作原理,那么GDRAM圖片數據的寫入和GDRAM清除程序就不難理解了。程序下面給出,注釋的也很詳細。
有了上面的介紹,那么再看下面對GDRAM的操作(如:清除,數據等)就會明白很多了,下面是對GDRAM的清除函數,注釋的也比較詳細:
清除GDRAM的函數如下:
voidClear_GDRAM(void)//清除GDRAM中的的隨機數據。因為上電后GDRAM中的數據是隨機的,如果不清除而直接打開GDRAM顯示時,會顯示亂碼
//所以在局部使用GDRAM顯示圖形時,要先清除隨機數據。如果是全局使用GDRAM,即整個lcd屏全部設置顯示數據,則可以
//不必清除,因為新數據會把隨機數據給覆蓋掉
{
uchari,j,k;
wr_lcd(comm,0x34);//打開擴展指令集操作GDRAM是擴展指令集
i=0x80;
for(j=0;j<32;j++)//寫入第一行的8個32*16模塊
{
wr_lcd(comm,i++);//寫入第一行8個32*16模塊的垂直起始地址,在寫入地址時,要先輸入垂直地址,再輸入水平地址這是規定好的
wr_lcd(comm,0x80);//第一行水平的起始地址為80H
//以后寫入數據后,地址計數器(AC)會自動加一
for(k=0;k<16;k++)
{
wr_lcd(dat,0x00);//寫入空字符,就相當于清零
//寫入32*16個圖片數據因為一個數據是8位的,所以這一次就相當于寫入了8個數據,所以一共為8個32*16模塊
}
}
i=0x80;
for(j=0;j<32;j++)//寫入第二行的8個32*16模塊
{
wr_lcd(comm,i++);//寫入第一行8個32*16模塊的垂直起始地址,在寫入地址時,要先輸入垂直地址,再輸入水平地址這是規定好的
wr_lcd(comm,0x88);//第二行的水平起始地址為88H
//以后寫入數據后,地址計數器(AC)會自動加一
for(k=0;k<16;k++)
{
wr_lcd(dat,0x00);//寫入32*16個圖片數據因為一個數據是8位的,所以這一次就相當于寫入了8個數據,所以一共為8個32*16模塊
//寫入空字符,就相當于清零
}
}
wr_lcd(comm,0x30);//回到基本指令集
}
向GDRAM的寫函數如下:
voidDraw_PM(constuchar*ptr)//整屏顯示圖形
{
uchari,j,k;
wr_lcd(comm,0x34);//打開擴展指令集
i=0x80;
for(j=0;j<32;j++)//寫入第一行的8個32*16模塊
{
wr_lcd(comm,i++);//寫入第一行8個32*16模塊的垂直起始地址,在寫入地址時,要先輸入垂直地址,再輸入水平地址這是規定好的
wr_lcd(comm,0x80);//第一行水平的起始地址為80H
//以后寫入數據后,地址計數器(AC)會自動加一
for(k=0;k<16;k++)
{
wr_lcd(dat,*ptr++);//寫入32*16個圖片數據因為一個數據是8位的,所以這一次就相當于寫入了8個數據,所以一共為8個32*16模塊
//這些16進制數,一共可以控制32*16*8個像素
}
}
i=0x80;
for(j=0;j<32;j++)//寫入第二行的8個32*16模塊
{
wr_lcd(comm,i++);//寫入第一行8個32*16模塊的垂直起始地址,在寫入地址時,要先輸入垂直地址,再輸入水平地址這是規定好的
wr_lcd(comm,0x88);//第二行的水平起始地址為88H
//以后寫入數據后,地址計數器(AC)會自動加一
for(k=0;k<16;k++)
{
wr_lcd(dat,*ptr++);//寫入32*16個圖片數據因為一個數據是8位的,所以這一次就相當于寫入了8個數據,所以一共為8個32*16模塊
//這些16進制數,一共可以控制32*16*8個像素
}
}
wr_lcd(comm,0x36);//打開繪圖顯示
wr_lcd(comm,0x30);//回到基本指令集
}
最后在說一個簡單的函數,拿到液晶時,我們希望檢查一下液晶是不是好的,是不是所有的點都是可用的,就要寫一個檢查液晶的函數。原理很簡單,就是把液晶的所有的像素點都點亮,看看有沒有壞點就可以了,函數,如下,和寫GDRAM,清除GDRAM的函數基本相同,只不過向GDRAM中寫入的是全1,點亮所有的像素點,函數如下:
voidcheck_screen(void)//點亮全屏,檢查壞點
{
uchari,j,k;
wr_lcd(comm,0x34);//打開擴展指令集操作GDRAM是擴展指令集
i=0x80;
for(j=0;j<32;j++)//寫入第一行的8個32*16模塊
{
wr_lcd(comm,i++);//寫入第一行8個32*16模塊的垂直起始地址,在寫入地址時,要先輸入垂直地址,再輸入水平地址
wr_lcd(comm,0x80);//第一行水平的起始地址為80H
//以后寫入數據后,地址計數器(AC)會自動加一
for(k=0;k<16;k++)
{
wr_lcd(dat,0xff);//全部點亮屏幕
//寫入32*16個圖片數據因為一個數據是8位的,所以這一次就相當于寫入了8個數據,所以一共為8個32*16模塊
}
}
i=0x80;
for(j=0;j<32;j++)//寫入第二行的8個32*16模塊
{
wr_lcd(comm,i++);//寫入第一行8個32*16模塊的垂直起始地址,在寫入地址時,要先輸入垂直地址,再輸入水平地址
wr_lcd(comm,0x88);//第二行的水平起始地址為88H
//以后寫入數據后,地址計數器(AC)會自動加一
for(k=0;k<16;k++)
{
wr_lcd(dat,0xff);//全部點亮屏幕
//寫入32*16個圖片數據因為一個數據是8位的,所以這一次就相當于寫入了8個數據,所以一共為8個32*16模塊
}
}
wr_lcd(comm,0x36);//打開繪圖顯示
wr_lcd(comm,0x30);//回到基本指令集
}
評論