章出处:http://www.cywlcd.com/版权归深圳驰宇微科技所有 qq驰宇微液晶屏: 2355433581
驰宇微中文字库12864是一款内置3000多个常用汉字的模块,可以极大地减少工程师编写中文的工作,适合需要显示比较多的汉字的情况. 亮点就是支持中英文混合输出.
产品名称: | 驰宇微 LCD图形点阵液晶屏 |
| ||
产品型号: | CYW-B12864G | |||
使用范围: | 仪器仪表、医疗设备、电力设备、通讯设备、安防设备、数控设备、家用电器、工业控制、税控机、IC卡设备等 | |||
详情参数: | ||||
液晶屏点阵数: | 128*64 | 液晶屏外形尺寸: | 93mm×70mm | |
控制器 : | KS0108 or SBN0064 | 液晶屏视域尺寸: | 70.7mmx38.8mm | |
液晶屏规格: | STN or FSTN | 点间距: | 0.52×0.52mm | |
液晶屏视角: | 6点和12点方向 | 液晶屏类别: | LCD图形点阵型 | |
背光: | 高亮LED背光 | 工作电压: | 3.3V & 5V | |
颜色: | 灰膜、黑膜、黄绿膜、蓝膜 | 接口类型: | 并口 | |
注明:可根据应用要求设计结构尺寸和接口定义,欢迎订制! |
代码没啥好说,我尽量多写了注释,播放动画也很流畅的
C代码
1. #ifndef _LCD12864_H
2. #define _LCD12864_H
3. #include "my51.h"
4.
5. #define LCD_dataBus P0 //总线
6. sbit LCD_EN = P3^4; //使能控制
7. sbit LCD_RS = P3^5; //数据_命令选择端
8. sbit LCD_RW = P3^6; //读写控制
9. sbit LCD_PSB= P3^7; //串并选择,H并行,L串行
10.
11.
12. extern bool bShowPicFlag; //绘图时图像显示控制(仅控制GDRAM)
13.
14. /*************************基本功能函数*********************************************/
15. extern void LCD12864_init(); //初始化,必须置顶调用
16. extern void LCD12864_setPos(u8 row, u8 cols); //设置光标位置
17. extern void LCD12864_writeByte(u8 dat); //写一个字节
18. extern void LCD12864_writeCmd(u8 cmd); //写指令
19. extern u8 LCD12864_readByte(); //读一个字节ram
20. extern u8 LCD12864_readIR(); //读暂存器
21. extern bool LCD12864_isBusy(); //判忙
22.
23. /*************************调用基本字库显示文字**************************************/
24. //独创支持全角半角字符及中英混合的字符串,或字符串的子串,起始行号row(0-3)和列坐标cols(0-15),写满屏幕为止
25. //行号4-7行是滚动区
26. extern void LCD12864_writeData(u8 row, u8 cols,u8* pBuf,u8 dataSize);//写一堆数据
27. extern void LCD12864_earseSomeDDRam(u8 row,u8 cols,u8 dataSize); //擦除N字节DDRam
28.
29. /*************************用户自定义图标字体****************************************/
30. extern void LCD12864_writeCGRAM(u8 userRamNum,u8* pCGRAM_userCode); //写自定义图标字体
31. extern void LCD12864_showCGRAM(u8 row,u8 cols,u8 num) ; //显示自定义图标字体,row(0-3),cols(0-15)
32. extern void LCD12864_clearCGRAM(u8 CGRAM_groupNum) ; //CGRAM清零(初始化也可清0)
33.
34. /*************************图像显示功能函数**********************************************/
35. extern void LCD12864_showGDRAM(bool bShowImage); //GDRAM绘图显示开关
36. extern void LCD12864_clearGDRAM(); //液晶整个可视区的GDRAM快速清0
37. //前4参数:起始点x(0-7)位址,y(0-63)坐标,要显示的宽度(1-128)和高度(1-64)[可显示从图像左上角开始的部分区域]
38. //后4参数:图像代码地址,图像本身的宽度(1-128)和高度(1-64), 反白(true反白,false不反白)
39. //画图填充GDRAM ,注:显示的区域或者图像本身宽度必须是8的倍数
40. extern u8 LCD12864_drawGDRAM(u8 x,u8 y,u8 width,u8 height,u8 *pImageCode,u8 imageWidth,u8 imageHight,bool bReverse);
41. extern void LCD12864_drawDot(u8 x,u8 y,u8 flag); //打点,x(0-127),y(0-63),flag(0正常,1反白,2清0)
42. extern bool LCD12864_drawXYLine(u8 x1, u8 y1,u8 x2, u8 y2,u8 flag); //画水平或垂直直线
43. extern void LCD12864_drawAnyLine(u8 x1, u8 y1,u8 x2, u8 y2,u8 flag) ; //画任意直线
44. extern void LCD12864_drawRectangle(u8 x,u8 y ,u8 width,u8 height,u8 flag);//画矩形
45. extern void LCD12864_drawFillRect(u8 x,u8 y, u8 width,u8 hight,u8 flag); //填充矩形,可对矩形区反白或清0
46. extern void LCD12864_drawVerticalSquare(u8 x,u8 y,u8 r,u8 flag) ; //画站立的正方形
47. extern void LCD12864_drawCircle(u8 x0,u8 y0,u8 r,u8 flag); //画圆
48.
49. //打点法全屏画图有点慢了,打点法反白矩形区还可以,建议矩形范围小一些,不然比较慢
50. //打点法效果最好,因为文字的矩形区比较小,速度很快
51. //不过绘图法反白文字效率高,flash空间充裕的建议用绘图法
52.
53. /***************************全屏滚动*******************************************/
54. //需要滚动时,用LCD12864_writeScrollData()函数,参数和LCD12864_writeData()一样
55. extern void LCD12864_writeScrollData(u8 row,u8 cols,u8* pBuf,u8 dataSize);//写数据 (滚动模式)
56. extern void LCD12864_setScrollPos(u8 row, u8 cols); //设置滚动模式的坐标
57. extern void LCD12864_showScrollCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum);//用于CGRAM滚动显示前执行
58. extern void LCD12864_startScroll(u8 scrollNum,u16 delay_ms); //滚动开始
59. #endif
1. #include "lcd12864.h"
2. //图像与文字,图像与用户图标,像素重合时是异或关系
3. //文字与用户图标是覆盖关系
4. bool bShowPicFlag=false; //绘图时图像显示控制
5.
6. /*
7. u8 LCD12864_table[]={"123456789"};
8. */
9.
10. void LCD12864_drawFillRect(u8 x,u8 y, u8 width,u8 hight,u8 flag)//填充任意位置的整个矩形
11. {//矩形起始坐标x(0-127),y(0-63),宽(1-128)高(1-64),flag有3种值,0正常填充,1反色,2清0
12. u8 i=0;
13. u8 j=0;
14. if(0==width||0==hight) //矩形宽度或高度为0时返回
15. {
16. return ;
17. }
18. if( (x+width>128 ||(y+hight)>64) )
19. {
20. led2=0;
21. return;
22. }
23. for(j=0;j<hight;j++)
24. {
25. for(i=0;i<width;i++)
26. {
27. LCD12864_drawDot(x+i, y+j,flag);
28. }
29. }
30. }
31.
32.
33. void LCD12864_drawRectangle(u8 x,u8 y, u8 width,u8 hight,u8 flag)//画矩形
34. { //矩形起始坐标x(0-127),y(0-63),宽度(1-128)和高度(1-64) flag有3种值,0正常写1,1反色,2清0
35. if(0==width||0==hight) //矩形宽度或高度为0时返回
36. {
37. return ;
38. }
39. width--;hight--;
40. LCD12864_drawXYLine(x, y,x+width, y, flag);
41. LCD12864_drawXYLine(x+width, y,x+width, y+hight, flag);
42. LCD12864_drawXYLine(x, y,x, y+hight, flag);
43. LCD12864_drawXYLine(x, y+hight,x+width, y+hight, flag);
44. }
45.
46. bool LCD12864_drawXYLine(u8 x1,u8 y1, u8 x2, u8 y2, u8 flag)//画水平或垂直直线
47. { //起始点坐标和终点坐标,x(0-127),y(0-63), flag有3种值,0正常写1,1反色,2清0
48. u8 n=0;
49. if(flag>2|| x1>127||x2>127||y1>63||y2>63)
50. {
51. return false;
52. }
53.
54. if(x1==x2)
55. {
56. for(n=0;n<abs(y2-y1)+1;n++)
57. {
58. LCD12864_drawDot( x1,y1+(y2>=y1?n:-n) ,flag);
59. }
60. }
61.
62. if(y1==y2)
63. {
64. for(n=0;n<abs(x2-x1)+1;n++)
65. {
66. LCD12864_drawDot(x1+(x2>=x1?n:-n),y1,flag) ;
67. }
68. }
69. return true;
70. }
71.
72. void LCD12864_drawCircle(u8 x0,u8 y0,u8 r,u8 flag)
73. {
74. s8 a,b;
75. s8 di;
76. if(r>31 ||r==0) return; //参数过滤,次液晶显示的最大圆半径为31
77. a=0;
78. b=r;
79. di=3-2*r; //判断下个点位置的标志
80. while(a<=b)
81. {
82. LCD12864_drawDot(x0-b,y0-a,flag); //3
83. LCD12864_drawDot(x0+b,y0-a,flag); //0
84. LCD12864_drawDot(x0-a,y0+b,flag); //1
85. LCD12864_drawDot(x0-b,y0-a,flag); //7
86. LCD12864_drawDot(x0-a,y0-b,flag); //2
87. LCD12864_drawDot(x0+b,y0+a,flag); //4
88. LCD12864_drawDot(x0+a,y0-b,flag); //5
89. LCD12864_drawDot(x0+a,y0+b,flag); //6
90. LCD12864_drawDot(x0-b,y0+a,flag);
91. a++;
92. //使用Bresenham算法画圆
93. if(di<0)
94. di +=4*a+6;
95. else
96. {
97. di +=10+4*(a-b);
98. b--;
99. }
100. LCD12864_drawDot(x0+a,y0+b,flag);
101. }
102. }
103.
104.
105. void LCD12864_drawVerticalSquare(u8 x,u8 y,u8 r,u8 flag) //画站立的正方形
106. {
107. u8 a,b;
108. float c=0;
109. a = 0;
110. b = r;
111. c = 3 - 2*r;
112. while(a < b)
113. {
114. LCD12864_drawDot(x+a,y+b,flag);
115. LCD12864_drawDot(x-a,y+b,flag);
116. LCD12864_drawDot(x+a,y-b,flag);
117. LCD12864_drawDot(x-a,y-b,flag);
118.
119. LCD12864_drawDot(x+b,y+a,flag);
120. LCD12864_drawDot(x-b,y+a,flag);
121. LCD12864_drawDot(x+b,y-a,flag);
122. LCD12864_drawDot(x-b,y-a,flag);
123.
124. if(c < 0)
125. {
126. c = c+4*a + 6;
127. }
128. else
129. {
130. c= c + 4*(a - b) + 10;
131. b-=1;
132. }
133. a = a + 1; //控制打点间隔
134.
135. }
136. if(a == b)
137. {
138. LCD12864_drawDot(x+a,y+b,flag);
139. LCD12864_drawDot(x-a,y+b,flag);
140. LCD12864_drawDot(x+a,y-b,flag);
141. LCD12864_drawDot(x-a,y+b,flag);
142.
143. LCD12864_drawDot(x+b,y+a,flag);
144. LCD12864_drawDot(x-b,y+a,flag);
145. LCD12864_drawDot(x+b,y-a,flag);
146. LCD12864_drawDot(x-b,y-a,flag);
147. }
148. }
149.
150.
151. void LCD12864_drawAnyLine(u8 StartX, u8 StartY,u8 EndX, u8 EndY, u8 flag) //画任意直线
152. {
153. u8 t, distance ; /*根据屏幕大小改变变量类型(如改为int型)*/
154. s16 x = 0 , y = 0 ;
155. s8 incx, incy, dx, dy ;
156. if((StartX==EndX) ||(StartY==EndY))
157. {
158. LCD12864_drawXYLine(StartX,StartY,EndX,EndY,flag);
159. return;
160. }
161.
162. dx = EndX - StartX ;
163. dy = EndY - StartY ;
164. incx = dx > 0 ?1:-1;
165. incy = dy > 0 ?1:-1;
166.
167. dx = abs( dx );
168. dy = abs( dy );
169. if( dx > dy )
170. {
171. distance = dx ;
172. }
173. else
174. {
175. distance = dy ;
176. }
177. LCD12864_drawDot( StartX, StartY, flag ) ; //反白补点
178. for( t = 0 ; t <= distance+1 ; t++ )
179. {
180. LCD12864_drawDot( StartX, StartY, flag ) ;
181. x += dx ;
182. y += dy ;
183. if( x > distance )
184. {
185. x -= distance ;
186. StartX += incx ;
187. }
188. if( y > distance )
189. {
190. y -= distance ;
191. StartY += incy ;
192. }
193. }
194. }
195.
196. void LCD12864_drawDot(u8 x, u8 y,u8 flag) //画点,0打点,1反色,2清0
197. { //x(0-127),y(0-63),flag有3种值,0正常写1,1反色,2清0
198. u8 x_word=0; //水平(0-127)个像素中的哪个字,一字16位
199. u8 x_mode=0; //取余
200. u8 y_part=0;
201. u8 y_bit=0;
202. u8 tempH=0;
203. u8 tempL=0;
204. x_word=x>>4; //在哪一个字(0-7) ,x_word=x/16
205. x_mode=x&0x0f; //在该字的哪一位 ,x_mode= x%16
206. y_part=y>>5; //在哪个屏0或1 ,y_part=y/32
207. y_bit= y&0x1f; //垂直方向,y_bit范围(0-31),y_bit=y%32
208. bShowPicFlag?LCD12864_writeCmd(0x36):LCD12864_writeCmd(0x34);
209. LCD12864_writeCmd(0x80+y_bit); //垂直坐标
210. LCD12864_writeCmd(0x80+8*y_part+x_word); //水平位址
211.
212. LCD12864_readByte();
213. tempH=LCD12864_readByte(); //先将该字16位数据保存
214. tempL= LCD12864_readByte();
215.
216. LCD12864_writeCmd(0x80+y_bit); //重设地址,因为AC计数器变了
217. LCD12864_writeCmd(0x80+8*y_part+x_word); //水平位址
218. if(0==flag) //不反白,打1,
219. {
220. if(x_mode<8) //如果x_mode小于8,说明点应位于该字的左边高8位中
221. {
222. LCD12864_writeByte( tempH | bit(7- x_mode) );
223. //LCD12864_writeByte(tempL);
224. }
225. else
226. {
227. //LCD12864_writeByte(tempH);
228. LCD12864_readByte(); //让AC走半步
229. LCD12864_writeByte(tempL|bit(15-x_mode));
230. }
231. }
232. else if(1==flag) //反白,该点与原来的状态相反
233. {
234. if(x_mode<8) //如果x_mode小于8,说明点应位于该字的左边高8位中
235. {
236. if(tempH & bit(7- x_mode)) //原来是1
237. {
238. LCD12864_writeByte( tempH&~bit(7- x_mode) ); //写0
239. }
240. else //原来是0
241. {
242. LCD12864_writeByte( tempH | bit(7- x_mode) ); //写1
243. }
244.
245. }
246. else
247. {
248. LCD12864_readByte(); //让AC走半字
249. if(tempL& bit(15-x_mode)) //原来是1的写0
250. {
251.
252. LCD12864_writeByte(tempL&~bit(15-x_mode)); //写0
253. }
254. else
255. {
256. LCD12864_writeByte(tempL|bit(15-x_mode)); //写0
257. }
258.
259. }
260. }
261. else if(2==flag) //清0
262. {
263. if(x_mode<8) //如果x_mode小于8,说明点应位于该字的左边高8位中
264. {
265. LCD12864_writeByte( tempH&~bit(7- x_mode) );
266. }
267. else
268. {
269. LCD12864_readByte(); //让AC走半字
270. LCD12864_writeByte(tempL&~bit(15-x_mode));
271. }
272. }
273. }
274.
275. void LCD12864_showGDRAM(bool bShowImage) //GDRAM图像显示开关
276. {
277. if(bShowImage) //开启显示
278. {
279. LCD12864_writeCmd(0x36);
280. LCD12864_writeCmd(0x30);
281. }
282. else //关闭显示
283. {
284. LCD12864_writeCmd(0x34);
285. LCD12864_writeCmd(0x30);
286. }
287. }
288.
289.
290. //填充GDRAM
291. u8 LCD12864_drawGDRAM(u8 x,u8 y,u8 width,u8 height,u8* pImageCode,u8 imageWidth,u8 imageHight,bool bReverse)
292. {//前4参数:起始点x(0-7)位址,y(0-63)坐标,要显示的宽度(1-128)和高度(1-64)[可显示从图像左上角开始的部分区域]
293. //后4参数:图像代码地址,图像本身的宽度(1-128)和高度(1-64), 反白(true反白,false不反白)
294. u8 i=0;
295. u8 j=0;
296. if( height > imageHight ) //检测显示高度,宽度不检测不会乱码
297. { //显示的高度不能超过图片本身高度
298. return 0x01; //也就是说可显示图像的部分区域(从图像左上角开始的部分区域)
299. }
300. width>>=3; //像素宽度转化为字节个数,所以width必须是8的整数倍
301. imageWidth>>=3; //像素宽度转化为字节个数,所以width必须是8的整数倍
302. if(bShowPicFlag)
303. {
304. LCD12864_writeCmd(0x36); //改写GDRAM时,开启绘图显示,可防止动画显示时闪动
305. }
306. else
307. {
308. LCD12864_writeCmd(0x34); //改写GDRAM时,关闭绘图显示
309. }
310.
311. for(j=0;j<height;j++) //写GDRAM
312. {
313. if(y+j>31) //地址变换
314. {
315. LCD12864_writeCmd(0x80+y+j-32); //垂直坐标
316. LCD12864_writeCmd(0x88+x); //水平位址
317. }
318. else
319. {
320. LCD12864_writeCmd(0x80+y+j);
321. LCD12864_writeCmd(0x80+x);
322. }
323. for(i=0;i<width;i++) //水平方向写数据,带反白控制
324. {
325. LCD12864_writeByte(bReverse?~pImageCode[imageWidth*j+i]:pImageCode[imageWidth*j+i]);
326. }
327. }
328. LCD12864_writeCmd(0x30);
329. return 0x02;
330. }
331.
332.
333. void LCD12864_clearGDRAM() //液晶可视区的绘图GDRAM清0
334. {
335. u8 j=0;
336. u8 i=0;
337. LCD12864_writeCmd(0x34); //扩展指令
338. for(j=0;j<64;j++) //垂直方向地址手动增加,当j=64时清整个GDram
339. { //我们只要清可视区的GDRAM就可以了
340. LCD12864_writeCmd(0x80+j); //y轴坐标
341. LCD12864_writeCmd(0x80); //x轴坐标
342. for(i=0;i<32;i++) //水平方向位址自动增加
343. {
344. LCD12864_writeByte(0x00);
345. }
346. }
347. LCD12864_writeCmd(0x30); //回到基本指令
348. }
349.
350.
351. /*--------------------------------CGRAM start----------------------------------------------*/
352. void LCD12864_clearCGRAM(u8 CGRAM_groupNum)//将用户自定义编码区CGRAM清0
353. { //参数一是CGRAM的4组用户空间组号码(0~3) ,参数二是用户自定义图表或汉字的编码
354. u8 i,addr=0;
355. bShowPicFlag?LCD12864_writeCmd(0x36):LCD12864_writeCmd(0x34);//扩展指令,绘图开关保持
356. LCD12864_writeCmd(0x02); //SR等于0,允许设置卷动地址
357. LCD12864_writeCmd(0x30); //恢复为8位并行,基本指令集
358. addr=(CGRAM_groupNum<<4)|0x40; //将CGRAM空间号转换为相应存储地址
359. LCD12864_writeCmd(addr); //定位到该位址(用户空间位址范围0x40-0x7F共128字节)
360. for(i=0;i<16;i++) //将用户自定义编码写入该16*16位元组空间
361. {
362. LCD12864_writeByte(0); //连续写2个字节共16位
363. LCD12864_writeByte(0);
364. }
365. }
366.
367. void LCD12864_writeScrollCGRAM(u8 CGRAM_groupNum, u8* pUserCode)//将用户自定义编码写入CGRAM
368. { //参数一是CGRAM的4组用户空间组号码(0~3) ,参数二是用户自定义图表或汉字的编码
369. u8 i,addr=0;
370. if(bShowPicFlag)
371. {
372. LCD12864_writeCmd(0x36); //开启绘图显示,可流畅播放动画
373. }
374. else
375. {
376. LCD12864_writeCmd(0x34); //默认关闭绘图显示
377. }
378. LCD12864_writeCmd(0x02); //SR等于0,允许设置卷动地址
379. LCD12864_writeCmd(0x30); //恢复为8位并行,基本指令集
380. addr=(CGRAM_groupNum<<4)|0x40; //将CGRAM空间号转换为相应存储地址
381. LCD12864_writeCmd(addr); //定位到该位址(用户空间位址范围0x40-0x7F共128字节)
382. for(i=0;i<16;i++) //将用户自定义编码写入该16*16位元组空间
383. {
384. LCD12864_writeByte(pUserCode[i*2]); //连续写2个字节共16位
385. LCD12864_writeByte(pUserCode[i*2+1]);
386. }
387. }
388.
389. void LCD12864_writeCGRAM(u8 CGRAM_groupNum, u8* pUserCode)//将用户自定义编码写入CGRAM
390. { //参数一是CGRAM的4组用户空间组号码(0~3) ,参数二是用户自定义图表或汉字的编码
391. u8 i,addr=0;
392. if(bShowPicFlag)
393. {
394. LCD12864_writeCmd(0x36); //开启绘图显示,可流畅播放动画
395. }
396. else
397. {
398. LCD12864_writeCmd(0x34); //默认关闭绘图显示
399. }
400. LCD12864_writeCmd(0x02); //SR等于0,允许设置卷动地址
401. LCD12864_writeCmd(0x30); //恢复为8位并行,基本指令集
402. addr=(CGRAM_groupNum<<4)|0x40; //将CGRAM空间号转换为相应存储地址
403. LCD12864_writeCmd(addr); //定位到该位址(用户空间位址范围0x40-0x7F共128字节)
404. for(i=0;i<16;i++) //将用户自定义编码写入该16*16位元组空间
405. {
406. LCD12864_writeByte(pUserCode[i*2]); //连续写2个字节共16位
407. LCD12864_writeByte(pUserCode[i*2+1]);
408. }
409. }
410.
411. void LCD12864_showScrollCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum)//滚动CGRAM
412. { //row(0-3), cols(0-15)
413. //第三个参数是用户空间号码(0~3共4组空间号码),该号码乘2就是它所对应的[调用用户空间编码]
414. LCD12864_setScrollPos(row,cols);
415. LCD12864_writeByte(0x00);//4组用户空间的编码的高字节都固定为0,我猜这是为和E文ASCII码区分开
416. LCD12864_writeByte(CGRAM_groupNum*2); //对应编码00h,02h,04h,06h
417. LCD12864_showCGRAM(row,cols,CGRAM_groupNum);
418. }
419.
420. void LCD12864_showCGRAM(u8 row,u8 cols,u8 CGRAM_groupNum)//定位液晶光标,并显示自定义内容
421. {//row(0-3), cols(0-15)
422. //第三个参数是用户空间号码(0~3共4组空间号码),该号码乘2就是它所对应的[调用用户空间编码]
423. LCD12864_setPos(row,cols);
424. LCD12864_writeByte(0x00);//4组用户空间的编码的高字节都固定为0,我猜这是为和E文ASCII码区分开
425. LCD12864_writeByte(CGRAM_groupNum*2); //对应编码00h,02h,04h,06h
426. }
427. /*--------------------------------CGRAM end----------------------------------------------*/
428.
429. /*--------------------------------DDRAM start----------------------------------------------*/
430. void LCD12864_earseSomeDDRam(u8 row,u8 cols,u8 dataSize) //擦除N个字节DDRam
431. {//row(0-3),cols(0-15),如果起始地址是汉字的低字节,则会一同擦除汉字的高字节
432. LCD12864_setPos(row, cols); //定位
433. if(cols%2!=0) //如果从奇数列开始
434. {
435. LCD12864_readByte();//空读一次,让位址指针移动半字
436. if(LCD12864_readByte()>127) //检测高位是否是汉字码
437. {
438. LCD12864_setPos(row, cols); //是汉字码的话要擦除,不然要乱码
439. LCD12864_writeByte(' '); //其实是写空格,看不到了就等于擦除了
440. } //连续写2个0的话是乱码
441. }
442. while(dataSize--) //擦除
443. {
444. if(cols) //cols>0
445. {
446. if(0==cols%16) //如果一行满了
447. {
448. row++; //准备将光标移到下一行
449. cols=0; //列坐标置于行首
450. LCD12864_setPos(row, cols); //设置新光标
451. }
452. }
453. LCD12864_writeByte(' '); //其实是写空格,但为啥不写0呢
454. cols++; //因为0与是CGRAM重码了,写2个0会乱码的
455. }
456.
457. }
458.
459.
460. /*****************************************************************************************
461. pBuf如果用来修饰字符串,dataSize=strlen(pBuf);
462. pBuf如果是一个字符数组,dataSize=sizeof(pBuf);
463. strlen()虽然也可以用来计算字符数组长度,但遇到'\0'时就会返回,不会再计算后面的其他字符
464. 在VC中strlen()只能计算字符串长度,不能计算字符数组,否则编译出错
465. sizeof("你好5"),sizeof("你好56"),最终液晶光标位置是一样的,故不要用sizeof计算字符串
466. *****************************************************************************************/
467. void LCD12864_writeData(u8 row,u8 cols,u8* pBuf,u8 dataSize)//写数据
468. { //支持全角半角字符及中英混合的字符串,也可写入字符串的子串,(行坐标0~3,列坐标0~15)
469. u8 flag=0; //液晶低字节ram数据检测标志,0不检测
470. LCD12864_setPos(row, cols); //设置光标
471. if(cols%2!=0) //列号不为偶数(汉字在液晶上要偶对齐)
472. { //要让位址空移一个字节,执行下面这句读操作后,效果是达到了
473. LCD12864_readByte();//但AC值没变,我怀疑除了这个AC字型指针,另有一个标志位没公开)
474. flag=1; //此时需要检测液晶低位字节ram
475. } //因为高位字节现在可能是汉字码
476.
477. while(dataSize--) //循环处理目标字节流
478. {
479. if(0==cols%2) //偶对齐时,对于ram高字节
480. {
481. if(*pBuf>127) //如果写入ram的高字节是汉字码
482. {
483. flag=0; //下一次不要检测低字节,因为肯定是汉字了
484. }
485. else //如果高字节是半角字符
486. {
487. flag=1; //若在低字节ram写入汉字就乱码了,故检测
488. }
489. }
490.
491. if(cols%2!=0) //对于液晶低字节
492. {
493. if(flag) //如果要检测低字节
494. {
495. if(*pBuf>127) //如果低字节是汉字码
496. {
497. LCD12864_writeByte(0x20); //插入一个空格
498. cols++; //字节计数器++
499. flag=0; //清检测标志
500. }
501. }
502. }
503.
504. if(cols) //行尾检测
505. {
506. if(0==cols%16) //如果一行满了
507. {
508. row++; //准备将光标移到下一行
509. cols=0; //列坐标置于行首
510. LCD12864_setPos(row, cols); //设置新位址
511. }
512. }
513.
514. LCD12864_writeByte(*pBuf++); //终于可以写数据了
515. cols++; //列号累加
516. }
517. }
518.
519.
520. //滚屏模式的写数据函数
521. void LCD12864_writeScrollData(u8 row,u8 cols,u8* pBuf,u8 dataSize)//写数据,卷动模式
522. { //支持全角半角字符及中英混合的字符串,也可写入字符串的子串,(行坐标0~3,列坐标0~15)
523. u8 flag=0; //液晶低字节ram数据检测标志,0不检测
524. LCD12864_writeData(row,cols,pBuf,dataSize);
525. LCD12864_setScrollPos(row, cols); //设置光标
526. if(cols%2!=0) //列号不为偶数(汉字在液晶上要偶对齐)
527. { //要让位址空移一个字节,执行下面这句读操作后,效果是达到了
528. LCD12864_readByte();//但AC值没变,我怀疑除了这个AC字型指针,另有一个标志位没公开)
529. flag=1; //此时需要检测液晶低位字节ram
530. } //因为高位字节现在可能是汉字码
531.
532. while(dataSize--) //循环处理目标字节流
533. {
534. if(0==cols%2) //偶对齐时,对于ram高字节
535. {
536. if(*pBuf>127) //如果写入ram的高字节是汉字码
537. {
538. flag=0; //下一次不要检测低字节,因为肯定是汉字了
539. }
540. else //如果高字节是半角字符
541. {
542. flag=1; //若在低字节ram写入汉字就乱码了,故检测
543. }
544. }
545.
546. if(cols%2!=0) //对于液晶低字节
547. {
548. if(flag) //如果要检测低字节
549. {
550. if(*pBuf>127) //如果低字节是汉字码
551. {
552. LCD12864_writeByte(0x20); //插入一个空格
553. cols++; //字节计数器++
554. flag=0; //清检测标志
555. }
556. }
557. }
558.
559. if(cols) //行尾检测
560. {
561. if(0==cols%16) //如果一行满了
562. {
563. row++; //准备将光标移到下一行
564. cols=0; //列坐标置于行首
565. LCD12864_setScrollPos(row, cols); //设置新位址
566. }
567. }
568.
569. LCD12864_writeByte(*pBuf++); //终于可以写数据了
570. cols++; //列号累加
571. }
572. }
573.
574. void LCD12864_startScroll(u8 scrollNum,u16 delay_ms) //滚动
575. { //scrollNum建议值为64
576. u8 i;
577. LCD12864_writeCmd(0x34);
578. LCD12864_writeCmd(0x03);
579. for(i=0x40;i<0x40+scrollNum;i++)
580. {
581. LCD12864_writeCmd(i); //设置卷动地址
582. delayms(delay_ms); //实际使用时建议用定时器处理
583. }
584. LCD12864_writeCmd(0x40); //补滚一行
585. LCD12864_writeCmd(0x30);
586. }
587.
588. void LCD12864_setScrollPos(u8 row, u8 cols) //设置光标位置 ,卷动模式
589. { //row行坐标0~3
590. u8 newPos=0; //cols列坐标0~15
591. switch(row)
592. {
593. case 0:
594. {
595. row=0xa8;
596. }
597. break;
598. case 1:
599. {
600. row=0xb8;
601. }
602. break;
603. case 2:
604. {
605. row=0xa0;
606. }
607. break;
608. case 3:
609. {
610. row=0xb0;
611. }
612. break;
613. default: //如果需要检测行坐标范围,可在这里加代码
614. break;
615. }
616. newPos=row+cols/2; //液晶写指令坐标只能8级,我的函数中列坐标是16级的,支持半角全角混合
617. LCD12864_writeCmd(newPos);
618. }
619.
620.
621. void LCD12864_setPos(u8 row, u8 cols) //设置光标位置
622. { //row行坐标0~3
623. u8 newPos=0; //cols列坐标0~15
624. switch(row)
625. {
626. case 0:
627. {
628. row=0x80;
629. }
630. break;
631. case 1:
632. {
633. row=0x90;
634. }
635. break;
636. case 2:
637. {
638. row=0x88;
639. }
640. break;
641. case 3:
642. {
643. row=0x98;
644. }
645. break;
646. case 4:
647. {
648. row=0xa0;
649. }
650. break;
651. case 5:
652. {
653. row=0xb0;
654. }
655. break;
656. case 6:
657. {
658. row=0xa8;
659. }
660. break;
661. case 7:
662. {
663. row=0xb8;
664. }
665. break;
666.
667. default: //如果需要检测行坐标范围,可在这里加代码
668. break;
669. }
670. newPos=row+cols/2; //液晶写指令坐标只能8级,我的函数中列坐标是16级的,支持半角全角混合
671. LCD12864_writeCmd(newPos);
672. }
673. /*
674. void LCD12864_setPos(u8 row, u8 cols) //设置光标位置
675. { //row行坐标0~3
676. u8 newPos=0; //cols列坐标0~15
677. switch(row)
678. {
679. case 0:
680. {
681. row=0x80;
682. }
683. break;
684. case 1:
685. {
686. row=0x90;
687. }
688. break;
689. case 2:
690. {
691. row=0x88;
692. }
693. break;
694. case 3:
695. {
696. row=0x98;
697. }
698. break;
699. default: //如果需要检测行坐标范围,可在这里加代码
700. break;
701. }
702. newPos=row+cols/2; //液晶写指令坐标只能8级,我的函数中列坐标是16级的,支持半角全角混合
703. LCD12864_writeCmd(newPos);
704. }
705. */
706.
707.
708.
709. void LCD12864_init() //初始化
710. {
711. delayms(40); //rst由低到高后保持40ms以上,我们的rst接VCC
712. LCD_PSB= 1; //选择并口方式
713.
714. LCD12864_writeCmd( B(110000) ); //0x30,启用基本指令集
715. delayXus(15); //要求延时100us以上,(8+6x)*1.085=106us
716.
717. LCD12864_writeCmd( B(110000) ); //0x30,要求写2次该指令
718. delayXus(5); //要求延时37us以上,(8+6x)*1.085=41us
719.
720. LCD12864_writeCmd( B(1100) ); //0x0f,整体显示,游标,游标反白
721. delayXus(15); //要求延时100us以上
722.
723. LCD12864_writeCmd( B(0001) ); //0x01,清屏指令,整屏幕写满空格
724. delayms(10); //要求延时10ms以上
725.
726. LCD12864_writeCmd( B(110) ); //0x06,进入模式设置,游标自动指向下一位置,
727.
728. delayms(5); //手册上没说这里要延时,额,还是加上吧
729. }
730.
731.
732. void LCD12864_writeCmd(u8 cmd) //写指令
733. {
734. while(LCD12864_isBusy());
735. LCD_EN=0; //使能 拉低
736. LCD_RW=0; //写
737. LCD_RS=0;_nop_(); //命令
738.
739. LCD_EN=1; //使能
740. LCD_dataBus=cmd; //送指令
741. _nop_();_nop_(); //稳定
742.
743. LCD_EN=0;_nop_(); //取走
744. }
745.
746. void LCD12864_writeByte(u8 dat) //写一个字节
747. {
748. while(LCD12864_isBusy());
749. LCD_EN=0; //使能先拉低
750. LCD_RW=0; //写
751. LCD_RS=1;_nop_(); //数据
752.
753. LCD_EN=1;
754. LCD_dataBus=dat;
755. _nop_();_nop_(); //延时大于1.5us
756.
757. LCD_EN=0;_nop_(); //下降沿取走数据
758. }
759.
760. u8 LCD12864_readByte() //读数据暂存器Data Register
761. { //用的时候要空操作一次
762. u8 temp=0;
763. while(LCD12864_isBusy());//忙检测
764. LCD_dataBus=0xff; //用总线读数据时必须先置为输入模式
765. LCD_EN=0; //使能线拉低
766. LCD_RW=1; //读
767. LCD_RS=1;_nop_(); //数据
768. LCD_EN=1;_nop_(); //使能
769. temp=LCD_dataBus; //取走数据
770.
771. _nop_();
772. LCD_EN=0; //使能恢复
773. return temp;
774. }
775.
776. bool LCD12864_isBusy() //检测液晶是否忙
777. {
778. if(LCD12864_readIR() & 0x80) //检测BF位
779. {
780. return TRUE; //忙
781. }
782. return FALSE; //不忙
783. }
784.
785. u8 LCD12864_readIR() //读指令暂存器Instruction Register
786. {
787. u8 temp=0;
788. LCD_EN=0; //使能准备
789. LCD_RW=1; //读
790. LCD_RS=0;_nop_(); //命令字
791. LCD_dataBus=0xff; //准备输入
792. LCD_EN=1;_nop_(); //使能
793. temp=LCD_dataBus; //提取数据
794.
795. _nop_();
796. LCD_EN=0; //使能拉低
797. return temp;
798. }
公司名称: 深圳驰宇微科技有限公司
公司地址:深圳市宝安区龙华新区大浪街道华宁路伟华达工业区C栋七楼
公司电话:0755-29446830 13714036597
驰宇微首页 | 图形点阵液晶模块 | 中文字库液晶模块 | 字符型液晶模块 | 段码液晶模块 | 产品列表 | 站点地图 | 关于驰宇微
公司名称: 深圳驰宇微科技有限公司
备案号:粤ICP备14047421号
公司地址:深圳市龙华区大浪街道华昌路241号鸿源工业区E栋5层
公司电话:0755-29446830 13640934827
邮 箱:18926046819@163.com Q Q:577895076
版权归深圳驰宇微科技所有