您的位置 首页 硬件

第78节:多个窗口里移动光标设置参数的液晶屏菜单程序

开场白:上一节讲了1个窗口下如何设置参数的菜单程序,这一节多增加1个窗口变成2个窗口,看看它们两个窗口之间是如何通过按键程序进行切换

开场白:
上一节讲了1个窗口下怎么设置参数的菜单程序,这一节多添加1个窗口变成2个窗口,看看它们两个窗口之间是怎么经过按键程序进行切换的。持续稳固上一节教给我们的两个知识点:
榜首个知识点:我在前面讲数码管显现的时分就提出了一个 “一二级菜单显现理论”:但凡人机界面显现,不管是数码管仍是液晶屏,都能够把显现的内容分红不同的窗口来显现,每个显现的窗口中又能够分红不同的部分显现。其间窗口便是一级菜单,用ucWd变量表明。部分便是二级菜单,用ucPart来表明。不同的窗口,会有不同的更新显现变量ucWdXUpdate来对应,表明整屏悉数更新显现。不同的部分,也会有不同的更新显现变量ucWdXPartYUpdate来对应,表明部分更新显现。把每一个窗口的内容分为两种类型,一种类型是那些不必常常改写显现的内容,只需在切换窗口的时分才需求更新的,这种内容放在整屏更新显现的括号里,比方清屏操作等内容。别的一种是那些常常需求改写显现的内容,这种内容放在部分更新显现的括号里。
第二个知识点:按键怎么跟液晶屏显现有机的结合起来?只需遵从鸿哥总结出来的一个规则“在不同的窗口下,依据不同的部分变量来操作不同的参数”,这样再杂乱的人机交互程序都会显得很简单明晰。

具体内容,请看源代码解说。

(1)硬件渠道:依据朱兆祺51单片机学习板。加按键对应S1键,减按键对应S5键,切换“光标”移动按键对应S9键,设置参数按键对应S13键。

(2)完成功用:
经过按键设置8个不同的参数。
有2个窗口。每个窗口显现4个参数。每个参数的规模是从0到99。
有4个按键:
(a) 一个是设置参数S13按键,按下此按键,液晶屏的第1个窗口榜首行会呈现反显的光标,表明进入设置参数模式,再次按下此按键,反显光标会消失,而且强行切换到第1个窗口,表明退出设置参数形式。
(b) 一个是移动光标S9按键,在进入设置参数的形式下,顺次按下此按键,液晶屏上的光标会从上往下移动,表明选中不同的参数。当移动到每个窗口最下边那一行时,再按下此按键会进行切换窗口的操作。
(c) 一个是减数S5按键,在设置参数形式下,顺次按下此按键,被选中的参数会逐步减小。
(d) 一个是加数S1按键,在设置参数形式下,顺次按下此按键,被选中的参数会逐步加大。
(3)源代码解说如下:

  1. #include “REG52.H”
  2. /* 注释一:
  3. * 本程序用到的变量比较多,所以在keil编译形式里要设置一下编译形式memory model,
  4. * 不然编译会犯错.右键单击Target挑选“Options for TargetTarget1”就会出来一个框
  5. * 在memory model中挑选compact:variables in pdata 就能够了。
  6. */
  7. #define const_voice_short40 //蜂鸣器短叫的持续时刻
  8. #define const_key_time120 //按键去颤动延时的时刻
  9. #define const_key_time220 //按键去颤动延时的时刻
  10. #define const_key_time320 //按键去颤动延时的时刻
  11. #define const_key_time420 //按键去颤动延时的时刻
  12. sbit key_sr1=P0^0; //对应朱兆祺学习板的S1键
  13. sbit key_sr2=P0^1; //对应朱兆祺学习板的S5键
  14. sbit key_sr3=P0^2; //对应朱兆祺学习板的S9键
  15. sbit key_sr4=P0^3; //对应朱兆祺学习板的S13键
  16. sbit key_gnd_dr=P0^4; //模仿独立按键的地GND,因而有必要一向输出低电平
  17. sbit beep_dr=P2^7; //蜂鸣器的驱动IO口
  18. sbitLCDCS_dr= P1^6;//片选线
  19. sbitLCDSID_dr = P1^7;//串行数据线
  20. sbitLCDCLK_dr = P3^2;//串行时钟线
  21. sbitLCDRST_dr = P3^4;//复位线
  22. void SendByteToLcd(unsigned char ucData);//发送一个字节数据到液晶模块
  23. void SPIWrite(unsigned char ucWData, unsigned char ucWRS); //模仿SPI发送一个字节的指令或许数据给液晶模块的底层驱动
  24. void WriteCommand(unsigned char ucCommand); //发送一个字节的指令给液晶模块
  25. void LCDWriteData(unsigned char ucData); //发送一个字节的数据给液晶模块
  26. void LCDInit(void);//初始化函数内部包含液晶模块的复位
  27. void display_clear(unsigned char ucFillDate); // 清屏 悉数显现空填充0x00 悉数显现点阵用0xff
  28. 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);//把字模刺进画布.
  29. 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); //显现恣意点阵函数
  30. unsigned char *number_to_matrix(unsigned charucBitNumber); //把一位数字转化成字模首地址的函数
  31. void delay_short(unsigned int uiDelayshort); //延时
  32. void delay_long(unsigned int uiDelayLong);
  33. void T0_time(); //守时中止函数
  34. void key_service(void); //按键服务的应用程序
  35. void key_scan(void);//按键扫描函数 放在守时中止里
  36. void initial_myself();
  37. void initial_peripheral();
  38. void lcd_display_service(void); //应用层面的液晶屏显现程序
  39. void clear_all_canvas(void);//把画布悉数清零
  40. void wd1(void);//窗口1显现的内容
  41. void wd2(void);//窗口2显现的内容
  42. code unsigned char Zf816_0[]=
  43. {
  44. /*–文字:0–*/
  45. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  46. 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
  47. };
  48. code unsigned char Zf816_1[]=
  49. {
  50. /*–文字:1–*/
  51. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  52. 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00,
  53. };
  54. code unsigned char Zf816_2[]=
  55. {
  56. /*–文字:2–*/
  57. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  58. 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x04,0x04,0x08,0x10,0x20,0x42,0x7E,0x00,0x00,
  59. };
  60. code unsigned char Zf816_3[]=
  61. {
  62. /*–文字:3–*/
  63. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  64. 0x00,0x00,0x00,0x3C,0x42,0x42,0x04,0x18,0x04,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
  65. };
  66. code unsigned char Zf816_4[]=
  67. {
  68. /*–文字:4–*/
  69. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  70. 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x24,0x44,0x44,0x7E,0x04,0x04,0x1E,0x00,0x00,
  71. };
  72. code unsigned char Zf816_5[]=
  73. {
  74. /*–文字:5–*/
  75. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  76. 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x58,0x64,0x02,0x02,0x42,0x44,0x38,0x00,0x00,
  77. };
  78. code unsigned char Zf816_6[]=
  79. {
  80. /*–文字:6–*/
  81. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  82. 0x00,0x00,0x00,0x1C,0x24,0x40,0x40,0x58,0x64,0x42,0x42,0x42,0x24,0x18,0x00,0x00,
  83. };
  84. code unsigned char Zf816_7[]=
  85. {
  86. /*–文字:7–*/
  87. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  88. 0x00,0x00,0x00,0x7E,0x44,0x44,0x08,0x08,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,
  89. };
  90. code unsigned char Zf816_8[]=
  91. {
  92. /*–文字:8–*/
  93. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  94. 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x42,0x3C,0x00,0x00,
  95. };
  96. code unsigned char Zf816_9[]=
  97. {
  98. /*–文字:9–*/
  99. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  100. 0x00,0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x26,0x1A,0x02,0x02,0x24,0x38,0x00,0x00,
  101. };
  102. code unsigned char Zf816_nc[]=//空字模
  103. {
  104. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  105. };
  106. code unsigned char Zf816_mao_hao[]=//冒号
  107. {
  108. /*–文字::–*/
  109. /*–宋体12;此字体下对应的点阵为:宽x高=8×16 –*/
  110. 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,
  111. };
  112. code unsigned char Hz1616_yi[]=
  113. {
  114. /*–文字:一–*/
  115. /*–宋体12;此字体下对应的点阵为:宽x高=16×16 –*/
  116. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0xFE,
  117. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  118. };
  119. code unsigned char Hz1616_er[]=
  120. {
  121. /*–文字:二–*/
  122. /*–宋体12;此字体下对应的点阵为:宽x高=16×16 –*/
  123. 0x00,0x00,0x00,0x10,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  124. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x7F,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
  125. };
  126. code unsigned char Hz1616_san[]=
  127. {
  128. /*–文字:三–*/
  129. /*–宋体12;此字体下对应的点阵为:宽x高=16×16 –*/
  130. 0x00,0x00,0x00,0x00,0x7F,0xFC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,
  131. 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xFE,0x00,0x00,0x00,0x00,
  132. };
  133. code unsigned char Hz1616_si[]=
  134. {
  135. /*–文字:四–*/
  136. /*–宋体12;此字体下对应的点阵为:宽x高=16×16 –*/
  137. 0x00,0x00,0x7F,0xFC,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,0x44,0x84,
  138. 0x48,0x84,0x48,0x7C,0x50,0x04,0x60,0x04,0x40,0x04,0x7F,0xFC,0x40,0x04,0x00,0x00,
  139. };
  140. code unsigned char Hz1616_chuang[]=
  141. {
  142. /*–文字:窗–*/
  143. /*–宋体12;此字体下对应的点阵为:宽x高=16×16 –*/
  144. 0x01,0x00,0x00,0x80,0x7F,0xFE,0x40,0x22,0x09,0x18,0x12,0x06,0x7F,0xF8,0x11,0x08,
  145. 0x13,0xE8,0x14,0x48,0x1A,0x88,0x11,0x08,0x12,0x88,0x14,0x08,0x1F,0xF8,0x10,0x08,
  146. };
  147. code unsigned char Hz1616_kou[]=
  148. {
  149. /*–文字:口–*/
  150. /*–宋体12;此字体下对应的点阵为:宽x高=16×16 –*/
  151. 0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,
  152. 0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x20,0x08,0x20,0x08,0x00,0x00,0x00,0x00,
  153. };
  154. code unsigned char Hz1616_hang[]=
  155. {
  156. /*–文字:行–*/
  157. /*–宋体12;此字体下对应的点阵为:宽x高=16×16 –*/
  158. 0x08,0x00,0x1C,0x00,0x31,0xFC,0x40,0x00,0x88,0x00,0x0C,0x00,0x1B,0xFE,0x30,0x20,
  159. 0x50,0x20,0x90,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0xA0,0x10,0x40,
  160. };
  161. unsigned char ucCanvasBuffer[]= //画布显现数组。留意,这儿没有code关键字,是全局变量。初始化悉数填充0x00
  162. {
  163. 0x00,0x00,0x00,0x00,//上半屏
  164. 0x00,0x00,0x00,0x00,
  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. //————上半屏和下半屏的分割线———–
  172. 0x00,0x00,0x00,0x00,//下半屏
  173. 0x00,0x00,0x00,0x00,
  174. 0x00,0x00,0x00,0x00,
  175. 0x00,0x00,0x00,0x00,
  176. 0x00,0x00,0x00,0x00,
  177. 0x00,0x00,0x00,0x00,
  178. 0x00,0x00,0x00,0x00,
  179. 0x00,0x00,0x00,0x00,
  180. };
  181. unsigned char ucKeySec=0; //被触发的按键编号
  182. unsigned intuiVoiceCnt=0;//蜂鸣器鸣叫的持续时刻计数器
  183. unsigned char ucWd=1; //窗口变量
  184. unsigned char ucPart=0; //部分变量 0代表没有选中任何一行,其它数值1到4代表选中某一行
  185. unsigned char ucWd1Update=1; //窗口1的整屏更新显现变量 1代表更新显现,呼应函数内部会清零
  186. unsigned char ucWd1Part1Update=0; //窗口1的第1行部分更新显现变量1代表更新显现,呼应函数内部会清零
  187. unsigned char ucWd1Part2Update=0; //窗口1的第2行部分更新显现变量1代表更新显现,呼应函数内部会清零
  188. unsigned char ucWd1Part3Update=0; //窗口1的第3行部分更新显现变量1代表更新显现,呼应函数内部会清零
  189. unsigned char ucWd1Part4Update=0; //窗口1的第4行部分更新显现变量1代表更新显现,呼应函数内部会清零
  190. unsigned char ucWd2Update=0; //窗口2的整屏更新显现变量 1代表更新显现,呼应函数内部会清零
  191. unsigned char ucWd2Part1Update=0; //窗口2的第1行部分更新显现变量1代表更新显现,呼应函数内部会清零
  192. unsigned char ucWd2Part2Update=0; //窗口2的第2行部分更新显现变量1代表更新显现,呼应函数内部会清零
  193. unsigned char ucWd2Part3Update=0; //窗口2的第3行部分更新显现变量1代表更新显现,呼应函数内部会清零
  194. unsigned char ucWd2Part4Update=0; //窗口2的第4行部分更新显现变量1代表更新显现,呼应函数内部会清零
  195. unsigned char ucData_1_1=8;//第1个窗口第1行的被设置数据
  196. unsigned char ucData_1_2=9;//第1个窗口第2行的被设置数据
  197. unsigned char ucData_1_3=10;//第1个窗口第3行的被设置数据
  198. unsigned char ucData_1_4=11;//第1个窗口第4行的被设置数据
  199. unsigned char ucData_2_1=12;//第2个窗口第1行的被设置数据
  200. unsigned char ucData_2_2=13;//第2个窗口第2行的被设置数据
  201. unsigned char ucData_2_3=14;//第2个窗口第3行的被设置数据
  202. unsigned char ucData_2_4=15;//第2个窗口第4行的被设置数据
  203. void main()
  204. {
  205. initial_myself(); //榜首区,上电后立刻初始化
  206. delay_long(100); //一线,延时线。延时一段时刻
  207. initial_peripheral();//第二区,上电后延时一段时刻再初始化
  208. while(1) //第三区
  209. {
  210. key_service(); //按键服务的应用程序
  211. lcd_display_service(); //应用层面的液晶屏显现程序
  212. }
  213. }
  214. void initial_myself()//榜首区 上电后立刻初始化
  215. {
  216. /* 注释二:
  217. * 矩阵键盘也能够做独立按键,条件是把某一根公共输出线输出低电平,
  218. * 模仿独立按键的触发地,本程序中,把key_gnd_dr输出低电平。
  219. * 朱兆祺51学习板的S1和S5两个按键便是本程序中用到的两个独立按键。
  220. */
  221. key_gnd_dr=0; //模仿独立按键的地GND,因而有必要一向输出低电平
  222. beep_dr=1; //用PNP三极管操控蜂鸣器,输出高电平时不叫。
  223. TMOD=0x01;//设置守时器0为工作方式1
  224. TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
  225. TL0=0x2f;
  226. }
  227. void initial_peripheral() //第二区 上电后延时一段时刻再初始化
  228. {
  229. LCDInit(); //初始化12864 内部包含液晶模块的复位
  230. EA=1; //开总中止
  231. ET0=1; //答应守时中止
  232. TR0=1; //发动守时中止
  233. }
  234. void T0_time() interrupt 1
  235. {
  236. TF0=0;//铲除中止标志
  237. TR0=0; //关中止
  238. key_scan(); //按键扫描函数
  239. if(uiVoiceCnt!=0)
  240. {
  241. uiVoiceCnt–; //每次进入守时中止都自减1,直到等于零中止。才中止鸣叫
  242. beep_dr=0;//蜂鸣器是PNP三极管操控,低电平就开端鸣叫。
  243. }
  244. else
  245. {
  246. ; //此处多加一个空指令,想保持跟if括号句子的数量对称,都是两条指令。不加也能够。
  247. beep_dr=1;//蜂鸣器是PNP三极管操控,高电平就中止鸣叫。
  248. }
  249. TH0=0xf8; //重装初始值(65535-2000)=63535=0xf82f
  250. TL0=0x2f;
  251. TR0=1;//开中止
  252. }
  253. void key_scan(void)//按键扫描函数 放在守时中止里
  254. {
  255. static unsigned intuiKeyTimeCnt1=0; //按键去颤动延时计数器
  256. static unsigned char ucKeyLock1=0; //按键触发后自锁的变量标志
  257. static unsigned intuiKeyTimeCnt2=0; //按键去颤动延时计数器
  258. static unsigned char ucKeyLock2=0; //按键触发后自锁的变量标志
  259. static unsigned intuiKeyTimeCnt3=0; //按键去颤动延时计数器
  260. static unsigned char ucKeyLock3=0; //按键触发后自锁的变量标志
  261. static unsigned intuiKeyTimeCnt4=0; //按键去颤动延时计数器
  262. static unsigned char ucKeyLock4=0; //按键触发后自锁的变量标志
  263. if(key_sr1==1)//IO是高电平,阐明按键没有被按下,这时要及时清零一些标志位
  264. {
  265. ucKeyLock1=0; //按键自锁标志清零
  266. uiKeyTimeCnt1=0;//按键去颤动延时计数器清零,此行十分奇妙,是我实战中探索出来的。
  267. }
  268. else if(ucKeyLock1==0)//有按键按下,且是榜首次被按下
  269. {
  270. uiKeyTimeCnt1++; //累加守时中止次数
  271. if(uiKeyTimeCnt1>const_key_time1)
  272. {
  273. uiKeyTimeCnt1=0;
  274. ucKeyLock1=1;//自锁按键置位,防止一向触发
  275. ucKeySec=1; //触发1号键
  276. }
  277. }
  278. if(key_sr2==1)//IO是高电平,阐明按键没有被按下,这时要及时清零一些标志位
  279. {
  280. ucKeyLock2=0; //按键自锁标志清零
  281. uiKeyTimeCnt2=0;//按键去颤动延时计数器清零,此行十分奇妙,是我实战中探索出来的。
  282. }
  283. else if(ucKeyLock2==0)//有按键按下,且是榜首次被按下
  284. {
  285. uiKeyTimeCnt2++; //累加守时中止次数
  286. if(uiKeyTimeCnt2>const_key_time2)
  287. {
  288. uiKeyTimeCnt2=0;
  289. ucKeyLock2=1;//自锁按键置位,防止一向触发
  290. ucKeySec=2; //触发2号键
  291. }
  292. }
  293. if(key_sr3==1)//IO是高电平,阐明按键没有被按下,这时要及时清零一些标志位
  294. {
  295. ucKeyLock3=0; //按键自锁标志清零
  296. uiKeyTimeCnt3=0;//按键去颤动延时计数器清零,此行十分奇妙,是我实战中探索出来的。
  297. }
  298. else if(ucKeyLock3==0)//有按键按下,且是榜首次被按下
  299. {
  300. uiKeyTimeCnt3++; //累加守时中止次数
  301. if(uiKeyTimeCnt3>const_key_time3)
  302. {
  303. uiKeyTimeCnt3=0;
  304. ucKeyLock3=1;//自锁按键置位,防止一向触发
  305. ucKeySec=3; //触发3号键
  306. }
  307. }
  308. if(key_sr4==1)//IO是高电平,阐明按键没有被按下,这时要及时清零一些标志位
  309. {
  310. ucKeyLock4=0; //按键自锁标志清零
  311. uiKeyTimeCnt4=0;//按键去颤动延时计数器清零,此行十分奇妙,是我实战中探索出来的。
  312. }
  313. else if(ucKeyLock4==0)//有按键按下,且是榜首次被按下
  314. {
  315. uiKeyTimeCnt4++; //累加守时中止次数
  316. if(uiKeyTimeCnt4>const_key_time4)
  317. {
  318. uiKeyTimeCnt4=0;
  319. ucKeyLock4=1;//自锁按键置位,防止一向触发
  320. ucKeySec=4; //触发4号键
  321. }
  322. }
  323. }
  324. void key_service(void) //按键服务的应用程序
  325. {
  326. switch(ucKeySec) //按键服务状况切换
  327. {
  328. case 1:// 加按键 对应朱兆祺学习板的S1键
  329. switch(ucWd)//在不同的窗口下,设置不同的参数
  330. {
  331. case 1://窗口1
  332. switch(ucPart)//在窗口1下,依据不同的部分变量来设置不同的参数
  333. {
  334. case 0: //无光标显现的状况 此处的case 0能够省掉
  335. break;
  336. case 1: //设置第1行参数
  337. ucData_1_1++;
  338. if(ucData_1_1>99)
  339. {
  340. ucData_1_1=99;
  341. }
  342. ucWd1Part1Update=1; //1代表更新显现,呼应函数内部会清零
  343. break;
  344. case 2: //设置第2行参数
  345. ucData_1_2++;
  346. if(ucData_1_2>99)
  347. {
  348. ucData_1_2=99;
  349. }
  350. ucWd1Part2Update=1; //1代表更新显现,呼应函数内部会清零
  351. break;
  352. case 3: //设置第3行参数
  353. ucData_1_3++;
  354. if(ucData_1_3>99)
  355. {
  356. ucData_1_3=99;
  357. }
  358. ucWd1Part3Update=1; //1代表更新显现,呼应函数内部会清零
  359. break;
  360. case 4: //设置第4行参数
  361. ucData_1_4++;
  362. if(ucData_1_4>99)
  363. {
  364. ucData_1_4=99;
  365. }
  366. ucWd1Part4Update=1; //1代表更新显现,呼应函数内部会清零
  367. break;
  368. }
  369. break;
  370. case 2://窗口2
  371. switch(ucPart)//在窗口2下,依据不同的部分变量来设置不同的参数
  372. {
  373. case 0: //无光标显现的状况 此处的case 0能够省掉
  374. break;
  375. case 1: //设置第1行参数
  376. ucData_2_1++;
  377. if(ucData_2_1>99)
  378. {
  379. ucData_2_1=99;
  380. }
  381. ucWd2Part1Update=1; //1代表更新显现,呼应函数内部会清零
  382. break;
  383. case 2: //设置第2行参数
  384. ucData_2_2++;
  385. if(ucData_2_2>99)
  386. {
  387. ucData_2_2=99;
  388. }
  389. ucWd2Part2Update=1; //1代表更新显现,呼应函数内部会清零
  390. break;
  391. case 3: //设置第3行参数
  392. ucData_2_3++;
  393. if(ucData_2_3>99)
  394. {
  395. ucData_2_3=99;
  396. }
  397. ucWd2Part3Update=1; //1代表更新显现,呼应函数内部会清零
  398. break;
  399. case 4: //设置第4行参数
  400. ucData_2_4++;
  401. if(ucData_2_4>99)
  402. {
  403. ucData_2_4=99;
  404. }
  405. ucWd2Part4Update=1; //1代表更新显现,呼应函数内部会清零
  406. break;
  407. }
  408. break;
  409. }
  410. uiVoiceCnt=const_voice_short; //按键声响触发,滴一声就停。
  411. ucKeySec=0;//呼应按键服务处理程序后,按键编号清零,防止共同触发
  412. break;
  413. case 2:// 减按键 对应朱兆祺学习板的S5键
  414. switch(ucWd)//在不同的窗口下,设置不同的参数
  415. {
  416. case 1://窗口1
  417. switch(ucPart)//在窗口1下,依据不同的部分变量来设置不同的参数
  418. {
  419. case 0: //无光标显现的状况 此处的case 0能够省掉
  420. break;
  421. case 1: //设置第1行参数
  422. ucData_1_1–;
  423. if(ucData_1_1>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  424. {
  425. ucData_1_1=0;
  426. }
  427. ucWd1Part1Update=1; //1代表更新显现,呼应函数内部会清零
  428. break;
  429. case 2: //设置第2行参数
  430. ucData_1_2–;
  431. if(ucData_1_2>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  432. {
  433. ucData_1_2=0;
  434. }
  435. ucWd1Part2Update=1; //1代表更新显现,呼应函数内部会清零
  436. break;
  437. case 3: //设置第3行参数
  438. ucData_1_3–;
  439. if(ucData_1_3>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  440. {
  441. ucData_1_3=0;
  442. }
  443. ucWd1Part3Update=1; //1代表更新显现,呼应函数内部会清零
  444. break;
  445. case 4: //设置第4行参数
  446. ucData_1_4–;
  447. if(ucData_1_4>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  448. {
  449. ucData_1_4=0;
  450. }
  451. ucWd1Part4Update=1; //1代表更新显现,呼应函数内部会清零
  452. break;
  453. }
  454. break;
  455. case 2://窗口2
  456. switch(ucPart)//在窗口2下,依据不同的部分变量来设置不同的参数
  457. {
  458. case 0: //无光标显现的状况 此处的case 0能够省掉
  459. break;
  460. case 1: //设置第1行参数
  461. ucData_2_1–;
  462. if(ucData_2_1>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  463. {
  464. ucData_2_1=0;
  465. }
  466. ucWd2Part1Update=1; //1代表更新显现,呼应函数内部会清零
  467. break;
  468. case 2: //设置第2行参数
  469. ucData_2_2–;
  470. if(ucData_2_2>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  471. {
  472. ucData_2_2=0;
  473. }
  474. ucWd2Part2Update=1; //1代表更新显现,呼应函数内部会清零
  475. break;
  476. case 3: //设置第3行参数
  477. ucData_2_3–;
  478. if(ucData_2_3>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  479. {
  480. ucData_2_3=0;
  481. }
  482. ucWd2Part3Update=1; //1代表更新显现,呼应函数内部会清零
  483. break;
  484. case 4: //设置第4行参数
  485. ucData_2_4–;
  486. if(ucData_2_4>99) //一向减到最终,单片机C言语编译器有一个特征,0减去1会溢出变成255(0xff)
  487. {
  488. ucData_2_4=0;
  489. }
  490. ucWd2Part4Update=1; //1代表更新显现,呼应函数内部会清零
  491. break;
  492. }
  493. break;
  494. }
  495. uiVoiceCnt=const_voice_short; //按键声响触发,滴一声就停。
  496. ucKeySec=0;//呼应按键服务处理程序后,按键编号清零,防止共同触发
  497. break;
  498. case 3:// 切换”光标”移动按键 对应朱兆祺学习板的S9键
  499. switch(ucWd)//在不同的窗口下,设置不同的参数
  500. {
  501. case 1: //窗口1
  502. switch(ucPart)//在窗口1下,依据不同的部分变量来设置不同的参数
  503. {
  504. case 0: //无光标显现的状况 此处的case 0能够省掉
  505. break;
  506. case 1: //设置第1行参数
  507. ucPart=2; //光标切换到下一行
  508. ucWd1Part1Update=1; //更新显现本来那一行,意图是更新反显光标的状况
  509. ucWd1Part2Update=1; //更新显现下一行, 意图是更新反显光标的状况
  510. break;
  511. case 2: //设置第2行参数
  512. ucPart=3; //光标切换到下一行
  513. ucWd1Part2Update=1; //更新显现本来那一行,意图是更新反显光标的状况
  514. ucWd1Part3Update=1; //更新显现下一行, 意图是更新反显光标的状况
  515. break;
  516. case 3: //设置第3行参数
  517. ucPart=4; //光标切换到下一行
  518. ucWd1Part3Update=1; //更新显现本来那一行,意图是更新反显光标的状况
  519. ucWd1Part4Update=1; //更新显现下一行, 意图是更新反显光标的状况
  520. break;
  521. case 4: //设置第4行参数
  522. ucWd=2;//切换到第2个窗口
  523. ucPart=1; //光标回来到最上面榜首行
  524. ucWd2Update=1; //窗口2整屏更新
  525. break;
  526. }
  527. break;
  528. case 2: //窗口2
  529. switch(ucPart)//在窗口2下,依据不同的部分变量来设置不同的参数
  530. {
  531. case 0: //无光标显现的状况 此处的case 0能够省掉
  532. break;
  533. case 1: //设置第1行参数
  534. ucPart=2; //光标切换到下一行
  535. ucWd2Part1Update=1; //更新显现本来那一行,意图是更新反显光标的状况
  536. ucWd2Part2Update=1; //更新显现下一行, 意图是更新反显光标的状况
  537. break;
  538. case 2: //设置第2行参数
  539. ucPart=3; //光标切换到下一行
  540. ucWd2Part2Update=1; //更新显现本来那一行,意图是更新反显光标的状况
  541. ucWd2Part3Update=1; //更新显现下一行, 意图是更新反显光标的状况
  542. break;
  543. case 3: //设置第3行参数
  544. ucPart=4; //光标切换到下一行
  545. ucWd2Part3Update=1; //更新显现本来那一行,意图是更新反显光标的状况
  546. ucWd2Part4Update=1; //更新显现下一行, 意图是更新反显光标的状况
  547. break;
  548. case 4: //设置第4行参数
  549. ucWd=1;//切换到第1个窗口
  550. ucPart=1; //光标回来到最上面榜首行
  551. ucWd1Update=1; //窗口1整屏更新
  552. break;
  553. }
  554. break;
  555. }
  556. uiVoiceCnt=const_voice_short; //按键声响触发,滴一声就停。
  557. ucKeySec=0;//呼应按键服务处理程序后,按键编号清零,防止共同触发
  558. break;
  559. case 4: // 设置按键对应朱兆祺学习板的S13键,按一次进入设置状况,呈现反显光标。再按一次推出设置状况,消除反显光标,而且强行切换到第1个窗口
  560. switch(ucWd)//在不同的窗口下,设置不同的参数
  561. {
  562. case 1://窗口1
  563. switch(ucPart)//在窗口1下,依据不同的部分变量来设置不同的参数
  564. {
  565. case 0: //无光标显现的状况
  566. ucPart=1; //光标显现榜首行,进入设置形式
  567. ucWd1Part1Update=1; //更新显现
  568. break;
  569. case 1: //设置第1行参数
  570. ucPart=0; //无光标显现,退出设置形式
  571. ucWd1Part1Update=1; //更新显现
  572. break;
  573. case 2: //设置第2行参数
  574. ucPart=0; //无光标显现,退出设置形式
  575. ucWd1Part2Update=1; //更新显现
  576. break;
  577. case 3: //设置第3行参数
  578. ucPart=0; //无光标显现,退出设置形式
  579. ucWd1Part3Update=1; //更新显现
  580. break;
  581. case 4: //设置第4行参数
  582. ucPart=0; //无光标显现,退出设置形式
  583. ucWd1Part4Update=1; //更新显现
  584. break;
  585. }
  586. break;
  587. case 2://窗口2
  588. switch(ucPart)//在窗口2下,依据不同的部分变量来设置不同的参数
  589. {
  590. case 0: //无光标显现的状况
  591. ucWd=1; //强行切换到第1个窗口
  592. ucPart=1; //光标显现榜首行,进入设置形式
  593. ucWd1Update=1; //窗口1整屏更新
  594. break;
  595. case 1: //设置第1行参数
  596. ucWd=1; //强行切换到第1个窗口
  597. ucPart=0; //无光标显现,退出设置形式
  598. ucWd1Update=1; //窗口1整屏更新
  599. break;
  600. case 2: //设置第2行参数
  601. ucWd=1; //强行切换到第1个窗口
  602. ucPart=0; //无光标显现,退出设置形式
  603. ucWd1Update=1; //窗口1整屏更新
  604. break;
  605. case 3: //设置第3行参数
  606. ucWd=1; //强行切换到第1个窗口
  607. ucPart=0; //无光标显现,退出设置形式
  608. ucWd1Update=1; //窗口1整屏更新
  609. break;
  610. case 4: //设置第4行参数
  611. ucWd=1; //强行切换到第1个窗口
  612. ucPart=0; //无光标显现,退出设置形式
  613. ucWd1Update=1; //窗口1整屏更新
  614. break;
  615. }
  616. break;
  617. }
  618. uiVoiceCnt=const_voice_short; //按键声响触发,滴一声就停。
  619. ucKeySec=0;//呼应按键服务处理程序后,按键编号清零,防止共同触发
  620. break;
  621. }
  622. }
  623. unsigned char *number_to_matrix(unsigned charucBitNumber)
  624. {
  625. unsigned char *p_ucAnyNumber;//此指针依据ucBitNumber数值的巨细,别离调用不同的字库。
  626. switch(ucBitNumber)//依据ucBitNumber数值的巨细,别离调用不同的字库。
  627. {
  628. case 0:
  629. p_ucAnyNumber=Zf816_0;
  630. break;
  631. case 1:
  632. p_ucAnyNumber=Zf816_1;
  633. break;
  634. case 2:
  635. p_ucAnyNumber=Zf816_2;
  636. break;
  637. case 3:
  638. p_ucAnyNumber=Zf816_3;
  639. break;
  640. case 4:
  641. p_ucAnyNumber=Zf816_4;
  642. break;
  643. case 5:
  644. p_ucAnyNumber=Zf816_5;
  645. break;
  646. case 6:
  647. p_ucAnyNumber=Zf816_6;
  648. break;
  649. case 7:
  650. p_ucAnyNumber=Zf816_7;
  651. break;
  652. case 8:
  653. p_ucAnyNumber=Zf816_8;
  654. break;
  655. case 9:
  656. p_ucAnyNumber=Zf816_9;
  657. break;
  658. case 10:
  659. p_ucAnyNumber=Zf816_nc;
  660. break;
  661. default: //假如上面的条件都不契合,那么默许指向空字模
  662. p_ucAnyNumber=Zf816_nc;
  663. break;
  664. }
  665. return p_ucAnyNumber;//回来转化完毕后的指针
  666. }
  667. void lcd_display_service(void) //应用层面的液晶屏显现程序
  668. {
  669. switch(ucWd)//本程序的中心变量,窗口显现变量。类似于一级菜单的变量。代表显现不同的窗口。
  670. {
  671. case 1:
  672. wd1();//窗口1显现的内容
  673. break;
  674. case 2:
  675. wd2();//窗口2显现的内容
  676. break;
  677. //本程序只需2个窗口,所以只需一个case 1,假如要添加窗口,就直接添加 case 2, case 3…
  678. }
  679. }
  680. void wd1(void)//窗口1显现的内容
  681. {
  682. unsigned char ucAnyNumber_1; //分化变量的个位
  683. unsigned char ucAnyNumber_10; //分化变量的十位
  684. unsigned char *p_ucAnyNumber_1; //经过数字转化成字模后,分化变量的个位字模首地址
  685. unsigned char *p_ucAnyNumber_10; //经过数字转化成字模后,分化变量的十位字模首地址
  686. unsigned char ucCursorFlag;//光标标志,也便是反显的标志,它是依据部分变量ucPart来定的
  687. /* 注释三:
  688. * 把每一个窗口的内容分为两种类型,一种类型是那些不必常常改写显现的内容,只需在切换窗口的时分
  689. * 才需求更新,这种内容放在整屏更新显现的括号里,比方清屏操作等内容。别的一种是那些常常需求
  690. * 改写显现的内容,这种内容放在部分更新显现的括号里。
  691. */
  692. if(ucWd1Update==1)//窗口1整屏更新,里边只放那些不必常常改写显现的内容
  693. {
  694. ucWd1Update=0;//及时清零,防止一向更新
  695. ucWd1Part1Update=1; //激活窗口1的第1行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  696. ucWd1Part2Update=1; //激活窗口1的第2行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  697. ucWd1Part3Update=1; //激活窗口1的第3行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  698. ucWd1Part4Update=1; //激活窗口1的第4行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  699. display_clear(0x00); // 清屏操作, 悉数显现空填充0x00,悉数显现点阵用0xff。
  700. clear_all_canvas();//把画布悉数清零
  701. insert_buffer_to_canvas(0,0,Zf816_mao_hao,0,1,16);//把冒号的字模刺进画布
  702. display_lattice(0,0,Hz1616_yi,0,2,16,0); //一窗口一行,这些内容不必常常更新,只需在切换窗口的时分才更新显现
  703. display_lattice(1,0,Hz1616_chuang,0,2,16,0);
  704. display_lattice(2,0,Hz1616_kou,0,2,16,0);
  705. display_lattice(3,0,Hz1616_yi,0,2,16,0);
  706. display_lattice(4,0,Hz1616_hang,0,2,16,0);
  707. display_lattice(0,16,Hz1616_yi,0,2,16,0); //一窗口二行
  708. display_lattice(1,16,Hz1616_chuang,0,2,16,0);
  709. display_lattice(2,16,Hz1616_kou,0,2,16,0);
  710. display_lattice(3,16,Hz1616_er,0,2,16,0);
  711. display_lattice(4,16,Hz1616_hang,0,2,16,0);
  712. display_lattice(8,0,Hz1616_yi,0,2,16,0); //一窗口三行
  713. display_lattice(9,0,Hz1616_chuang,0,2,16,0);
  714. display_lattice(10,0,Hz1616_kou,0,2,16,0);
  715. display_lattice(11,0,Hz1616_san,0,2,16,0);
  716. display_lattice(12,0,Hz1616_hang,0,2,16,0);
  717. display_lattice(8,16,Hz1616_yi,0,2,16,0); //一窗口四行
  718. display_lattice(9,16,Hz1616_chuang,0,2,16,0);
  719. display_lattice(10,16,Hz1616_kou,0,2,16,0);
  720. display_lattice(11,16,Hz1616_si,0,2,16,0);
  721. display_lattice(12,16,Hz1616_hang,0,2,16,0);
  722. }
  723. /* 注释四:
  724. * 留意!我前面讲数码管显现的时分有一句话讲错了,我那时说<部分更新应该写在整屏更新之前>,这是不对的。
  725. * 依照现在的显现程序结构<即整屏显现更新括号里包含了一切部分变量的激活>,应该是<整屏更新应该写在部分更新之前>
  726. * 这样才对。
  727. */
  728. if(ucWd1Part1Update==1) //窗口1的第1行部分更新显现变量,里边放一些常常需求改写显现的内容
  729. {
  730. ucWd1Part1Update=0; //及时清零,防止一向更新
  731. if(ucPart==1) //被选中
  732. {
  733. ucCursorFlag=1; //反显 显现
  734. }
  735. else //没被选中
  736. {
  737. ucCursorFlag=0; //正常 显现
  738. }
  739. if(ucData_1_1>=10) //有2位数以上
  740. {
  741. ucAnyNumber_10=ucData_1_1/10;//十位
  742. }
  743. else //不然显现空
  744. {
  745. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  746. }
  747. ucAnyNumber_1=ucData_1_1%10/1;//个位
  748. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  749. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  750. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  751. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  752. display_lattice(5,0,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  753. }
  754. if(ucWd1Part2Update==1) //窗口1的第2行部分更新显现变量,里边放一些常常需求改写显现的内容
  755. {
  756. ucWd1Part2Update=0; //及时清零,防止一向更新
  757. if(ucPart==2) //被选中
  758. {
  759. ucCursorFlag=1; //反显 显现
  760. }
  761. else //没被选中
  762. {
  763. ucCursorFlag=0; //正常 显现
  764. }
  765. if(ucData_1_2>=10) //有2位数以上
  766. {
  767. ucAnyNumber_10=ucData_1_2/10;//十位
  768. }
  769. else //不然显现空
  770. {
  771. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  772. }
  773. ucAnyNumber_1=ucData_1_2%10/1;//个位
  774. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  775. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  776. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  777. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  778. display_lattice(5,16,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  779. }
  780. if(ucWd1Part3Update==1) //窗口1的第3行部分更新显现变量,里边放一些常常需求改写显现的内容
  781. {
  782. ucWd1Part3Update=0; //及时清零,防止一向更新
  783. if(ucPart==3) //被选中
  784. {
  785. ucCursorFlag=1; //反显 显现
  786. }
  787. else //没被选中
  788. {
  789. ucCursorFlag=0; //正常 显现
  790. }
  791. if(ucData_1_3>=10) //有2位数以上
  792. {
  793. ucAnyNumber_10=ucData_1_3/10;//十位
  794. }
  795. else //不然显现空
  796. {
  797. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  798. }
  799. ucAnyNumber_1=ucData_1_3%10/1;//个位
  800. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  801. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  802. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  803. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  804. display_lattice(13,0,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  805. }
  806. if(ucWd1Part4Update==1) //窗口1的第4行部分更新显现变量,里边放一些常常需求改写显现的内容
  807. {
  808. ucWd1Part4Update=0; //及时清零,防止一向更新
  809. if(ucPart==4) //被选中
  810. {
  811. ucCursorFlag=1; //反显 显现
  812. }
  813. else //没被选中
  814. {
  815. ucCursorFlag=0; //正常 显现
  816. }
  817. if(ucData_1_4>=10) //有2位数以上
  818. {
  819. ucAnyNumber_10=ucData_1_4/10;//十位
  820. }
  821. else //不然显现空
  822. {
  823. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  824. }
  825. ucAnyNumber_1=ucData_1_4%10/1;//个位
  826. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  827. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  828. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  829. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  830. display_lattice(13,16,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  831. }
  832. }
  833. void wd2(void)//窗口2显现的内容
  834. {
  835. unsigned char ucAnyNumber_1; //分化变量的个位
  836. unsigned char ucAnyNumber_10; //分化变量的十位
  837. unsigned char *p_ucAnyNumber_1; //经过数字转化成字模后,分化变量的个位字模首地址
  838. unsigned char *p_ucAnyNumber_10; //经过数字转化成字模后,分化变量的十位字模首地址
  839. unsigned char ucCursorFlag;//光标标志,也便是反显的标志,它是依据部分变量ucPart来定的
  840. if(ucWd2Update==1)//窗口2整屏更新,里边只放那些不必常常改写显现的内容
  841. {
  842. ucWd2Update=0;//及时清零,防止一向更新
  843. ucWd2Part1Update=1; //激活窗口2的第1行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  844. ucWd2Part2Update=1; //激活窗口2的第2行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  845. ucWd2Part3Update=1; //激活窗口2的第3行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  846. ucWd2Part4Update=1; //激活窗口2的第4行部分更新显现变量,这儿在前面数码管显现结构上有所改进
  847. display_clear(0x00); // 清屏操作, 悉数显现空填充0x00,悉数显现点阵用0xff。
  848. clear_all_canvas();//把画布悉数清零
  849. insert_buffer_to_canvas(0,0,Zf816_mao_hao,0,1,16);//把冒号的字模刺进画布
  850. display_lattice(0,0,Hz1616_er,0,2,16,0); //二窗口一行,这些内容不必常常更新,只需在切换窗口的时分才更新显现
  851. display_lattice(1,0,Hz1616_chuang,0,2,16,0);
  852. display_lattice(2,0,Hz1616_kou,0,2,16,0);
  853. display_lattice(3,0,Hz1616_yi,0,2,16,0);
  854. display_lattice(4,0,Hz1616_hang,0,2,16,0);
  855. display_lattice(0,16,Hz1616_er,0,2,16,0); //二窗口二行
  856. display_lattice(1,16,Hz1616_chuang,0,2,16,0);
  857. display_lattice(2,16,Hz1616_kou,0,2,16,0);
  858. display_lattice(3,16,Hz1616_er,0,2,16,0);
  859. display_lattice(4,16,Hz1616_hang,0,2,16,0);
  860. display_lattice(8,0,Hz1616_er,0,2,16,0); //二窗口三行
  861. display_lattice(9,0,Hz1616_chuang,0,2,16,0);
  862. display_lattice(10,0,Hz1616_kou,0,2,16,0);
  863. display_lattice(11,0,Hz1616_san,0,2,16,0);
  864. display_lattice(12,0,Hz1616_hang,0,2,16,0);
  865. display_lattice(8,16,Hz1616_er,0,2,16,0); //二窗口四行
  866. display_lattice(9,16,Hz1616_chuang,0,2,16,0);
  867. display_lattice(10,16,Hz1616_kou,0,2,16,0);
  868. display_lattice(11,16,Hz1616_si,0,2,16,0);
  869. display_lattice(12,16,Hz1616_hang,0,2,16,0);
  870. }
  871. if(ucWd2Part1Update==1) //窗口2的第1行部分更新显现变量,里边放一些常常需求改写显现的内容
  872. {
  873. ucWd2Part1Update=0; //及时清零,防止一向更新
  874. if(ucPart==1) //被选中
  875. {
  876. ucCursorFlag=1; //反显 显现
  877. }
  878. else //没被选中
  879. {
  880. ucCursorFlag=0; //正常 显现
  881. }
  882. if(ucData_2_1>=10) //有2位数以上
  883. {
  884. ucAnyNumber_10=ucData_2_1/10;//十位
  885. }
  886. else //不然显现空
  887. {
  888. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  889. }
  890. ucAnyNumber_1=ucData_2_1%10/1;//个位
  891. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  892. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  893. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  894. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  895. display_lattice(5,0,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  896. }
  897. if(ucWd2Part2Update==1) //窗口2的第2行部分更新显现变量,里边放一些常常需求改写显现的内容
  898. {
  899. ucWd2Part2Update=0; //及时清零,防止一向更新
  900. if(ucPart==2) //被选中
  901. {
  902. ucCursorFlag=1; //反显 显现
  903. }
  904. else //没被选中
  905. {
  906. ucCursorFlag=0; //正常 显现
  907. }
  908. if(ucData_2_2>=10) //有2位数以上
  909. {
  910. ucAnyNumber_10=ucData_2_2/10;//十位
  911. }
  912. else //不然显现空
  913. {
  914. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  915. }
  916. ucAnyNumber_1=ucData_2_2%10/1;//个位
  917. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  918. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  919. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  920. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  921. display_lattice(5,16,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  922. }
  923. if(ucWd2Part3Update==1) //窗口2的第3行部分更新显现变量,里边放一些常常需求改写显现的内容
  924. {
  925. ucWd2Part3Update=0; //及时清零,防止一向更新
  926. if(ucPart==3) //被选中
  927. {
  928. ucCursorFlag=1; //反显 显现
  929. }
  930. else //没被选中
  931. {
  932. ucCursorFlag=0; //正常 显现
  933. }
  934. if(ucData_2_3>=10) //有2位数以上
  935. {
  936. ucAnyNumber_10=ucData_2_3/10;//十位
  937. }
  938. else //不然显现空
  939. {
  940. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  941. }
  942. ucAnyNumber_1=ucData_2_3%10/1;//个位
  943. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  944. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  945. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  946. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  947. display_lattice(13,0,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  948. }
  949. if(ucWd2Part4Update==1) //窗口2的第4行部分更新显现变量,里边放一些常常需求改写显现的内容
  950. {
  951. ucWd2Part4Update=0; //及时清零,防止一向更新
  952. if(ucPart==4) //被选中
  953. {
  954. ucCursorFlag=1; //反显 显现
  955. }
  956. else //没被选中
  957. {
  958. ucCursorFlag=0; //正常 显现
  959. }
  960. if(ucData_2_4>=10) //有2位数以上
  961. {
  962. ucAnyNumber_10=ucData_2_4/10;//十位
  963. }
  964. else //不然显现空
  965. {
  966. ucAnyNumber_10=10;//鄙人面的转化函数中,代码10表明空字模
  967. }
  968. ucAnyNumber_1=ucData_2_4%10/1;//个位
  969. p_ucAnyNumber_10=number_to_matrix(ucAnyNumber_10); //把数字转化成字模首地址
  970. p_ucAnyNumber_1=number_to_matrix(ucAnyNumber_1); //把数字转化成字模首地址
  971. insert_buffer_to_canvas(2,0,p_ucAnyNumber_10,ucCursorFlag,1,16);//把十的字模刺进画布
  972. insert_buffer_to_canvas(3,0,p_ucAnyNumber_1,ucCursorFlag,1,16);//把个的字模刺进画布
  973. display_lattice(13,16,ucCanvasBuffer,0,4,16,0); //显现整屏的画布,最终的参数0是偏移量
  974. }
  975. }
  976. void clear_all_canvas(void)//把画布悉数清零
  977. {
  978. unsigned int j=0;
  979. unsigned int i=0;
  980. for(j=0;j<16;j++)//这儿的16表明画布有16行
  981. {
  982. for(i=0;i<4;i++) //这儿的4表明画布每行有4个字节
  983. {
  984. ucCanvasBuffer[j*4+i]=0x00;
  985. }
  986. }
  987. }
  988. void display_clear(unsigned char ucFillDate) // 清屏悉数显现空填充0x00 悉数显现点阵用0xff
  989. {
  990. unsigned char x,y;
  991. WriteCommand(0x34);//关显现缓冲指令
  992. WriteCommand(0x34);//关显现缓冲指令成心写2次,怕1次关不了 这个是由于我参考到某厂家的驱动程序也是这样写的
  993. y=0;
  994. while(y<32)//y轴的规模0至31
  995. {
  996. WriteCommand(y+0x80); //笔直地址
  997. WriteCommand(0x80); //水平地址
  998. for(x=0;x<32;x++)//256个横向点,有32个字节
  999. {
  1000. LCDWriteData(ucFillDate);
  1001. }
  1002. y++;
  1003. }
  1004. WriteCommand(0x36); //开显现缓冲指令
  1005. }
  1006. /* 注释五:
  1007. * 把字模刺进画布的函数.
  1008. * 这是本节的中心函数,读者尤其要搞懂x_amount和y_amount对应的显现联系。
  1009. * 第1,2个参数x,y是在画布中的坐标系统。
  1010. * x的规模是0至3,由于画布的横向只需4个字节。y的规模是0至15,由于画布的纵向只需16行。
  1011. * 第3个参数*ucArray是字模的数组。
  1012. * 第4个参数ucFbFlag是反白显现标志。0代表正常显现,1代表反白显现。
  1013. * 第5,6个参数x_amount,y_amount别离代表字模数组的横向有多少个字节,纵向有几横。
  1014. */
  1015. 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)
  1016. {
  1017. unsigned int j=0;
  1018. unsigned int i=0;
  1019. unsigned char ucTemp;
  1020. for(j=0;j
  1021. {
  1022. for(i=0;i
  1023. {
  1024. ucTemp=ucArray[j*x_amount+i];
  1025. if(ucFbFlag==0)
  1026. {
  1027. ucCanvasBuffer[(y+j)*4+x+i]=ucTemp; //这儿的4代表画布每一行只需4个字节
  1028. }
  1029. else
  1030. {
  1031. ucCanvasBuffer[(y+j)*4+x+i]=~ucTemp; //这儿的4代表画布每一行只需4个字节
  1032. }
  1033. }
  1034. }
  1035. }
  1036. /* 注释六:
  1037. * 显现恣意点阵函数.
  1038. * 留意,本函数在前几节的基础上多添加了第7个参数uiOffSetAddr,它是偏移地址。
  1039. * 关于这个函数,读者尤其要搞懂x_amount和y_amount对应的显现联系。
  1040. * 第1,2个参数x,y是坐标系统。x的规模是0至15,y的规模是0至31.
  1041. * 第3个参数*ucArray是字模的数组。
  1042. * 第4个参数ucFbFlag是反白显现标志。0代表正常显现,1代表反白显现。
  1043. * 第5,6个参数x_amount,y_amount别离代表字模数组的横向有多少个字节,纵向有几横。
  1044. * 第7个参数uiOffSetAddr是偏移地址,代表字模数组的从第几个数据开端显现。
  1045. */
  1046. 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)
  1047. {
  1048. unsigned int j=0;
  1049. unsigned int i=0;
  1050. unsigned char ucTemp;
  1051. //留意,要把以下两行指令屏蔽,不然屏幕在更新显现时会整屏闪烁
  1052. //WriteCommand(0x34);//关显现缓冲指令
  1053. //WriteCommand(0x34);//关显现缓冲指令成心写2次,怕1次关不了 这个是由于我参考到某厂家的驱动程序也是这样写的
  1054. for(j=0;j
  1055. {
  1056. WriteCommand(y+j+0x80); //笔直地址
  1057. WriteCommand(x+0x80); //水平地址
  1058. for(i=0;i
  1059. {
  1060. ucTemp=ucArray[j*x_amount+i+uiOffSetAddr]; //uiOffSetAddr是字模数组的偏移地址
  1061. if(ucFbFlag==1)//反白显现
  1062. {
  1063. ucTemp=~ucTemp;
  1064. }
  1065. LCDWriteData(ucTemp);
  1066. // delay_short(30000);//把上一节这个延时函数去掉,加速刷屏速度
  1067. }
  1068. }
  1069. WriteCommand(0x36); //开显现缓冲指令
  1070. }
  1071. void SendByteToLcd(unsigned char ucData)//发送一个字节数据到液晶模块
  1072. {
  1073. unsigned char i;
  1074. for ( i = 0; i < 8; i++ )
  1075. {
  1076. if ( (ucData << i) & 0x80 )
  1077. {
  1078. LCDSID_dr = 1;
  1079. }
  1080. else
  1081. {
  1082. LCDSID_dr = 0;
  1083. }
  1084. LCDCLK_dr = 0;
  1085. LCDCLK_dr = 1;
  1086. }
  1087. }
  1088. void SPIWrite(unsigned char ucWData, unsigned char ucWRS) //模仿SPI发送一个字节的指令或许数据给液晶模块的底层驱动
  1089. {
  1090. SendByteToLcd( 0xf8 + (ucWRS << 1) );
  1091. SendByteToLcd( ucWData & 0xf0 );
  1092. SendByteToLcd( (ucWData << 4) & 0xf0);
  1093. }
  1094. void WriteCommand(unsigned char ucCommand) //发送一个字节的指令给液晶模块
  1095. {
  1096. LCDCS_dr = 0;
  1097. LCDCS_dr = 1;
  1098. SPIWrite(ucCommand, 0);
  1099. delay_short(90);
  1100. }
  1101. void LCDWriteData(unsigned char ucData)//发送一个字节的数据给液晶模块
  1102. {
  1103. LCDCS_dr = 0;
  1104. LCDCS_dr = 1;
  1105. SPIWrite(ucData, 1);
  1106. }
  1107. void LCDInit(void) //初始化函数内部包含液晶模块的复位
  1108. {
  1109. LCDRST_dr = 1;//复位
  1110. LCDRST_dr = 0;
  1111. LCDRST_dr = 1;
  1112. }
  1113. void delay_short(unsigned int uiDelayShort) //延时函数
  1114. {
  1115. unsigned int i;
  1116. for(i=0;i
  1117. {
  1118. ;
  1119. }
  1120. }
  1121. void delay_long(unsigned int uiDelayLong)
  1122. {
  1123. unsigned int i;
  1124. unsigned int j;
  1125. for(i=0;i
  1126. {
  1127. for(j=0;j<500;j++)//内嵌循环的空指令数量
  1128. {
  1129. ; //一个分号相当于履行一条空句子
  1130. }
  1131. }
  1132. }

总结陈词:
这一节讲了在多个窗口里设置不同的参数。还有一种常见的项目,要求把第1窗口是用来作为主菜单,主菜单里边有3个子菜单,能够经过移动光标进入不同的子菜单窗口进行参数设置,这类项目该怎么编程?欲知概况,请听下回分化—–经过主菜单移动光标来进入子菜单窗口的液晶屏程序。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/yingjian/262018.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部