<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > 第77節(jié):窗口里通過移動光標(biāo)設(shè)置參數(shù)的液晶屏菜單程序

          第77節(jié):窗口里通過移動光標(biāo)設(shè)置參數(shù)的液晶屏菜單程序

          作者: 時間:2016-11-22 來源:網(wǎng)絡(luò) 收藏
          開場白:
          這一節(jié)要教會大家兩個知識點:
          第一個知識點:我在前面講數(shù)碼管顯示的時候就提出了一個 “一二級菜單顯示理論”:凡是人機(jī)界面顯示,不管是數(shù)碼管還是液晶屏,都可以把顯示的內(nèi)容分成不同的窗口來顯示,每個顯示的窗口中又可以分成不同的局部顯示。其中窗口就是一級菜單,用ucWd變量表示。局部就是二級菜單,用ucPart來表示。不同的窗口,會有不同的更新顯示變量ucWdXUpdate來對應(yīng),表示整屏全部更新顯示。不同的局部,也會有不同的更新顯示變量ucWdXPartYUpdate來對應(yīng),表示局部更新顯示。把每一個窗口的內(nèi)容分為兩種類型,一種類型是那些不用經(jīng)常刷新顯示的內(nèi)容,只有在切換窗口的時候才需要更新的,這種內(nèi)容放在整屏更新顯示的括號里,比如清屏操作等內(nèi)容。另外一種是那些經(jīng)常需要刷新顯示的內(nèi)容,這種內(nèi)容放在局部更新顯示的括號里。
          第二個知識點:按鍵如何跟液晶屏顯示有機(jī)的結(jié)合起來?只要遵循鴻哥總結(jié)出來的一個規(guī)律“在不同的窗口下,根據(jù)不同的局部變量來操作不同的參數(shù)”,這樣再復(fù)雜的人機(jī)交互程序都會顯得很簡單清晰。

          具體內(nèi)容,請看源代碼講解。

          (1)硬件平臺:基于朱兆祺51單片機(jī)學(xué)習(xí)板。加按鍵對應(yīng)S1鍵,減按鍵對應(yīng)S5鍵,切換“光標(biāo)”移動按鍵對應(yīng)S9鍵,設(shè)置參數(shù)按鍵對應(yīng)S13鍵。

          (2)實現(xiàn)功能:
          通過按鍵設(shè)置4個不同的參數(shù)。
          有1個窗口。每個窗口顯示4個參數(shù)。每個參數(shù)的范圍是從0到99。
          有4個按鍵:
          (a) 一個是設(shè)置參數(shù)S13按鍵,按下此按鍵,液晶屏的第一行會出現(xiàn)反顯的光標(biāo),表示進(jìn)入設(shè)置參數(shù)模式,再次按下此按鍵,反顯光標(biāo)會消失,表示退出設(shè)置參數(shù)模式。
          (b) 一個是移動光標(biāo)S9按鍵,在進(jìn)入設(shè)置參數(shù)的模式下,依次按下此按鍵,液晶屏上的光標(biāo)會從上往下移動,表示選中不同的參數(shù)。
          (c) 一個是減數(shù)S5按鍵,在設(shè)置參數(shù)模式下,依次按下此按鍵,被選中的參數(shù)會逐漸減小。
          (d) 一個是加數(shù)S1按鍵,在設(shè)置參數(shù)模式下,依次按下此按鍵,被選中的參數(shù)會逐漸加大。

          (3)源代碼講解如下:
          1. #include "REG52.H"
          2. #define const_voice_short40 //蜂鳴器短叫的持續(xù)時間
          3. #define const_key_time120 //按鍵去抖動延時的時間
          4. #define const_key_time220 //按鍵去抖動延時的時間
          5. #define const_key_time320 //按鍵去抖動延時的時間
          6. #define const_key_time420 //按鍵去抖動延時的時間
          7. sbit key_sr1=P0^0; //對應(yīng)朱兆祺學(xué)習(xí)板的S1鍵
          8. sbit key_sr2=P0^1; //對應(yīng)朱兆祺學(xué)習(xí)板的S5鍵
          9. sbit key_sr3=P0^2; //對應(yīng)朱兆祺學(xué)習(xí)板的S9鍵
          10. sbit key_sr4=P0^3; //對應(yīng)朱兆祺學(xué)習(xí)板的S13鍵
          11. sbit key_gnd_dr=P0^4; //模擬獨立按鍵的地GND,因此必須一直輸出低電平
          12. sbit beep_dr=P2^7; //蜂鳴器的驅(qū)動IO口
          13. sbitLCDCS_dr= P1^6;//片選線
          14. sbitLCDSID_dr = P1^7;//串行數(shù)據(jù)線
          15. sbitLCDCLK_dr = P3^2;//串行時鐘線
          16. sbitLCDRST_dr = P3^4;//復(fù)位線
          17. void SendByteToLcd(unsigned char ucData);//發(fā)送一個字節(jié)數(shù)據(jù)到液晶模塊
          18. void SPIWrite(unsigned char ucWData, unsigned char ucWRS); //模擬SPI發(fā)送一個字節(jié)的命令或者數(shù)據(jù)給液晶模塊的底層驅(qū)動
          19. void WriteCommand(unsigned char ucCommand); //發(fā)送一個字節(jié)的命令給液晶模塊
          20. void LCDWriteData(unsigned char ucData); //發(fā)送一個字節(jié)的數(shù)據(jù)給液晶模塊
          21. void LCDInit(void);//初始化函數(shù)內(nèi)部包括液晶模塊的復(fù)位
          22. void display_clear(unsigned char ucFillDate); // 清屏 全部顯示空填充0x00 全部顯示點陣用0xff
          23. 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);//把字模插入畫布.
          24. 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); //顯示任意點陣函數(shù)
          25. unsigned char *number_to_matrix(unsigned charucBitNumber); //把一位數(shù)字轉(zhuǎn)換成字模首地址的函數(shù)
          26. void delay_short(unsigned int uiDelayshort); //延時
          27. void delay_long(unsigned int uiDelayLong);
          28. void T0_time(); //定時中斷函數(shù)
          29. void key_service(void); //按鍵服務(wù)的應(yīng)用程序
          30. void key_scan(void);//按鍵掃描函數(shù) 放在定時中斷里
          31. void initial_myself();
          32. void initial_peripheral();
          33. void lcd_display_service(void); //應(yīng)用層面的液晶屏顯示程序
          34. void clear_all_canvas(void);//把畫布全部清零
          35. code unsigned char Zf816_0[]=
          36. {
          37. /*--文字:0--*/
          38. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          39. 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
          40. };
          41. code unsigned char Zf816_1[]=
          42. {
          43. /*--文字:1--*/
          44. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          45. 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,
          46. };
          47. code unsigned char Zf816_2[]=
          48. {
          49. /*--文字:2--*/
          50. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          51. 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,
          52. };
          53. code unsigned char Zf816_3[]=
          54. {
          55. /*--文字:3--*/
          56. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          57. 0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
          58. };
          59. code unsigned char Zf816_4[]=
          60. {
          61. /*--文字:4--*/
          62. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          63. 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,
          64. };
          65. code unsigned char Zf816_5[]=
          66. {
          67. /*--文字:5--*/
          68. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          69. 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
          70. };
          71. code unsigned char Zf816_6[]=
          72. {
          73. /*--文字:6--*/
          74. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          75. 0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
          76. };
          77. code unsigned char Zf816_7[]=
          78. {
          79. /*--文字:7--*/
          80. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          81. 0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
          82. };
          83. code unsigned char Zf816_8[]=
          84. {
          85. /*--文字:8--*/
          86. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          87. 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,
          88. };
          89. code unsigned char Zf816_9[]=
          90. {
          91. /*--文字:9--*/
          92. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          93. 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,
          94. };
          95. code unsigned char Zf816_nc[]=//空字模
          96. {
          97. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
          98. };
          99. code unsigned char Zf816_mao_hao[]=//冒號
          100. {
          101. /*--文字::--*/
          102. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=8x16 --*/
          103. 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,
          104. };
          105. code unsigned char Hz1616_yi[]=
          106. {
          107. /*--文字:一--*/
          108. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=16x16 --*/
          109. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0xFE,
          110. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
          111. };
          112. code unsigned char Hz1616_er[]=
          113. {
          114. /*--文字:二--*/
          115. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=16x16 --*/
          116. 0x00,0x00,0x00,0x10,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
          117. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
          118. };
          119. code unsigned char Hz1616_san[]=
          120. {
          121. /*--文字:三--*/
          122. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=16x16 --*/
          123. 0x00,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,
          124. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,
          125. };
          126. code unsigned char Hz1616_si[]=
          127. {
          128. /*--文字:四--*/
          129. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=16x16 --*/
          130. 0x00,0x00,0x7F,0xFC,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,
          131. 0x48,0x84,0x48,0x7C,0x50,0x04,0x60,0x04,0x40,0x04,0x7F,0xFC,0x40,0x04,0x00,0x00,
          132. };
          133. code unsigned char Hz1616_chuang[]=
          134. {
          135. /*--文字:窗--*/
          136. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=16x16 --*/
          137. 0x01,0x00,0x00,0x80,0x7F,0xFE,0x40,0x22,0x09,0x18,0x12,0x06,0x7F,0xF8,0x11,0x08,
          138. 0x13,0xE8,0x14,0x48,0x1A,0x88,0x11,0x08,0x12,0x88,0x14,0x08,0x1F,0xF8,0x10,0x08,
          139. };
          140. code unsigned char Hz1616_kou[]=
          141. {
          142. /*--文字:口--*/
          143. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=16x16 --*/
          144. 0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,
          145. 0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x20,0x08,0x20,0x08,0x00,0x00,0x00,0x00,
          146. };
          147. code unsigned char Hz1616_hang[]=
          148. {
          149. /*--文字:行--*/
          150. /*--宋體12;此字體下對應(yīng)的點陣為:寬x高=16x16 --*/
          151. 0x08,0x00,0x1C,0x00,0x31,0xFC,0x40,0x00,0x88,0x00,0x0C,0x00,0x1B,0xFE,0x30,0x20,
          152. 0x50,0x20,0x90,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0xA0,0x10,0x40,
          153. };
          154. unsigned char ucCanvasBuffer[]= //畫布顯示數(shù)組。注意,這里沒有code關(guān)鍵字,是全局變量。初始化全部填充0x00
          155. {
          156. 0x00,0x00,0x00,0x00,//上半屏
          157. 0x00,0x00,0x00,0x00,
          158. 0x00,0x00,0x00,0x00,
          159. 0x00,0x00,0x00,0x00,
          160. 0x00,0x00,0x00,0x00,
          161. 0x00,0x00,0x00,0x00,
          162. 0x00,0x00,0x00,0x00,
          163. 0x00,0x00,0x00,0x00,
          164. //------------上半屏和下半屏的分割線-----------
          165. 0x00,0x00,0x00,0x00,//下半屏
          166. 0x00,0x00,0x00,0x00,
          167. 0x00,0x00,0x00,0x00,
          168. 0x00,0x00,0x00,0x00,
          169. 0x00,0x00,0x00,0x00,
          170. 0x00,0x00,0x00,0x00,
          171. 0x00,0x00,0x00,0x00,
          172. 0x00,0x00,0x00,0x00,
          173. };
          174. unsigned char ucKeySec=0; //被觸發(fā)的按鍵編號
          175. unsigned intuiVoiceCnt=0;//蜂鳴器鳴叫的持續(xù)時間計數(shù)器
          176. unsigned char ucWd=1; //窗口變量
          177. unsigned char ucPart=0; //局部變量 0代表沒有選中任何一行,其它數(shù)值1到4代表選中某一行
          178. unsigned char ucWd1Update=1; //窗口1的整屏更新顯示變量 1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          179. unsigned char ucWd1Part1Update=0; //窗口1的第1行局部更新顯示變量1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          180. unsigned char ucWd1Part2Update=0; //窗口1的第2行局部更新顯示變量1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          181. unsigned char ucWd1Part3Update=0; //窗口1的第3行局部更新顯示變量1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          182. unsigned char ucWd1Part4Update=0; //窗口1的第4行局部更新顯示變量1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          183. unsigned char ucData_1_1=8;//第1個窗口第1行的被設(shè)置數(shù)據(jù)
          184. unsigned char ucData_1_2=9;//第1個窗口第2行的被設(shè)置數(shù)據(jù)
          185. unsigned char ucData_1_3=10;//第1個窗口第3行的被設(shè)置數(shù)據(jù)
          186. unsigned char ucData_1_4=11;//第1個窗口第4行的被設(shè)置數(shù)據(jù)
          187. void main()
          188. {
          189. initial_myself(); //第一區(qū),上電后馬上初始化
          190. delay_long(100); //一線,延時線。延時一段時間
          191. initial_peripheral();//第二區(qū),上電后延時一段時間再初始化
          192. while(1) //第三區(qū)
          193. {
          194. key_service(); //按鍵服務(wù)的應(yīng)用程序
          195. lcd_display_service(); //應(yīng)用層面的液晶屏顯示程序
          196. }
          197. }
          198. void initial_myself()//第一區(qū) 上電后馬上初始化
          199. {
          200. /* 注釋一:
          201. * 矩陣鍵盤也可以做獨立按鍵,前提是把某一根公共輸出線輸出低電平,
          202. * 模擬獨立按鍵的觸發(fā)地,本程序中,把key_gnd_dr輸出低電平。
          203. * 朱兆祺51學(xué)習(xí)板的S1和S5兩個按鍵就是本程序中用到的兩個獨立按鍵。
          204. */
          205. key_gnd_dr=0; //模擬獨立按鍵的地GND,因此必須一直輸出低電平
          206. beep_dr=1; //用PNP三極管控制蜂鳴器,輸出高電平時不叫。
          207. TMOD=0x01;//設(shè)置定時器0為工作方式1
          208. TH0=0xf8; //重裝初始值(65535-2000)=63535=0xf82f
          209. TL0=0x2f;
          210. }
          211. void initial_peripheral() //第二區(qū) 上電后延時一段時間再初始化
          212. {
          213. LCDInit(); //初始化12864 內(nèi)部包含液晶模塊的復(fù)位
          214. EA=1; //開總中斷
          215. ET0=1; //允許定時中斷
          216. TR0=1; //啟動定時中斷
          217. }
          218. void T0_time() interrupt 1
          219. {
          220. TF0=0;//清除中斷標(biāo)志
          221. TR0=0; //關(guān)中斷
          222. key_scan(); //按鍵掃描函數(shù)
          223. if(uiVoiceCnt!=0)
          224. {
          225. uiVoiceCnt--; //每次進(jìn)入定時中斷都自減1,直到等于零為止。才停止鳴叫
          226. beep_dr=0;//蜂鳴器是PNP三極管控制,低電平就開始鳴叫。
          227. }
          228. else
          229. {
          230. ; //此處多加一個空指令,想維持跟if括號語句的數(shù)量對稱,都是兩條指令。不加也可以。
          231. beep_dr=1;//蜂鳴器是PNP三極管控制,高電平就停止鳴叫。
          232. }
          233. TH0=0xf8; //重裝初始值(65535-2000)=63535=0xf82f
          234. TL0=0x2f;
          235. TR0=1;//開中斷
          236. }
          237. void key_scan(void)//按鍵掃描函數(shù) 放在定時中斷里
          238. {
          239. static unsigned intuiKeyTimeCnt1=0; //按鍵去抖動延時計數(shù)器
          240. static unsigned char ucKeyLock1=0; //按鍵觸發(fā)后自鎖的變量標(biāo)志
          241. static unsigned intuiKeyTimeCnt2=0; //按鍵去抖動延時計數(shù)器
          242. static unsigned char ucKeyLock2=0; //按鍵觸發(fā)后自鎖的變量標(biāo)志
          243. static unsigned intuiKeyTimeCnt3=0; //按鍵去抖動延時計數(shù)器
          244. static unsigned char ucKeyLock3=0; //按鍵觸發(fā)后自鎖的變量標(biāo)志
          245. static unsigned intuiKeyTimeCnt4=0; //按鍵去抖動延時計數(shù)器
          246. static unsigned char ucKeyLock4=0; //按鍵觸發(fā)后自鎖的變量標(biāo)志
          247. if(key_sr1==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標(biāo)志位
          248. {
          249. ucKeyLock1=0; //按鍵自鎖標(biāo)志清零
          250. uiKeyTimeCnt1=0;//按鍵去抖動延時計數(shù)器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
          251. }
          252. else if(ucKeyLock1==0)//有按鍵按下,且是第一次被按下
          253. {
          254. uiKeyTimeCnt1++; //累加定時中斷次數(shù)
          255. if(uiKeyTimeCnt1>const_key_time1)
          256. {
          257. uiKeyTimeCnt1=0;
          258. ucKeyLock1=1;//自鎖按鍵置位,避免一直觸發(fā)
          259. ucKeySec=1; //觸發(fā)1號鍵
          260. }
          261. }
          262. if(key_sr2==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標(biāo)志位
          263. {
          264. ucKeyLock2=0; //按鍵自鎖標(biāo)志清零
          265. uiKeyTimeCnt2=0;//按鍵去抖動延時計數(shù)器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
          266. }
          267. else if(ucKeyLock2==0)//有按鍵按下,且是第一次被按下
          268. {
          269. uiKeyTimeCnt2++; //累加定時中斷次數(shù)
          270. if(uiKeyTimeCnt2>const_key_time2)
          271. {
          272. uiKeyTimeCnt2=0;
          273. ucKeyLock2=1;//自鎖按鍵置位,避免一直觸發(fā)
          274. ucKeySec=2; //觸發(fā)2號鍵
          275. }
          276. }
          277. if(key_sr3==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標(biāo)志位
          278. {
          279. ucKeyLock3=0; //按鍵自鎖標(biāo)志清零
          280. uiKeyTimeCnt3=0;//按鍵去抖動延時計數(shù)器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
          281. }
          282. else if(ucKeyLock3==0)//有按鍵按下,且是第一次被按下
          283. {
          284. uiKeyTimeCnt3++; //累加定時中斷次數(shù)
          285. if(uiKeyTimeCnt3>const_key_time3)
          286. {
          287. uiKeyTimeCnt3=0;
          288. ucKeyLock3=1;//自鎖按鍵置位,避免一直觸發(fā)
          289. ucKeySec=3; //觸發(fā)3號鍵
          290. }
          291. }
          292. if(key_sr4==1)//IO是高電平,說明按鍵沒有被按下,這時要及時清零一些標(biāo)志位
          293. {
          294. ucKeyLock4=0; //按鍵自鎖標(biāo)志清零
          295. uiKeyTimeCnt4=0;//按鍵去抖動延時計數(shù)器清零,此行非常巧妙,是我實戰(zhàn)中摸索出來的。
          296. }
          297. else if(ucKeyLock4==0)//有按鍵按下,且是第一次被按下
          298. {
          299. uiKeyTimeCnt4++; //累加定時中斷次數(shù)
          300. if(uiKeyTimeCnt4>const_key_time4)
          301. {
          302. uiKeyTimeCnt4=0;
          303. ucKeyLock4=1;//自鎖按鍵置位,避免一直觸發(fā)
          304. ucKeySec=4; //觸發(fā)4號鍵
          305. }
          306. }
          307. }
          308. void key_service(void) //按鍵服務(wù)的應(yīng)用程序
          309. {
          310. switch(ucKeySec) //按鍵服務(wù)狀態(tài)切換
          311. {
          312. case 1:// 加按鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S1鍵
          313. switch(ucWd)//在不同的窗口下,設(shè)置不同的參數(shù)
          314. {
          315. case 1:
          316. switch(ucPart)//在窗口1下,根據(jù)不同的局部變量來設(shè)置不同的參數(shù)
          317. {
          318. case 0: //無光標(biāo)顯示的狀態(tài) 此處的case 0可以省略
          319. break;
          320. case 1: //設(shè)置第1行參數(shù)
          321. ucData_1_1++;
          322. if(ucData_1_1>99)
          323. {
          324. ucData_1_1=99;
          325. }
          326. ucWd1Part1Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          327. break;
          328. case 2: //設(shè)置第2行參數(shù)
          329. ucData_1_2++;
          330. if(ucData_1_2>99)
          331. {
          332. ucData_1_2=99;
          333. }
          334. ucWd1Part2Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          335. break;
          336. case 3: //設(shè)置第3行參數(shù)
          337. ucData_1_3++;
          338. if(ucData_1_3>99)
          339. {
          340. ucData_1_3=99;
          341. }
          342. ucWd1Part3Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          343. break;
          344. case 4: //設(shè)置第4行參數(shù)
          345. ucData_1_4++;
          346. if(ucData_1_4>99)
          347. {
          348. ucData_1_4=99;
          349. }
          350. ucWd1Part4Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          351. break;
          352. }
          353. break;
          354. }
          355. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          356. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          357. break;
          358. case 2:// 減按鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S5鍵
          359. switch(ucWd)//在不同的窗口下,設(shè)置不同的參數(shù)
          360. {
          361. case 1:
          362. switch(ucPart)//在窗口1下,根據(jù)不同的局部變量來設(shè)置不同的參數(shù)
          363. {
          364. case 0: //無光標(biāo)顯示的狀態(tài) 此處的case 0可以省略
          365. break;
          366. case 1: //設(shè)置第1行參數(shù)
          367. ucData_1_1--;
          368. if(ucData_1_1>99) //一直減到最后,單片機(jī)C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
          369. {
          370. ucData_1_1=0;
          371. }
          372. ucWd1Part1Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          373. break;
          374. case 2: //設(shè)置第2行參數(shù)
          375. ucData_1_2--;
          376. if(ucData_1_2>99) //一直減到最后,單片機(jī)C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
          377. {
          378. ucData_1_2=0;
          379. }
          380. ucWd1Part2Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          381. break;
          382. case 3: //設(shè)置第3行參數(shù)
          383. ucData_1_3--;
          384. if(ucData_1_3>99) //一直減到最后,單片機(jī)C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
          385. {
          386. ucData_1_3=0;
          387. }
          388. ucWd1Part3Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          389. break;
          390. case 4: //設(shè)置第4行參數(shù)
          391. ucData_1_4--;
          392. if(ucData_1_4>99) //一直減到最后,單片機(jī)C語言編譯器有一個特征,0減去1會溢出變成255(0xff)
          393. {
          394. ucData_1_4=0;
          395. }
          396. ucWd1Part4Update=1; //1代表更新顯示,響應(yīng)函數(shù)內(nèi)部會清零
          397. break;
          398. }
          399. break;
          400. }
          401. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          402. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          403. break;
          404. case 3:// 切換"光標(biāo)"移動按鍵 對應(yīng)朱兆祺學(xué)習(xí)板的S9鍵
          405. switch(ucWd)//在不同的窗口下,設(shè)置不同的參數(shù)
          406. {
          407. case 1:
          408. switch(ucPart)//在窗口1下,根據(jù)不同的局部變量來設(shè)置不同的參數(shù)
          409. {
          410. case 0: //無光標(biāo)顯示的狀態(tài) 此處的case 0可以省略
          411. break;
          412. case 1: //設(shè)置第1行參數(shù)
          413. ucPart=2; //光標(biāo)切換到下一行
          414. ucWd1Part1Update=1; //更新顯示原來那一行,目的是更新反顯光標(biāo)的狀態(tài)
          415. ucWd1Part2Update=1; //更新顯示下一行, 目的是更新反顯光標(biāo)的狀態(tài)
          416. break;
          417. case 2: //設(shè)置第2行參數(shù)
          418. ucPart=3; //光標(biāo)切換到下一行
          419. ucWd1Part2Update=1; //更新顯示原來那一行,目的是更新反顯光標(biāo)的狀態(tài)
          420. ucWd1Part3Update=1; //更新顯示下一行, 目的是更新反顯光標(biāo)的狀態(tài)
          421. break;
          422. case 3: //設(shè)置第3行參數(shù)
          423. ucPart=4; //光標(biāo)切換到下一行
          424. ucWd1Part3Update=1; //更新顯示原來那一行,目的是更新反顯光標(biāo)的狀態(tài)
          425. ucWd1Part4Update=1; //更新顯示下一行, 目的是更新反顯光標(biāo)的狀態(tài)
          426. break;
          427. case 4: //設(shè)置第4行參數(shù)
          428. ucPart=1; //光標(biāo)返回到最上面第一行
          429. ucWd1Part4Update=1; //更新顯示原來那一行,目的是更新反顯光標(biāo)的狀態(tài)
          430. ucWd1Part1Update=1; //更新顯示最上面第一行, 目的是更新反顯光標(biāo)的狀態(tài)
          431. break;
          432. }
          433. break;
          434. }
          435. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          436. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          437. break;
          438. case 4: // 設(shè)置按鍵對應(yīng)朱兆祺學(xué)習(xí)板的S13鍵,按一次進(jìn)入設(shè)置狀態(tài),出現(xiàn)反顯光標(biāo)。再按一次推出設(shè)置狀態(tài),消除反顯光標(biāo)
          439. switch(ucWd)//在不同的窗口下,設(shè)置不同的參數(shù)
          440. {
          441. case 1:
          442. switch(ucPart)//在窗口1下,根據(jù)不同的局部變量來設(shè)置不同的參數(shù)
          443. {
          444. case 0: //無光標(biāo)顯示的狀態(tài)
          445. ucPart=1; //光標(biāo)顯示第一行,進(jìn)入設(shè)置模式
          446. ucWd1Part1Update=1; //更新顯示
          447. break;
          448. case 1: //設(shè)置第1行參數(shù)
          449. ucPart=0; //無光標(biāo)顯示,退出設(shè)置模式
          450. ucWd1Part1Update=1; //更新顯示
          451. break;
          452. case 2: //設(shè)置第2行參數(shù)
          453. ucPart=0; //無光標(biāo)顯示,退出設(shè)置模式
          454. ucWd1Part2Update=1; //更新顯示
          455. break;
          456. case 3: //設(shè)置第3行參數(shù)
          457. ucPart=0; //無光標(biāo)顯示,退出設(shè)置模式
          458. ucWd1Part3Update=1; //更新顯示
          459. break;
          460. case 4: //設(shè)置第4行參數(shù)
          461. ucPart=0; //無光標(biāo)顯示,退出設(shè)置模式
          462. ucWd1Part4Update=1; //更新顯示
          463. break;
          464. }
          465. break;
          466. }
          467. uiVoiceCnt=const_voice_short; //按鍵聲音觸發(fā),滴一聲就停。
          468. ucKeySec=0;//響應(yīng)按鍵服務(wù)處理程序后,按鍵編號清零,避免一致觸發(fā)
          469. break;
          470. }
          471. }
          472. unsigned char *number_to_matrix(unsigned charucBitNumber)
          473. {
          474. unsigned char *p_ucAnyNumber;//此指針根據(jù)ucBitNumber數(shù)值的大小,分別調(diào)用不同的字庫。
          475. switch(ucBitNumber)//根據(jù)ucBitNumber數(shù)值的大小,分別調(diào)用不同的字庫。
          476. {
          477. case 0:
          478. p_ucAnyNumber=Zf816_0;
          479. break;
          480. case 1:
          481. p_ucAnyNumber=Zf816_1;
          482. break;
          483. case 2:
          484. p_ucAnyNumber=Zf816_2;
          485. break;
          486. case 3:
          487. p_ucAnyNumber=Zf816_3;
          488. break;
          489. case 4:
          490. p_ucAnyNumber=Zf816_4;
          491. break;
          492. case 5:
          493. p_ucAnyNumber=Zf816_5;
          494. break;
          495. case 6:
          496. p_ucAnyNumber=Zf816_6;
          497. break;
          498. case 7:
          499. p_ucAnyNumber=Zf816_7;
          500. break;
          501. case 8:
          502. p_ucAnyNumber=Zf816_8;
          503. break;
          504. case 9:
          505. p_ucAnyNumber=Zf816_9;
          506. break;
          507. case 10:
          508. p_ucAnyNumber=Zf816_nc;
          509. break;
          510. default: //如果上面的條件都不符合,那么默認(rèn)指向空字模
          511. p_ucAnyNumber=Zf816_nc;
          512. break;
          513. }
          514. return p_ucAnyNumber;//返回轉(zhuǎn)換結(jié)束后的指針
          515. }
          516. void lcd_display_service(void) //應(yīng)用層面的液晶屏顯示程序
          517. {
          518. unsigned char ucAnyNumber_1; //分解變量的個位
          519. unsigned char ucAnyNumber_10; //分解變量的十位
          520. unsigned char *p_ucAnyNumber_1; //經(jīng)過數(shù)字轉(zhuǎn)換成字模后,分解變量的個位字模首地址
          521. unsigned char *p_ucAnyNumber_10; //經(jīng)過數(shù)字轉(zhuǎn)換成字模后,分解變量的十位字模首地址
          522. unsigned char ucCursorFlag;//光標(biāo)標(biāo)志,也就是反顯的標(biāo)志,它是根據(jù)局部變量ucPart來定的
          523. switch(ucWd)//本程序的核心變量,窗口顯示變量。類似于一級菜單的變量。代表顯示不同的窗口。
          524. {
          525. case 1: //顯示窗口1的數(shù)據(jù)
          526. /* 注釋二:
          527. * 把每一個窗口的內(nèi)容分為兩種類型,一種類型是那些不用經(jīng)常刷新顯示的內(nèi)容,只有在切換窗口的時候
          528. * 才需要更新,這種內(nèi)容放在整屏更新顯示的括號里,比如清屏操作等內(nèi)容。另外一種是那些經(jīng)常需要
          529. * 刷新顯示的內(nèi)容,這種內(nèi)容放在局部更新顯示的括號里。
          530. */
          531. if(ucWd1Update==1)//窗口1整屏更新,里面只放那些不用經(jīng)常刷新顯示的內(nèi)容
          532. {
          533. ucWd1Update=0;//及時清零,避免一直更新
          534. ucWd1Part1Update=1; //激活窗口1的第1行局部更新顯示變量,這里在前面數(shù)碼管顯示框架上有所改進(jìn)
          535. ucWd1Part2Update=1; //激活窗口1的第2行局部更新顯示變量,這里在前面數(shù)碼管顯示框架上有所改進(jìn)
          536. ucWd1Part3Update=1; //激活窗口1的第3行局部更新顯示變量,這里在前面數(shù)碼管顯示框架上有所改進(jìn)
          537. ucWd1Part4Update=1; //激活窗口1的第4行局部更新顯示變量,這里在前面數(shù)碼管顯示框架上有所改進(jìn)
          538. display_clear(0x00); // 清屏操作, 全部顯示空填充0x00,全部顯示點陣用0xff。
          539. clear_all_canvas();//把畫布全部清零
          540. insert_buffer_to_canvas(0,0,Zf816_mao_hao,0,1,16);//把冒號的字模插入畫布
          541. display_lattice(0,0,Hz1616_yi,0,2,16,0); //一窗口一行,這些內(nèi)容不用經(jīng)常更新,只有在切換窗口的時候才更新顯示
          542. display_lattice(1,0,Hz1616_chuang,0,2,16,0);
          543. display_lattice(2,0,Hz1616_kou,0,2,16,0);
          544. display_lattice(3,0,Hz1616_yi,0,2,16,0);
          545. display_lattice(4,0,Hz1616_hang,0,2,16,0);
          546. display_lattice(0,16,Hz1616_yi,0,2,16,0); //一窗口二行
          547. display_lattice(1,16,Hz1616_chuang,0,2,16,0);
          548. display_lattice(2,16,Hz1616_kou,0,2,16,0);
          549. display_lattice(3,16,Hz1616_er,0,2,16,0);
          550. display_lattice(4,16,Hz1616_hang,0,2,16,0);
          551. display_lattice(8,0,Hz1616_yi,0,2,16,0); //一窗口三行
          552. display_lattice(9,0,Hz1616_chuang,0,2,16,0);
          553. display_lattice(10,0,Hz1616_kou,0,2,16,0);
          554. display_lattice(11,0,Hz1616_san,0,2,16,0);
          555. display_lattice(12,0,Hz1616_hang,0,2,16,0);
          556. display_lattice(8,16,Hz1616_yi,0,2,16,0); //一窗口四行
          557. display_lattice(9,16,Hz1616_chuang,0,2,16,0);
          558. display_lattice(10,16,Hz1616_kou,0,2,16,0);
          559. display_lattice(11,16,Hz1616_si,0,2,16,0);
          560. display_lattice(12,16,Hz1616_hang,0,2,16,0);
          561. }
          562. /* 注釋三:
          563. * 注意!我前面講數(shù)碼管顯示的時候有一句話講錯了,我那時說<局部更新應(yīng)該寫在整屏更新之前>,這是不對的。
          564. * 按照現(xiàn)在的顯示程序框架<即整屏顯示更新括號里包含了所有局部變量的激活>,應(yīng)該是<整屏更新應(yīng)該寫在局部更新之前>
          565. * 這樣才對。
          566. */
          567. if(ucWd1Part1Update==1) //窗口1的第1行局部更新顯示變量,里面放一些經(jīng)常需要刷新顯示的內(nèi)容
          568. {
          569. ucWd1Part1Update=0; //及時清零,避免一直更新
          570. if(ucPart==1) //被選中
          571. {
          572. ucCursorFlag=1; //反顯 顯示
          573. }
          574. else //沒被選中
          575. {
          576. ucCursorFlag=0; //正常 顯示
          577. }
          578. if(ucData_1_1>=10) //有2位數(shù)以上
          579. {
          580. ucAnyNumber_10=ucData_1_1/10;//十位
          581. }
          582. else //否則顯示空
          583. {
          584. ucAnyNumber_10=10;//在下面的轉(zhuǎn)換函數(shù)中,代碼10表示空字模
          585. }
          586. ucAnyNumber_1=ucData_1_1%10/1;//個位
          587. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數(shù)字轉(zhuǎn)換成字模首地址
          588. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數(shù)字轉(zhuǎn)換成字模首地址
          589. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
          590. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
          591. display_lattice(5,0,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數(shù)0是偏移量
          592. }
          593. if(ucWd1Part2Update==1) //窗口1的第2行局部更新顯示變量,里面放一些經(jīng)常需要刷新顯示的內(nèi)容
          594. {
          595. ucWd1Part2Update=0; //及時清零,避免一直更新
          596. if(ucPart==2) //被選中
          597. {
          598. ucCursorFlag=1; //反顯 顯示
          599. }
          600. else //沒被選中
          601. {
          602. ucCursorFlag=0; //正常 顯示
          603. }
          604. if(ucData_1_2>=10) //有2位數(shù)以上
          605. {
          606. ucAnyNumber_10=ucData_1_2/10;//十位
          607. }
          608. else //否則顯示空
          609. {
          610. ucAnyNumber_10=10;//在下面的轉(zhuǎn)換函數(shù)中,代碼10表示空字模
          611. }
          612. ucAnyNumber_1=ucData_1_2%10/1;//個位
          613. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數(shù)字轉(zhuǎn)換成字模首地址
          614. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數(shù)字轉(zhuǎn)換成字模首地址
          615. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
          616. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
          617. display_lattice(5,16,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數(shù)0是偏移量
          618. }
          619. if(ucWd1Part3Update==1) //窗口1的第3行局部更新顯示變量,里面放一些經(jīng)常需要刷新顯示的內(nèi)容
          620. {
          621. ucWd1Part3Update=0; //及時清零,避免一直更新
          622. if(ucPart==3) //被選中
          623. {
          624. ucCursorFlag=1; //反顯 顯示
          625. }
          626. else //沒被選中
          627. {
          628. ucCursorFlag=0; //正常 顯示
          629. }
          630. if(ucData_1_3>=10) //有2位數(shù)以上
          631. {
          632. ucAnyNumber_10=ucData_1_3/10;//十位
          633. }
          634. else //否則顯示空
          635. {
          636. ucAnyNumber_10=10;//在下面的轉(zhuǎn)換函數(shù)中,代碼10表示空字模
          637. }
          638. ucAnyNumber_1=ucData_1_3%10/1;//個位
          639. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數(shù)字轉(zhuǎn)換成字模首地址
          640. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數(shù)字轉(zhuǎn)換成字模首地址
          641. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
          642. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
          643. display_lattice(13,0,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數(shù)0是偏移量
          644. }
          645. if(ucWd1Part4Update==1) //窗口1的第4行局部更新顯示變量,里面放一些經(jīng)常需要刷新顯示的內(nèi)容
          646. {
          647. ucWd1Part4Update=0; //及時清零,避免一直更新
          648. if(ucPart==4) //被選中
          649. {
          650. ucCursorFlag=1; //反顯 顯示
          651. }
          652. else //沒被選中
          653. {
          654. ucCursorFlag=0; //正常 顯示
          655. }
          656. if(ucData_1_4>=10) //有2位數(shù)以上
          657. {
          658. ucAnyNumber_10=ucData_1_4/10;//十位
          659. }
          660. else //否則顯示空
          661. {
          662. ucAnyNumber_10=10;//在下面的轉(zhuǎn)換函數(shù)中,代碼10表示空字模
          663. }
          664. ucAnyNumber_1=ucData_1_4%10/1;//個位
          665. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把數(shù)字轉(zhuǎn)換成字模首地址
          666. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把數(shù)字轉(zhuǎn)換成字模首地址
          667. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模插入畫布
          668. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把個的字模插入畫布
          669. display_lattice(13,16,ucCanvasBuffer,0,4,16,0); //顯示整屏的畫布,最后的參數(shù)0是偏移量
          670. }
          671. break;
          672. //本程序只有1個窗口,所以只有一個case 1,如果要增加窗口,就直接增加 case 2, case 3...
          673. }
          674. }
          675. void clear_all_canvas(void)//把畫布全部清零
          676. {
          677. unsigned int j=0;
          678. unsigned int i=0;
          679. for(j=0;j<16;j++)//這里的16表示畫布有16行
          680. {
          681. for(i=0;i<4;i++) //這里的4表示畫布每行有4個字節(jié)
          682. {
          683. ucCanvasBuffer[j*4+i]=0x00;
          684. }
          685. }
          686. }
          687. void display_clear(unsigned char ucFillDate) // 清屏全部顯示空填充0x00 全部顯示點陣用0xff
          688. {
          689. unsigned char x,y;
          690. WriteCommand(0x34);//關(guān)顯示緩沖指令
          691. WriteCommand(0x34);//關(guān)顯示緩沖指令故意寫2次,怕1次關(guān)不了 這個是因為我參考到某廠家的驅(qū)動程序也是這樣寫的
          692. y=0;
          693. while(y<32)//y軸的范圍0至31
          694. {
          695. WriteCommand(y+0x80); //垂直地址
          696. WriteCommand(0x80); //水平地址
          697. for(x=0;x<32;x++)//256個橫向點,有32個字節(jié)
          698. {
          699. LCDWriteData(ucFillDate);
          700. }
          701. y++;
          702. }
          703. WriteCommand(0x36); //開顯示緩沖指令
          704. }
          705. /* 注釋四:
          706. * 把字模插入畫布的函數(shù).
          707. * 這是本節(jié)的核心函數(shù),讀者尤其要搞懂x_amount和y_amount對應(yīng)的顯示關(guān)系。
          708. * 第1,2個參數(shù)x,y是在畫布中的坐標(biāo)體系。
          709. * x的范圍是0至3,因為畫布的橫向只要4個字節(jié)。y的范圍是0至15,因為畫布的縱向只有16行。
          710. * 第3個參數(shù)*ucArray是字模的數(shù)組。
          711. * 第4個參數(shù)ucFbFlag是反白顯示標(biāo)志。0代表正常顯示,1代表反白顯示。
          712. * 第5,6個參數(shù)x_amount,y_amount分別代表字模數(shù)組的橫向有多少個字節(jié),縱向有幾橫。
          713. */
          714. 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)
          715. {
          716. unsigned int j=0;
          717. unsigned int i=0;
          718. unsigned char ucTemp;
          719. for(j=0;j
          720. {
          721. for(i=0;i
          722. {
          723. ucTemp=ucArray[j*x_amount+i];
          724. if(ucFbFlag==0)
          725. {
          726. ucCanvasBuffer[(y+j)*4+x+i]=ucTemp; //這里的4代表畫布每一行只有4個字節(jié)
          727. }
          728. else
          729. {
          730. ucCanvasBuffer[(y+j)*4+x+i]=~ucTemp; //這里的4代表畫布每一行只有4個字節(jié)
          731. }
          732. }
          733. }
          734. }
          735. /* 注釋五:
          736. * 顯示任意點陣函數(shù).
          737. * 注意,本函數(shù)在前幾節(jié)的基礎(chǔ)上多增加了第7個參數(shù)uiOffSetAddr,它是偏移地址。
          738. * 對于這個函數(shù),讀者尤其要搞懂x_amount和y_amount對應(yīng)的顯示關(guān)系。
          739. * 第1,2個參數(shù)x,y是坐標(biāo)體系。x的范圍是0至15,y的范圍是0至31.
          740. * 第3個參數(shù)*ucArray是字模的數(shù)組。
          741. * 第4個參數(shù)ucFbFlag是反白顯示標(biāo)志。0代表正常顯示,1代表反白顯示。
          742. * 第5,6個參數(shù)x_amount,y_amount分別代表字模數(shù)組的橫向有多少個字節(jié),縱向有幾橫。
          743. * 第7個參數(shù)uiOffSetAddr是偏移地址,代表字模數(shù)組的從第幾個數(shù)據(jù)開始顯示。
          744. */
          745. 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)
          746. {
          747. unsigned int j=0;
          748. unsigned int i=0;
          749. unsigned char ucTemp;
          750. //注意,要把以下兩行指令屏蔽,否則屏幕在更新顯示時會整屏閃動
          751. //WriteCommand(0x34);//關(guān)顯示緩沖指令
          752. //WriteCommand(0x34);//關(guān)顯示緩沖指令故意寫2次,怕1次關(guān)不了 這個是因為我參考到某廠家的驅(qū)動程序也是這樣寫的
          753. for(j=0;j
          754. {
          755. WriteCommand(y+j+0x80); //垂直地址
          756. WriteCommand(x+0x80); //水平地址
          757. for(i=0;i
          758. {
          759. ucTemp=ucArray[j*x_amount+i+uiOffSetAddr]; //uiOffSetAddr是字模數(shù)組的偏移地址
          760. if(ucFbFlag==1)//反白顯示
          761. {
          762. ucTemp=~ucTemp;
          763. }
          764. LCDWriteData(ucTemp);
          765. // delay_short(30000);//把上一節(jié)這個延時函數(shù)去掉,加快刷屏速度
          766. }
          767. }
          768. WriteCommand(0x36); //開顯示緩沖指令
          769. }
          770. void SendByteToLcd(unsigned char ucData)//發(fā)送一個字節(jié)數(shù)據(jù)到液晶模塊
          771. {
          772. unsigned char i;
          773. for ( i = 0; i < 8; i++ )
          774. {
          775. if ( (ucData << i) & 0x80 )
          776. {
          777. LCDSID_dr = 1;
          778. }
          779. else
          780. {
          781. LCDSID_dr = 0;
          782. }
          783. LCDCLK_dr = 0;
          784. LCDCLK_dr = 1;
          785. }
          786. }
          787. void SPIWrite(unsigned char ucWData, unsigned char ucWRS) //模擬SPI發(fā)送一個字節(jié)的命令或者數(shù)據(jù)給液晶模塊的底層驅(qū)動
          788. {
          789. SendByteToLcd( 0xf8 + (ucWRS << 1) );
          790. SendByteToLcd( ucWData & 0xf0 );
          791. SendByteToLcd( (ucWData << 4) & 0xf0);
          792. }
          793. void WriteCommand(unsigned char ucCommand) //發(fā)送一個字節(jié)的命令給液晶模塊
          794. {
          795. LCDCS_dr = 0;
          796. LCDCS_dr = 1;
          797. SPIWrite(ucCommand, 0);
          798. delay_short(90);
          799. }
          800. void LCDWriteData(unsigned char ucData)//發(fā)送一個字節(jié)的數(shù)據(jù)給液晶模塊
          801. {
          802. LCDCS_dr = 0;
          803. LCDCS_dr = 1;
          804. SPIWrite(ucData, 1);
          805. }
          806. void LCDInit(void) //初始化函數(shù)內(nèi)部包括液晶模塊的復(fù)位
          807. {
          808. LCDRST_dr = 1;//復(fù)位
          809. LCDRST_dr = 0;
          810. LCDRST_dr = 1;
          811. }
          812. void delay_short(unsigned int uiDelayShort) //延時函數(shù)
          813. {
          814. unsigned int i;
          815. for(i=0;i
          816. {
          817. ;
          818. }
          819. }
          820. void delay_long(unsigned int uiDelayLong)
          821. {
          822. unsigned int i;
          823. unsigned int j;
          824. for(i=0;i
          825. {
          826. for(j=0;j<500;j++)//內(nèi)嵌循環(huán)的空指令數(shù)量
          827. {
          828. ; //一個分號相當(dāng)于執(zhí)行一條空語句
          829. }
          830. }
          831. }

          總結(jié)陳詞:
          這一節(jié)講了在一個窗口里設(shè)置不同的參數(shù),如果有幾個窗口的情況下,該如何編程?欲知詳情,請聽下回分解-----在多個窗口里通過移動光標(biāo)來設(shè)置不同參數(shù)的液晶屏菜單程序。


          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();