void lcd_disp(unsigned char x,unsigned char y) { unsigned char da[8]; unsigned char j; y = 63-y; for(j=1;j<7;j++) da[j] = 0x0; {// 繪制邊框 da[0]=0x01; da[7]=0x80; if((x==0)||(x==127)) { for(j=0;j<8;j++) da[j] = 0xff; } } if(x%5==0) da[pointY>>3] |= 0x01 《 (pointY&0x07); // 繪制由變量pointY 控制的水平游標線 if(x==pointX) // 繪制由變量pointX 控制的垂直游標線 for(j=0;j<64;j++) if(j%5==0) da[j>>3] |= 0x01 《(j&0x07); da[y/8] |= 0x01《(y%8); // 繪制信號波形 lcd_row_wr(x,da); } 運行效果如圖6 所示。 圖6 水平垂直移動游標線示例 五、圖形液晶LCD12864數字符號顯示 圖形點陣LCD 顯示數字,原理是把數字以點陣的形式取模,再把點陣模寫入特定的LCD 空間即可,首先來看數字取模,如圖7 所示,對數字“0”按8×5點取模。 圖7 數字取模示例圖 縱向看,8 點一列,從上至下對應bit0 到bit7,我們用1 表示“亮”,0 表示“暗”,從左至右,依次確定為0111 1100,即0x7c ;1000 0010,即0x82 ;10000010, 即0x82 ;1000 0010, 即0x82 ;0111 1100,即0x7c ;如果我們依次將這5 個字節(jié)寫入LCD 某頁連續(xù)5個地址空間,LCD 上就會顯示“0”。 下面我們把數字變量在LCD 上動態(tài)顯示,就是數值變了,顯示跟著變。 字符顯示LCD 驅動函數,實現8×n 點陣字符寫入函數。 void lcd_put_xyns(unsigned char x,y,n,unsigned char *s) { unsigned char i; for(i=0;i<n;i++) { if((x+i)>63) { lcd_cmd_wr(ORGY+y,1); lcd_cmd_wr(ORGX+x+i-64,1); lcd_dat_wr(s[i],1); } else { lcd_cmd_wr(ORGY+y,0); lcd_cmd_wr(ORGX+x+i,0); lcd_dat_wr(s[i],0); } } } 參數:“x, y”是坐標,這里y 是頁坐標,取值從0 到7,“n”是點陣模字節(jié)數,“*s”是點陣模起始地址。 將字模生成字模表: unsigned char code number[]={ 0x7C,0x82,0x82,0x7C,0x84,0xFE,0x80,0x00,0xCC,0xA2,0x 92,0x8C,0x44,0x92,0x92,0x6C, 0x38,0x24,0xFE,0x20,0x9E,0x92,0x92,0x62,0x7C,0x92,0x9 2,0x64,0x06,0xF2,0x0E,0x02, 0x6C,0x92,0x92,0x6C,0x4C,0x92,0x92,0x7C,0x80, }; lcd_put_xyns(0,0,4,number+0*4); // 直接顯示字符0 lcd_put_xyns(4,0,4,number+1*4); // 直接顯示字符1 …… tmp=3421; // 以下代碼顯示變量tmp lcd_put_xyns(80,2,4,number+(tmp/1000)*4); lcd_put_xyns(84,2,4,number+(tmp/100%10)*4); lcd_put_xyns(88,2,4,number+(tmp/10%10)*4); lcd_put_xyns(92,2,4,number+(tmp%10)*4);
本文針對LCD12864 特性,完成了數字示波器顯示必須的繪圖驅動程序設計,這個教程定位給初學者使用,我立足從簡單到復雜一步一步介紹設計過程,甚至是調試的過程,還包括一些經驗總結,特別是提供了完整的keil 工程附件。希望讀者立足示波器項目,學到更多軟硬件設計經驗技巧。
一、簡易數字示波器原理
數字示波器基本原理可以簡單理解為:數據采集+ 圖形顯示,該過程循環(huán)進行,如圖1 所示。
圖1 簡易數字示波器流程圖
LCD 圖形顯示需要根據LCD 特性設計,不同LCD驅動程序不同,本篇將結合不帶字庫的LCD12864 設計顯示程序。
二、圖形液晶LCD12864繪圖驅動設計基礎
關于LCD 的硬件接口電路,在其他教程中有詳細介紹,涉及單片機總線知識和CPLD 內部電路,需要認真學習,這里借助現成的驅動函數,重點講解LCD繪圖程序設計。
LCD12864 的電路接口在頭文件中定義:
#define LCD_LCW XBYTE[0xf4ea]
// 左屏命令寫入
#define LCD_LDW XBYTE[0xf5ea]
// 左屏數據寫入
#define LCD_LCR XBYTE[0xf6ea]
// 左屏命令讀出
#define LCD_LDR XBYTE[0xf7ea]
// 左屏數據讀出
#define LCD_RCW XBYTE[0xf8ea]
// 右屏命令寫入
#define LCD_RDW XBYTE[0xf9ea]
// 右屏數據寫入
#define LCD_RCR XBYTE[0xfaea]
// 右屏命令讀出
#define LCD_RDR XBYTE[0xfbea]
// 右屏數據讀出
后面所有對LCD 的編程操作都是基于以上接口定義進行的各種讀寫操作。
首先來看LCD12864 的點陣結構圖,如圖2 所示。
圖2 LCD點陣分布結構圖
此LCD 屏由水平128 列,垂直64 行組成。水平128 列分左右各64 列兩個半屏構成。垂直64 行又分8 頁,每頁8 行(1 列8 點剛好1 字節(jié))。程序每次對LCD 的繪圖操作就是以最小單位1 字節(jié)進行操作的。
理解這點至關重要。也就是每次只能針對8 點進行操作,而不是1 點進行操作。左右屏由單獨地址線控制(前面的接口定義就是分左右屏定義的)。實際打點只需往指定“位置”寫入數據,“1”亮,“0”暗。
聲明控制水平線的變量“unsigned charpointY=0;” 范圍0 到63, 聲明控制垂直線的變量“unsigned char pointX=0;”范圍0 到127。