第78節(jié):多個窗口里移動光標設置參數的液晶屏菜單程序
上一節(jié)講了1個窗口下如何設置參數的菜單程序,這一節(jié)多增加1個窗口變成2個窗口,看看它們兩個窗口之間是如何通過按鍵程序進行切換的。繼續(xù)鞏固上一節(jié)教給大家的兩個知識點:
第一個知識點:我在前面講數碼管顯示的時候就提出了一個 “一二級菜單顯示理論”:凡是人機界面顯示,不管是數碼管還是液晶屏,都可以把顯示的內容分成不同的窗口來顯示,每個顯示的窗口中又可以分成不同的局部顯示。其中窗口就是一級菜單,用ucWd變量表示。局部就是二級菜單,用ucPart來表示。不同的窗口,會有不同的更新顯示變量ucWdXUpdate來對應,表示整屏全部更新顯示。不同的局部,也會有不同的更新顯示變量ucWdXPartYUpdate來對應,表示局部更新顯示。把每一個窗口的內容分為兩種類型,一種類型是那些不用經常刷新顯示的內容,只有在切換窗口的時候才需要更新的,這種內容放在整屏更新顯示的括號里,比如清屏操作等內容。另外一種是那些經常需要刷新顯示的內容,這種內容放在局部更新顯示的括號里。
第二個知識點:按鍵如何跟液晶屏顯示有機的結合起來?只要遵循鴻哥總結出來的一個規(guī)律“在不同的窗口下,根據不同的局部變量來操作不同的參數”,這樣再復雜的人機交互程序都會顯得很簡單清晰。
具體內容,請看源代碼講解。
(1)硬件平臺:基于朱兆祺51單片機學習板。加按鍵對應S1鍵,減按鍵對應S5鍵,切換“光標”移動按鍵對應S9鍵,設置參數按鍵對應S13鍵。
(2)實現功能:
通過按鍵設置8個不同的參數。
有2個窗口。每個窗口顯示4個參數。每個參數的范圍是從0到99。
有4個按鍵:
(a) 一個是設置參數S13按鍵,按下此按鍵,液晶屏的第1個窗口第一行會出現反顯的光標,表示進入設置參數模式,再次按下此按鍵,反顯光標會消失,并且強行切換到第1個窗口,表示退出設置參數模式。
(b) 一個是移動光標S9按鍵,在進入設置參數的模式下,依次按下此按鍵,液晶屏上的光標會從上往下移動,表示選中不同的參數。當移動到每個窗口最下邊那一行時,再按下此按鍵會進行切換窗口的操作。
(c) 一個是減數S5按鍵,在設置參數模式下,依次按下此按鍵,被選中的參數會逐漸減小。
(d) 一個是加數S1按鍵,在設置參數模式下,依次按下此按鍵,被選中的參數會逐漸加大。
(3)源代碼講解如下:
- #include "REG52.H"
- /* 注釋一:
- * 本程序用到的變量比較多,所以在keil編譯模式里要設置一下編譯模式memory model,
- * 否則編譯會出錯.右鍵單擊Target選擇“Options for TargetTarget1”就會出來一個框
- * 在memory model中選擇compact:variables in pdata 就可以了。
- */
- #define const_voice_short40 //蜂鳴器短叫的持續(xù)時間
- #define const_key_time120 //按鍵去抖動延時的時間
- #define const_key_time220 //按鍵去抖動延時的時間
- #define const_key_time320 //按鍵去抖動延時的時間
- #define const_key_time420 //按鍵去抖動延時的時間
- sbit key_sr1=P0^0; //對應朱兆祺學習板的S1鍵
- sbit key_sr2=P0^1; //對應朱兆祺學習板的S5鍵
- sbit key_sr3=P0^2; //對應朱兆祺學習板的S9鍵
- sbit key_sr4=P0^3; //對應朱兆祺學習板的S13鍵
- sbit key_gnd_dr=P0^4; //模擬獨立按鍵的地GND,因此必須一直輸出低電平
- sbit beep_dr=P2^7; //蜂鳴器的驅動IO口
- sbitLCDCS_dr= P1^6;//片選線
- sbitLCDSID_dr = P1^7;//串行數據線
- sbitLCDCLK_dr = P3^2;//串行時鐘線
- sbitLCDRST_dr = P3^4;//復位線
- void SendByteToLcd(unsigned char ucData);//發(fā)送一個字節(jié)數據到液晶模塊
- void SPIWrite(unsigned char ucWData, unsigned char ucWRS); //模擬SPI發(fā)送一個字節(jié)的命令或者數據給液晶模塊的底層驅動
- void WriteCommand(unsigned char ucCommand); //發(fā)送一個字節(jié)的命令給液晶模塊
- void LCDWriteData(unsigned char ucData); //發(fā)送一個字節(jié)的數據給液晶模塊
- void LCDInit(void);//初始化函數內部包括液晶模塊的復位
- void display_clear(unsigned char ucFillDate); // 清屏 全部顯示空填充0x00 全部顯示點陣用0xff
- void insert_buffer_to_canvas(unsigned int x,unsigned int y,const unsigned char*ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount);//把字模插入畫布.
- void display_lattice(unsigned int x,unsigned int y,const unsigned char*ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount,unsigned int uiOffSetAddr); //顯示任意點陣函數
- unsigned char *number_to_matrix(unsigned charucBitNumber); //把一位數字轉換成字模首地址的函數
- void delay_short(unsigned int uiDelayshort); //延時
- void delay_long(unsigned int uiDelayLong);
- void T0_time(); //定時中斷函數
- void key_service(void); //按鍵服務的應用程序
- void key_scan(void);//按鍵掃描函數 放在定時中斷里
- void initial_myself();
- void initial_peripheral();
- void lcd_display_service(void); //應用層面的液晶屏顯示程序
- void clear_all_canvas(void);//把畫布全部清零
- void wd1(void);//窗口1顯示的內容
- void wd2(void);//窗口2顯示的內容
- code unsigned char Zf816_0[]=
- {
- /*--文字:0--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
- };
- code unsigned char Zf816_1[]=
- {
- /*--文字:1--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,
- };
- code unsigned char Zf816_2[]=
- {
- /*--文字:2--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,
- };
- code unsigned char Zf816_3[]=
- {
- /*--文字:3--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
- };
- code unsigned char Zf816_4[]=
- {
- /*--文字:4--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,
- };
- code unsigned char Zf816_5[]=
- {
- /*--文字:5--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
- };
- code unsigned char Zf816_6[]=
- {
- /*--文字:6--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
- };
- code unsigned char Zf816_7[]=
- {
- /*--文字:7--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
- };
- code unsigned char Zf816_8[]=
- {
- /*--文字:8--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,
- };
- code unsigned char Zf816_9[]=
- {
- /*--文字:9--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,
- };
- code unsigned char Zf816_nc[]=//空字模
- {
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- };
- code unsigned char Zf816_mao_hao[]=//冒號
- {
- /*--文字::--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=8x16 --*/
- 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,
- };
- code unsigned char Hz1616_yi[]=
- {
- /*--文字:一--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=16x16 --*/
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0xFE,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- };
- code unsigned char Hz1616_er[]=
- {
- /*--文字:二--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=16x16 --*/
- 0x00,0x00,0x00,0x10,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
- };
- code unsigned char Hz1616_san[]=
- {
- /*--文字:三--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=16x16 --*/
- 0x00,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,
- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,
- };
- code unsigned char Hz1616_si[]=
- {
- /*--文字:四--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=16x16 --*/
- 0x00,0x00,0x7F,0xFC,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,
- 0x48,0x84,0x48,0x7C,0x50,0x04,0x60,0x04,0x40,0x04,0x7F,0xFC,0x40,0x04,0x00,0x00,
- };
- code unsigned char Hz1616_chuang[]=
- {
- /*--文字:窗--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=16x16 --*/
- 0x01,0x00,0x00,0x80,0x7F,0xFE,0x40,0x22,0x09,0x18,0x12,0x06,0x7F,0xF8,0x11,0x08,
- 0x13,0xE8,0x14,0x48,0x1A,0x88,0x11,0x08,0x12,0x88,0x14,0x08,0x1F,0xF8,0x10,0x08,
- };
- code unsigned char Hz1616_kou[]=
- {
- /*--文字:口--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=16x16 --*/
- 0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,
- 0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x20,0x08,0x20,0x08,0x00,0x00,0x00,0x00,
- };
- code unsigned char Hz1616_hang[]=
- {
- /*--文字:行--*/
- /*--宋體12;此字體下對應的點陣為:寬x高=16x16 --*/
- 0x08,0x00,0x1C,0x00,0x31,0xFC,0x40,0x00,0x88,0x00,0x0C,0x00,0x1B,0xFE,0x30,0x20,
- 0x50,0x20,0x90,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0xA0,0x10,0x40,
- };
- unsigned char ucCanvasBuffer[]= //畫布顯示數組。注意,這里沒有code關鍵字,是全局變量。初始化全部填充0x00
- {
- 0x00,0x00,0x00,0x00,//上半屏
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- //------------上半屏和下半屏的分割線-----------
- 0x00,0x00,0x00,0x00,//下半屏
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x00,
- };
- unsigned char ucKeySec=0; //被觸發(fā)的按鍵編號
- unsigned intuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數器
- unsigned char ucWd=1; //窗口變量
- unsigned char ucPart=0; //局部變量 0代表沒有選中任何一行,其它數值1到4代表選中某一行
- unsigned char ucWd1Update=1; //窗口1的整屏更新顯示變量 1代表更新顯示,響應函數內部會清零
- unsigned char ucWd1Part1Update=0; //窗口1的第1行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucWd1Part2Update=0; //窗口1的第2行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucWd1Part3Update=0; //窗口1的第3行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucWd1Part4Update=0; //窗口1的第4行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucWd2Update=0; //窗口2的整屏更新顯示變量 1代表更新顯示,響應函數內部會清零
- unsigned char ucWd2Part1Update=0; //窗口2的第1行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucWd2Part2Update=0; //窗口2的第2行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucWd2Part3Update=0; //窗口2的第3行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucWd2Part4Update=0; //窗口2的第4行局部更新顯示變量1代表更新顯示,響應函數內部會清零
- unsigned char ucData_1_1=8;//第1個窗口第1行的被設置數據
- unsigned char ucData_1_2=9;//第1個窗口第2行的被設置數據
- unsigned char ucData_1_3=10;//第1個窗口第3行的被設置數據
- unsigned char ucData_1_4=11;//第1個窗口第4行的被設置數據
- unsigned char ucData_2_1=12;//第2個窗口第1行的被設置數據
- unsigned char ucData_2_2=13;//第2個窗口第2行的被設置數據
- unsigned char ucData_2_3=14;//第2個窗口第3行的被設置數據
- unsigned char ucData_2_4=15;//第2個窗口第4行的被設置數據
- void main()
- {
- initial_myself(); //第一區(qū),上電后馬上初始化
- delay_long(100); //一線,延時線。延時一段時間
- initial_peripheral();//第二區(qū),上電后延時一段時間再初始化
- while(1) //第三區(qū)
- {
- key_service(); //按鍵服務的應用程序
- lcd_display_service(); //應用層面的液晶屏顯示程序
- }
- }
- void initial_myself()//第一區(qū) 上電后馬上初始化
- {
- /* 注釋二:
- * 矩陣鍵盤也可以做獨立按鍵,前提是把某一根公共輸出線輸出低電平,
- * 模擬獨立按鍵的觸發(fā)地,本程序中,把key_gnd_dr輸出低電平。
- * 朱兆祺51學習板的S1和S5兩個按鍵就是本程序中用到的兩個獨立按鍵。
- */
- key_gnd_dr=0; //模擬獨立按鍵的地GND,因此必須一直輸出低電平
- beep_dr=1; //用PNP三極管控制蜂鳴器,輸出高電平時不叫。
- TMOD=0x01;//設置定時器0為工作方式1
- TH0=0xf8; //重裝初始值(65535-2000)=63535=0xf82f
- TL0=0x2f;
- }
- void initial_peripheral() //第二區(qū) 上電后延時一段時間再初始化
- {
- LCDInit(); //初始化12864 內部包含液晶模塊的復位
- EA=1; //開總中斷
- ET0=1; //允許定時中斷
- TR0=1; //啟動定時中斷
- }
- void T0_time() interrupt 1
- {
- TF0=0;//清除中斷標志
- TR0=0; //關中斷
- key_scan(); //按鍵掃描函數
- if(uiVoiceCnt!=0)
- {
- uiVoiceCnt--; //每次進入定時中斷都自減1,直到等于零為止。才停止鳴叫
- beep_dr=0;//蜂鳴器是PNP三極管控制,低電平就開始鳴叫。
- }
- else
- {
- ; //此處多加一個空指令,想維持跟if括號語句的數量對稱,都是兩條指令。不加也可以。
- beep_dr=1;//蜂鳴器是PNP三極管控制,高電平就停止鳴叫。
- }
- TH0=0xf8; //重裝初始值(65535-2000)=63535=0xf82f
- TL0=0x2f;
- TR0=1;//開中斷
- }
- void key_scan(void)//按鍵掃描函數 放在定時中斷里
- {
- static unsigned intuiKeyTimeCnt1=0; //按鍵去抖動延時計數器
- static unsigned char ucKeyLock1=0; //按鍵觸發(fā)后自鎖的變量標志
- static unsigned intuiKeyTimeCnt2=0; //按鍵去抖動延時計數器
- static unsigned char ucKeyLock2=0; //按鍵觸發(fā)后自鎖的變量標志
- static unsigned intuiKeyTimeCnt3=0; //按鍵去抖動延時計數器
- static unsigned char ucKeyLock3=0; //按鍵觸發(fā)后自鎖的變量標志
- static unsigned intuiKeyTimeCnt4=0; //按鍵去抖動延時計數器
- static unsigned char ucKeyLock4=0; //按鍵觸發(fā)后自鎖的變量標志
- if(key_sr1==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標志位
- {
- ucKeyLock1=0; //按鍵自鎖標志清零
- uiKeyTimeCnt1=0;//按鍵去抖動延時計數器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
- }
- else if(ucKeyLock1==0)//有按鍵按下,且是第一次被按下
- {
- uiKeyTimeCnt1++; //累加定時中斷次數
- if(uiKeyTimeCnt1>const_key_time1)
- {
- uiKeyTimeCnt1=0;
- ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)
- ucKeySec=1; //觸發(fā)1號鍵
- }
- }
- if(key_sr2==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標志位
- {
- ucKeyLock2=0; //按鍵自鎖標志清零
- uiKeyTimeCnt2=0;//按鍵去抖動延時計數器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
- }
- else if(ucKeyLock2==0)//有按鍵按下,且是第一次被按下
- {
- uiKeyTimeCnt2++; //累加定時中斷次數
- if(uiKeyTimeCnt2>const_key_time2)
- {
- uiKeyTimeCnt2=0;
- ucKeyLock2=1;//自鎖按鍵置位,避免一直觸發(fā)
- ucKeySec=2; //觸發(fā)2號鍵
- }
- }
- if(key_sr3==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標志位
- {
- ucKeyLock3=0; //按鍵自鎖標志清零
- uiKeyTimeCnt3=0;//按鍵去抖動延時計數器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
- }
- else if(ucKeyLock3==0)//有按鍵按下,且是第一次被按下
- {
- uiKeyTimeCnt3++; //累加定時中斷次數
- if(uiKeyTimeCnt3>const_key_time3)
- {
- uiKeyTimeCnt3=0;
- ucKeyLock3=1;//自鎖按鍵置位,避免一直觸發(fā)
- ucKeySec=3; //觸發(fā)3號鍵
- }
- }
- if(key_sr4==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標志位
- {
- ucKeyLock4=0; //按鍵自鎖標志清零
- uiKeyTimeCnt4=0;//按鍵去抖動延時計數器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
- }
- else if(ucKeyLock4==0)//有按鍵按下,且是第一次被按下
- {
- uiKeyTimeCnt4++; //累加定時中斷次數
- if(uiKeyTimeCnt4>const_key_time4)
- {
- uiKeyTimeCnt4=0;
- ucKeyLock4=1;//自鎖按鍵置位,避免一直觸發(fā)
- ucKeySec=4; //觸發(fā)4號鍵
- }
- }
- }
- void key_service(void) //按鍵服務的應用程序
- {
- switch(ucKeySec) //按鍵服務狀態(tài)切換
- {
- case 1:// 加按鍵 對應朱兆祺學習板的S1鍵
- switch(ucWd)//在不同的窗口下,設置不同的參數
- {
- case 1://窗口1
- switch(ucPart)//在窗口1下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài) 此處的case 0可以省略
- break;
- case 1: //設置第1行參數
- ucData_1_1++;
- if(ucData_1_1>99)
- {
- ucData_1_1=99;
- }
- ucWd1Part1Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 2: //設置第2行參數
- ucData_1_2++;
- if(ucData_1_2>99)
- {
- ucData_1_2=99;
- }
- ucWd1Part2Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 3: //設置第3行參數
- ucData_1_3++;
- if(ucData_1_3>99)
- {
- ucData_1_3=99;
- }
- ucWd1Part3Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 4: //設置第4行參數
- ucData_1_4++;
- if(ucData_1_4>99)
- {
- ucData_1_4=99;
- }
- ucWd1Part4Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- }
- break;
- case 2://窗口2
- switch(ucPart)//在窗口2下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài) 此處的case 0可以省略
- break;
- case 1: //設置第1行參數
- ucData_2_1++;
- if(ucData_2_1>99)
- {
- ucData_2_1=99;
- }
- ucWd2Part1Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 2: //設置第2行參數
- ucData_2_2++;
- if(ucData_2_2>99)
- {
- ucData_2_2=99;
- }
- ucWd2Part2Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 3: //設置第3行參數
- ucData_2_3++;
- if(ucData_2_3>99)
- {
- ucData_2_3=99;
- }
- ucWd2Part3Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 4: //設置第4行參數
- ucData_2_4++;
- if(ucData_2_4>99)
- {
- ucData_2_4=99;
- }
- ucWd2Part4Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- }
- break;
- }
- uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
- ucKeySec=0;//響應按鍵服務處理程序后,按鍵編號清零,避免一致觸發(fā)
- break;
- case 2:// 減按鍵 對應朱兆祺學習板的S5鍵
- switch(ucWd)//在不同的窗口下,設置不同的參數
- {
- case 1://窗口1
- switch(ucPart)//在窗口1下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài) 此處的case 0可以省略
- break;
- case 1: //設置第1行參數
- ucData_1_1--;
- if(ucData_1_1>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_1_1=0;
- }
- ucWd1Part1Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 2: //設置第2行參數
- ucData_1_2--;
- if(ucData_1_2>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_1_2=0;
- }
- ucWd1Part2Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 3: //設置第3行參數
- ucData_1_3--;
- if(ucData_1_3>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_1_3=0;
- }
- ucWd1Part3Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 4: //設置第4行參數
- ucData_1_4--;
- if(ucData_1_4>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_1_4=0;
- }
- ucWd1Part4Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- }
- break;
- case 2://窗口2
- switch(ucPart)//在窗口2下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài) 此處的case 0可以省略
- break;
- case 1: //設置第1行參數
- ucData_2_1--;
- if(ucData_2_1>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_2_1=0;
- }
- ucWd2Part1Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 2: //設置第2行參數
- ucData_2_2--;
- if(ucData_2_2>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_2_2=0;
- }
- ucWd2Part2Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 3: //設置第3行參數
- ucData_2_3--;
- if(ucData_2_3>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_2_3=0;
- }
- ucWd2Part3Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- case 4: //設置第4行參數
- ucData_2_4--;
- if(ucData_2_4>99) //一直減到最后,單片機C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
- {
- ucData_2_4=0;
- }
- ucWd2Part4Update=1; //1代表更新顯示,響應函數內部會清零
- break;
- }
- break;
- }
- uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
- ucKeySec=0;//響應按鍵服務處理程序后,按鍵編號清零,避免一致觸發(fā)
- break;
- case 3:// 切換"光標"移動按鍵 對應朱兆祺學習板的S9鍵
- switch(ucWd)//在不同的窗口下,設置不同的參數
- {
- case 1: //窗口1
- switch(ucPart)//在窗口1下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài) 此處的case 0可以省略
- break;
- case 1: //設置第1行參數
- ucPart=2; //光標切換到下一行
- ucWd1Part1Update=1; //更新顯示原來那一行,目的是更新反顯光標的狀態(tài)
- ucWd1Part2Update=1; //更新顯示下一行, 目的是更新反顯光標的狀態(tài)
- break;
- case 2: //設置第2行參數
- ucPart=3; //光標切換到下一行
- ucWd1Part2Update=1; //更新顯示原來那一行,目的是更新反顯光標的狀態(tài)
- ucWd1Part3Update=1; //更新顯示下一行, 目的是更新反顯光標的狀態(tài)
- break;
- case 3: //設置第3行參數
- ucPart=4; //光標切換到下一行
- ucWd1Part3Update=1; //更新顯示原來那一行,目的是更新反顯光標的狀態(tài)
- ucWd1Part4Update=1; //更新顯示下一行, 目的是更新反顯光標的狀態(tài)
- break;
- case 4: //設置第4行參數
- ucWd=2;//切換到第2個窗口
- ucPart=1; //光標返回到最上面第一行
- ucWd2Update=1; //窗口2整屏更新
- break;
- }
- break;
- case 2: //窗口2
- switch(ucPart)//在窗口2下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài) 此處的case 0可以省略
- break;
- case 1: //設置第1行參數
- ucPart=2; //光標切換到下一行
- ucWd2Part1Update=1; //更新顯示原來那一行,目的是更新反顯光標的狀態(tài)
- ucWd2Part2Update=1; //更新顯示下一行, 目的是更新反顯光標的狀態(tài)
- break;
- case 2: //設置第2行參數
- ucPart=3; //光標切換到下一行
- ucWd2Part2Update=1; //更新顯示原來那一行,目的是更新反顯光標的狀態(tài)
- ucWd2Part3Update=1; //更新顯示下一行, 目的是更新反顯光標的狀態(tài)
- break;
- case 3: //設置第3行參數
- ucPart=4; //光標切換到下一行
- ucWd2Part3Update=1; //更新顯示原來那一行,目的是更新反顯光標的狀態(tài)
- ucWd2Part4Update=1; //更新顯示下一行, 目的是更新反顯光標的狀態(tài)
- break;
- case 4: //設置第4行參數
- ucWd=1;//切換到第1個窗口
- ucPart=1; //光標返回到最上面第一行
- ucWd1Update=1; //窗口1整屏更新
- break;
- }
- break;
- }
- uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
- ucKeySec=0;//響應按鍵服務處理程序后,按鍵編號清零,避免一致觸發(fā)
- break;
- case 4: // 設置按鍵對應朱兆祺學習板的S13鍵,按一次進入設置狀態(tài),出現反顯光標。再按一次推出設置狀態(tài),消除反顯光標,并且強行切換到第1個窗口
- switch(ucWd)//在不同的窗口下,設置不同的參數
- {
- case 1://窗口1
- switch(ucPart)//在窗口1下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài)
- ucPart=1; //光標顯示第一行,進入設置模式
- ucWd1Part1Update=1; //更新顯示
- break;
- case 1: //設置第1行參數
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Part1Update=1; //更新顯示
- break;
- case 2: //設置第2行參數
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Part2Update=1; //更新顯示
- break;
- case 3: //設置第3行參數
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Part3Update=1; //更新顯示
- break;
- case 4: //設置第4行參數
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Part4Update=1; //更新顯示
- break;
- }
- break;
- case 2://窗口2
- switch(ucPart)//在窗口2下,根據不同的局部變量來設置不同的參數
- {
- case 0: //無光標顯示的狀態(tài)
- ucWd=1; //強行切換到第1個窗口
- ucPart=1; //光標顯示第一行,進入設置模式
- ucWd1Update=1; //窗口1整屏更新
- break;
- case 1: //設置第1行參數
- ucWd=1; //強行切換到第1個窗口
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Update=1; //窗口1整屏更新
- break;
- case 2: //設置第2行參數
- ucWd=1; //強行切換到第1個窗口
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Update=1; //窗口1整屏更新
- break;
- case 3: //設置第3行參數
- ucWd=1; //強行切換到第1個窗口
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Update=1; //窗口1整屏更新
- break;
- case 4: //設置第4行參數
- ucWd=1; //強行切換到第1個窗口
- ucPart=0; //無光標顯示,退出設置模式
- ucWd1Update=1; //窗口1整屏更新
- break;
- }
- break;
- }
- uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
- ucKeySec=0;//響應按鍵服務處理程序后,按鍵編號清零,避免一致觸發(fā)
- break;
- }
- }
- unsigned char *number_to_matrix(unsigned charucBitNumber)
- {
- unsigned char *p_ucAnyNumber;//此指針根據ucBitNumber數值的大小,分別調用不同的字庫。
- switch(ucBitNumber)//根據ucBitNumber數值的大小,分別調用不同的字庫。
- {
- case 0:
- p_ucAnyNumber=Zf816_0;
- break;
- case 1:
- p_ucAnyNumber=Zf816_1;
- break;
- case 2:
- p_ucAnyNumber=Zf816_2;
- break;
- case 3:
- p_ucAnyNumber=Zf816_3;
- break;
- case 4:
- p_ucAnyNumber=Zf816_4;
- break;
- case 5:
- p_ucAnyNumber=Zf816_5;
- break;
- case 6:
- p_ucAnyNumber=Zf816_6;
- break;
- case 7:
- p_ucAnyNumber=Zf816_7;
- break;
- case 8:
- p_ucAnyNumber=Zf816_8;
- break;
- case 9:
- p_ucAnyNumber=Zf816_9;
- break;
- case 10:
- p_ucAnyNumber=Zf816_nc;
- break;
- default: //如果上面的條件都不符合,那么默認指向空字模
- p_ucAnyNumber=Zf816_nc;
- break;
- }
- return p_ucAnyNumber;//返回轉換結束后的指針
- }
- void lcd_display_service(void) //應用層面的液晶屏顯示程序
- {
- switch(ucWd)//本程序的核心變量,窗口顯示變量。類似于一級菜單的變量。代表顯示不同的窗口。
- {
- case 1:
- wd1();//窗口1顯示的內容
- break;
- case 2:
- wd2();//窗口2顯示的內容
- break;
- //本程序只有2個窗口,所以只有一個case 1,如果要增加窗口,就直接增加 case 2, case 3...
- }
- }
- void wd1(void)//窗口1顯示的內容
- {
- unsigned char ucAnyNumber_1; //分解變量的個位
- unsigned char ucAnyNumber_10; //分解變量的十位
- unsigned char *p_ucAnyNumber_1; //經過數字轉換成字模后,分解變量的個位字模首地址
- unsigned char *p_ucAnyNumber_10; //經過數字轉換成字模后,分解變量的十位字模首地址
- unsigned char ucCursorFlag;//光標標志,也就是反顯的標志,它是根據局部變量ucPart來定的
- /* 注釋三:
- * 把每一個窗口的內容分為兩種類型,一種類型是那些不用經常刷新顯示的內容,只有在切換窗口的時候
- * 才需要更新,這種內容放在整屏更新顯示的括號里,比如清屏操作等內容。另外一種是那些經常需要
- * 刷新顯示的內容,這種內容放在局部更新顯示的括號里。
- */
- if(ucWd1Update==1)//窗口1整屏更新,里面只放那些不用經常刷新顯示的內容
- {
- ucWd1Update=0;//及時清零,避免一直更新
- ucWd1Part1Update=1; //激活窗口1的第1行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- ucWd1Part2Update=1; //激活窗口1的第2行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- ucWd1Part3Update=1; //激活窗口1的第3行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- ucWd1Part4Update=1; //激活窗口1的第4行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- display_clear(0x00); // 清屏操作, 全部顯示空填充0x00,全部顯示點陣用0xff。
- clear_all_canvas();//把畫布全部清零
- insert_buffer_to_canvas(0,0,Zf816_mao_hao,0,1,16);//把冒號的字模插入畫布
- display_lattice(0,0,Hz1616_yi,0,2,16,0); //一窗口一行,這些內容不用經常更新,只有在切換窗口的時候才更新顯示
- display_lattice(1,0,Hz1616_chuang,0,2,16,0);
- display_lattice(2,0,Hz1616_kou,0,2,16,0);
- display_lattice(3,0,Hz1616_yi,0,2,16,0);
- display_lattice(4,0,Hz1616_hang,0,2,16,0);
- display_lattice(0,16,Hz1616_yi,0,2,16,0); //一窗口二行
- display_lattice(1,16,Hz1616_chuang,0,2,16,0);
- display_lattice(2,16,Hz1616_kou,0,2,16,0);
- display_lattice(3,16,Hz1616_er,0,2,16,0);
- display_lattice(4,16,Hz1616_hang,0,2,16,0);
- display_lattice(8,0,Hz1616_yi,0,2,16,0); //一窗口三行
- display_lattice(9,0,Hz1616_chuang,0,2,16,0);
- display_lattice(10,0,Hz1616_kou,0,2,16,0);
- display_lattice(11,0,Hz1616_san,0,2,16,0);
- display_lattice(12,0,Hz1616_hang,0,2,16,0);
- display_lattice(8,16,Hz1616_yi,0,2,16,0); //一窗口四行
- display_lattice(9,16,Hz1616_chuang,0,2,16,0);
- display_lattice(10,16,Hz1616_kou,0,2,16,0);
- display_lattice(11,16,Hz1616_si,0,2,16,0);
- display_lattice(12,16,Hz1616_hang,0,2,16,0);
- }
- /* 注釋四:
- * 注意!我前面講數碼管顯示的時候有一句話講錯了,我那時說<局部更新應該寫在整屏更新之前>,這是不對的。
- * 按照現在的顯示程序框架<即整屏顯示更新括號里包含了所有局部變量的激活>,應該是<整屏更新應該寫在局部更新之前>
- * 這樣才對。
- */
- if(ucWd1Part1Update==1) //窗口1的第1行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd1Part1Update=0; //及時清零,避免一直更新
- if(ucPart==1) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_1_1>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_1_1/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_1_1%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(5,0,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- if(ucWd1Part2Update==1) //窗口1的第2行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd1Part2Update=0; //及時清零,避免一直更新
- if(ucPart==2) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_1_2>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_1_2/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_1_2%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(5,16,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- if(ucWd1Part3Update==1) //窗口1的第3行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd1Part3Update=0; //及時清零,避免一直更新
- if(ucPart==3) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_1_3>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_1_3/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_1_3%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(13,0,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- if(ucWd1Part4Update==1) //窗口1的第4行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd1Part4Update=0; //及時清零,避免一直更新
- if(ucPart==4) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_1_4>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_1_4/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_1_4%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(13,16,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- }
- void wd2(void)//窗口2顯示的內容
- {
- unsigned char ucAnyNumber_1; //分解變量的個位
- unsigned char ucAnyNumber_10; //分解變量的十位
- unsigned char *p_ucAnyNumber_1; //經過數字轉換成字模后,分解變量的個位字模首地址
- unsigned char *p_ucAnyNumber_10; //經過數字轉換成字模后,分解變量的十位字模首地址
- unsigned char ucCursorFlag;//光標標志,也就是反顯的標志,它是根據局部變量ucPart來定的
- if(ucWd2Update==1)//窗口2整屏更新,里面只放那些不用經常刷新顯示的內容
- {
- ucWd2Update=0;//及時清零,避免一直更新
- ucWd2Part1Update=1; //激活窗口2的第1行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- ucWd2Part2Update=1; //激活窗口2的第2行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- ucWd2Part3Update=1; //激活窗口2的第3行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- ucWd2Part4Update=1; //激活窗口2的第4行局部更新顯示變量,這里在前面數碼管顯示框架上有所改進
- display_clear(0x00); // 清屏操作, 全部顯示空填充0x00,全部顯示點陣用0xff。
- clear_all_canvas();//把畫布全部清零
- insert_buffer_to_canvas(0,0,Zf816_mao_hao,0,1,16);//把冒號的字模插入畫布
- display_lattice(0,0,Hz1616_er,0,2,16,0); //二窗口一行,這些內容不用經常更新,只有在切換窗口的時候才更新顯示
- display_lattice(1,0,Hz1616_chuang,0,2,16,0);
- display_lattice(2,0,Hz1616_kou,0,2,16,0);
- display_lattice(3,0,Hz1616_yi,0,2,16,0);
- display_lattice(4,0,Hz1616_hang,0,2,16,0);
- display_lattice(0,16,Hz1616_er,0,2,16,0); //二窗口二行
- display_lattice(1,16,Hz1616_chuang,0,2,16,0);
- display_lattice(2,16,Hz1616_kou,0,2,16,0);
- display_lattice(3,16,Hz1616_er,0,2,16,0);
- display_lattice(4,16,Hz1616_hang,0,2,16,0);
- display_lattice(8,0,Hz1616_er,0,2,16,0); //二窗口三行
- display_lattice(9,0,Hz1616_chuang,0,2,16,0);
- display_lattice(10,0,Hz1616_kou,0,2,16,0);
- display_lattice(11,0,Hz1616_san,0,2,16,0);
- display_lattice(12,0,Hz1616_hang,0,2,16,0);
- display_lattice(8,16,Hz1616_er,0,2,16,0); //二窗口四行
- display_lattice(9,16,Hz1616_chuang,0,2,16,0);
- display_lattice(10,16,Hz1616_kou,0,2,16,0);
- display_lattice(11,16,Hz1616_si,0,2,16,0);
- display_lattice(12,16,Hz1616_hang,0,2,16,0);
- }
- if(ucWd2Part1Update==1) //窗口2的第1行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd2Part1Update=0; //及時清零,避免一直更新
- if(ucPart==1) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_2_1>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_2_1/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_2_1%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(5,0,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- if(ucWd2Part2Update==1) //窗口2的第2行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd2Part2Update=0; //及時清零,避免一直更新
- if(ucPart==2) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_2_2>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_2_2/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_2_2%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(5,16,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- if(ucWd2Part3Update==1) //窗口2的第3行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd2Part3Update=0; //及時清零,避免一直更新
- if(ucPart==3) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_2_3>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_2_3/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_2_3%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(13,0,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- if(ucWd2Part4Update==1) //窗口2的第4行局部更新顯示變量,里面放一些經常需要刷新顯示的內容
- {
- ucWd2Part4Update=0; //及時清零,避免一直更新
- if(ucPart==4) //被選中
- {
- ucCursorFlag=1; //反顯 顯示
- }
- else //沒被選中
- {
- ucCursorFlag=0; //正常 顯示
- }
- if(ucData_2_4>=10) //有2位數以上
- {
- ucAnyNumber_10=ucData_2_4/10;//十位
- }
- else //否則顯示空
- {
- ucAnyNumber_10=10;//在下面的轉換函數中,代碼10表示空字模
- }
- ucAnyNumber_1=ucData_2_4%10/1;//個位
- p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數字轉換成字模首地址
- p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數字轉換成字模首地址
- insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
- insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
- display_lattice(13,16,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數0是偏移量
- }
- }
- void clear_all_canvas(void)//把畫布全部清零
- {
- unsigned int j=0;
- unsigned int i=0;
- for(j=0;j<16;j++)//這里的16表示畫布有16行
- {
- for(i=0;i<4;i++) //這里的4表示畫布每行有4個字節(jié)
- {
- ucCanvasBuffer[j*4+i]=0x00;
- }
- }
- }
- void display_clear(unsigned char ucFillDate) // 清屏全部顯示空填充0x00 全部顯示點陣用0xff
- {
- unsigned char x,y;
- WriteCommand(0x34);//關顯示緩沖指令
- WriteCommand(0x34);//關顯示緩沖指令故意寫2次,怕1次關不了 這個是因為我參考到某廠家的驅動程序也是這樣寫的
- y=0;
- while(y<32)//y軸的范圍0至31
- {
- WriteCommand(y+0x80); //垂直地址
- WriteCommand(0x80); //水平地址
- for(x=0;x<32;x++)//256個橫向點,有32個字節(jié)
- {
- LCDWriteData(ucFillDate);
- }
- y++;
- }
- WriteCommand(0x36); //開顯示緩沖指令
- }
- /* 注釋五:
- * 把字模插入畫布的函數.
- * 這是本節(jié)的核心函數,讀者尤其要搞懂x_amount和y_amount對應的顯示關系。
- * 第1,2個參數x,y是在畫布中的坐標體系。
- * x的范圍是0至3,因為畫布的橫向只要4個字節(jié)。y的范圍是0至15,因為畫布的縱向只有16行。
- * 第3個參數*ucArray是字模的數組。
- * 第4個參數ucFbFlag是反白顯示標志。0代表正常顯示,1代表反白顯示。
- * 第5,6個參數x_amount,y_amount分別代表字模數組的橫向有多少個字節(jié),縱向有幾橫。
- */
- void insert_buffer_to_canvas(unsigned int x,unsigned int y,const unsigned char*ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount)
- {
- unsigned int j=0;
- unsigned int i=0;
- unsigned char ucTemp;
- for(j=0;j
- {
- for(i=0;i
- {
- ucTemp=ucArray[j*x_amount+i];
- if(ucFbFlag==0)
- {
- ucCanvasBuffer[(y+j)*4+x+i]=ucTemp; //這里的4代表畫布每一行只有4個字節(jié)
- }
- else
- {
- ucCanvasBuffer[(y+j)*4+x+i]=~ucTemp; //這里的4代表畫布每一行只有4個字節(jié)
- }
- }
- }
- }
- /* 注釋六:
- * 顯示任意點陣函數.
- * 注意,本函數在前幾節(jié)的基礎上多增加了第7個參數uiOffSetAddr,它是偏移地址。
- * 對于這個函數,讀者尤其要搞懂x_amount和y_amount對應的顯示關系。
- * 第1,2個參數x,y是坐標體系。x的范圍是0至15,y的范圍是0至31.
- * 第3個參數*ucArray是字模的數組。
- * 第4個參數ucFbFlag是反白顯示標志。0代表正常顯示,1代表反白顯示。
- * 第5,6個參數x_amount,y_amount分別代表字模數組的橫向有多少個字節(jié),縱向有幾橫。
- * 第7個參數uiOffSetAddr是偏移地址,代表字模數組的從第幾個數據開始顯示。
- */
- void display_lattice(unsigned int x,unsigned int y,const unsigned char*ucArray,unsigned char ucFbFlag,unsigned int x_amount,unsigned int y_amount,unsigned int uiOffSetAddr)
- {
- unsigned int j=0;
- unsigned int i=0;
- unsigned char ucTemp;
- //注意,要把以下兩行指令屏蔽,否則屏幕在更新顯示時會整屏閃動
- //WriteCommand(0x34);//關顯示緩沖指令
- //WriteCommand(0x34);//關顯示緩沖指令故意寫2次,怕1次關不了 這個是因為我參考到某廠家的驅動程序也是這樣寫的
- for(j=0;j
- {
- WriteCommand(y+j+0x80); //垂直地址
- WriteCommand(x+0x80); //水平地址
- for(i=0;i
- {
- ucTemp=ucArray[j*x_amount+i+uiOffSetAddr]; //uiOffSetAddr是字模數組的偏移地址
- if(ucFbFlag==1)//反白顯示
- {
- ucTemp=~ucTemp;
- }
- LCDWriteData(ucTemp);
- // delay_short(30000);//把上一節(jié)這個延時函數去掉,加快刷屏速度
- }
- }
- WriteCommand(0x36); //開顯示緩沖指令
- }
- void SendByteToLcd(unsigned char ucData)//發(fā)送一個字節(jié)數據到液晶模塊
- {
- unsigned char i;
- for ( i = 0; i < 8; i++ )
- {
- if ( (ucData << i) & 0x80 )
- {
- LCDSID_dr = 1;
- }
- else
- {
- LCDSID_dr = 0;
- }
- LCDCLK_dr = 0;
- LCDCLK_dr = 1;
- }
- }
- void SPIWrite(unsigned char ucWData, unsigned char ucWRS) //模擬SPI發(fā)送一個字節(jié)的命令或者數據給液晶模塊的底層驅動
- {
- SendByteToLcd( 0xf8 + (ucWRS << 1) );
- SendByteToLcd( ucWData & 0xf0 );
- SendByteToLcd( (ucWData << 4) & 0xf0);
- }
- void WriteCommand(unsigned char ucCommand) //發(fā)送一個字節(jié)的命令給液晶模塊
- {
- LCDCS_dr = 0;
- LCDCS_dr = 1;
- SPIWrite(ucCommand, 0);
- delay_short(90);
- }
- void LCDWriteData(unsigned char ucData)//發(fā)送一個字節(jié)的數據給液晶模塊
- {
- LCDCS_dr = 0;
- LCDCS_dr = 1;
- SPIWrite(ucData, 1);
- }
- void LCDInit(void) //初始化函數內部包括液晶模塊的復位
- {
- LCDRST_dr = 1;//復位
- LCDRST_dr = 0;
- LCDRST_dr = 1;
- }
- void delay_short(unsigned int uiDelayShort) //延時函數
- {
- unsigned int i;
- for(i=0;i
- {
- ;
- }
- }
- void delay_long(unsigned int uiDelayLong)
- {
- unsigned int i;
- unsigned int j;
- for(i=0;i
- {
- for(j=0;j<500;j++)//內嵌循環(huán)的空指令數量
- {
- ; //一個分號相當于執(zhí)行一條空語句
- }
- }
- }
總結陳詞:
這一節(jié)講了在多個窗口里設置不同的參數。還有一種常見的項目,要求把第1窗口是用來作為主菜單,主菜單里面有3個子菜單,可以通過移動光標進入不同的子菜單窗口進行參數設置,這類項目該如何編程?欲知詳情,請聽下回分解-----通過主菜單移動光標來進入子菜單窗口的液晶屏程序。
評論