📄 12-4.lst
字号:
244
245 void send_sd(uchar c)
246 {
247 1 clr_E1();
248 1 set_E2();
249 1 wait_ready();
250 1 set_A0(); //数据
251 1 clr_WR(); //写触发
252 1 lcd_data = c;
253 1 NOP();
254 1 clr_E2();
255 1 }
256
257 //等待ready:等待LCD内部操作完成
258
259 void wait_ready(void)
260 {
261 1 // DDRA = 0x00; //PA口输入
262 1 clr_A0(); //指令
263 1 set_WR(); //读
264 1 NOP();
265 1 while(lcd_data & status_busy); //读入LCD状态,1=忙,一直等待LCD内部操作完成
266 1 // DDRA = 0xff; //重新置PA口输出
267 1 }
268
269 //122x32LCD初始化,开机后仅调用一次
270 void lcd_init(void)
271 {
272 1 send_mi(reset); //复位m-left,s-right
273 1 send_si(reset);
274 1
275 1 send_mi(disp_off); //关闭显示
276 1 send_si(disp_off);
277 1
278 1 send_mi(dynamic_driver); //动态驱动
279 1 send_si(dynamic_driver);
280 1
281 1 send_mi(clk32); //1/32占空比
282 1 send_si(clk32);
283 1
284 1 send_mi(adc_select); //clockwise
285 1 send_si(adc_select);
286 1
287 1 send_mi(mode_write); //写模式
288 1 send_si(mode_write);
289 1
290 1 send_mi(col_addr_set);
291 1 send_mi(disp_start_line); //归回零列,设定显示起始行首
292 1 send_si(col_addr_set);
293 1 send_si(disp_start_line);
294 1
295 1 send_mi(disp_on); //开显示
296 1 send_si(disp_on);
297 1 }
298
299 //清屏
300 void lcd_clr(void)
301 {
302 1 uchar i, page;
303 1 for (page=0;page<4;page++)
C51 COMPILER V7.09 12_4 08/11/2005 18:46:34 PAGE 6
304 1 {
305 2 send_mi(page_addr_set|page);
306 2 send_si(page_addr_set|page);
307 2 send_mi(0); //主窗口设置为0列
308 2 send_si(0); //从窗口设置为0列
309 2 for (i=0;i<62;i++)
310 2 {
311 3 send_md(0x00);
312 3 send_sd(0x00);
313 3 }
314 2 }
315 1 }
316
317 //同时设置主(右)从(左)显示页为0~3页
318 void set_page(uchar page)
319 {
320 1 send_mi(page_addr_set|page);
321 1 send_si(page_addr_set|page);
322 1 }
323
324 //同时设置主(右)从(左)列地址为0~61列
325 void set_address(uchar address)
326 {
327 1 send_mi(address&0x7F); //&0x7F,考虑到防止越限
328 1 send_si(address&0x7F);
329 1 }
330
331 //在右页(从窗口)当前地址画一个字节(8点)
332
333 void putchar_l(uchar c)
334 {
335 1 send_md(c);
336 1 }
337
338 //在左页(主窗口)当前地址画一个字节(8点)
339
340 void putchar_r(uchar c)
341 {
342 1 send_sd(c);
343 1 }
344
345 //画一个图,横坐标是col,layer表示上下层,width是图形的宽,高固定16
346 // bmp是图形指针
347 // 使用zimo21软件,采用纵向取模下高位得到bmp数据。
348 // col 图型的起始位置0~121
349 // layer 图形的位置(Y坐标)0-下半部分 非0-上半部分
350 // width 图形宽度8,16可选
351 // bmp 图形数据指针
352
353 void draw_bmp(uchar col,uchar layer,uchar width,uchar *bmp)
354 {
355 1 uchar x;
356 1 uchar address; //address表示显存的物理地址
357 1 uchar p=0;
358 1 uchar page=0;
359 1 uchar window=0; //page表示上下两页,window表示左右窗口(0
360 1 //左,1右)
361 1 if (layer) page=2; //左-主窗口,右-从窗口
362 1
363 1 for (x=col; x<col+width; x++)
364 1 {
365 2 if (x>121)return; //防止显示乱码
C51 COMPILER V7.09 12_4 08/11/2005 18:46:34 PAGE 7
366 2 if (x>60) //左右窗口定位
367 2 {
368 3 window=1; //右-从窗口
369 3 address=x%61;
370 3 }
371 2 else
372 2 address=x; //主窗口输出
373 2
374 2 set_page(page); //上层数据输出
375 2 set_address(address);
376 2
377 2 if (window)
378 2 putchar_r(bmp[p]);
379 2 else
380 2 putchar_l(bmp[p]);
381 2
382 2 set_page(page+1); //下层数据输出
383 2 set_address(address); //列保持不变
384 2
385 2 if (window)
386 2 putchar_r(bmp[p+width]);
387 2 else
388 2 putchar_l(bmp[p+width]);
389 2
390 2 p++;
391 2 }
392 1 }
393
394 //显示单个ASCII码col-列;layer-上下行:1-上,0-下;ascii_code:所要显示德ASCCII码
395
396 void disp_one_ascii(uchar col,uchar layer,uchar ascii_code,uchar mode)
397 {
398 1 uchar i;
399 1 for(i=0;i<16;i++) //ASCII码显示占用16个字节
400 1 {
401 2 if(mode)dot_buffer[i]=~ascii[(ascii_code-0x20)*16 + i];
402 2 else dot_buffer[i]= ascii[(ascii_code-0x20)*16 + i];
403 2 }
404 1 draw_bmp(col,layer,8,dot_buffer);
405 1 }
406
407 //显示小于4个的十进制数字
408 //修改缓冲区的大小可以扩展显示
409
410 void disp_ram_data(uchar col,uchar layer,uchar n,uchar mode)
411 {
412 1 while(n--)
413 1 {
414 2 if(mode)disp_one_ascii(col,layer,disp_buffer[n]+0x30,1);
415 2 else disp_one_ascii(col,layer,disp_buffer[n]+0x30,0);
416 2 col += 8;
417 2 }
418 1 }
419
420 //ASCII(8*16) 和 汉字(16*16)显示函数
421
422 void dprintf(uchar col,uchar layer,uchar *ptr,uchar mode)
423 {
424 1 uchar c1,c2;
425 1 uchar i,j,k;
426 1 uchar ulen;
427 1 //uchar ucol,ulayer,umode;
C51 COMPILER V7.09 12_4 08/11/2005 18:46:34 PAGE 8
428 1 uchar ucol,ulayer;
429 1 ulen = 0;
430 1 ucol = col;
431 1 ulayer = layer;
432 1
433 1 while (ptr[ulen]!= 0)ulen++; //探测字串长度
434 1 i=0;
435 1 while(i<ulen)
436 1 {
437 2 c1 = ptr[i];
438 2 c2 = ptr[i+1];
439 2 //ASCII字符与汉字内码的区别在于128做
440 2 //分界;大于128的为汉字码
441 2 if(c1 <=128) //ASCII
442 2 {
443 3 if(mode)disp_one_ascii(ucol,ulayer,c1,1);
444 3 else disp_one_ascii(ucol,ulayer,c1,0);
445 3 ucol+=8;
446 3 i++; //ASCII码的处理
447 3 }
448 2 else //中文
449 2 {
450 3 for(j=0;j<sizeof(hz16)/sizeof(hz16[0]);j++)
451 3 { //查找定位当前汉字的点阵区
452 4 if((c1 == hz16[j].index[0]) && (c2 == hz16[j].index[1]))
453 4 break;
454 4 }
455 3 for(k=0;k<32;k++)
456 3 { if(mode)dot_buffer[k]=~hz16[j].zimo[k];
457 4 else dot_buffer[k]= hz16[j].zimo[k];
458 4 }
459 3 draw_bmp(ucol,ulayer,16,dot_buffer);
460 3 ucol+=16;
461 3 i+=2; //中文的处理
462 3 }
463 2 }
464 1 }
465
466 void main(void)
467 {
468 1 uchar i;
469 1 uint j;
470 1 // DDRC=0xF0; //C口高四位为输出控制端口
471 1 // DDRA=0xFF; //A口为数据线(一般为输出,仅在读LCD状//态时为输入)
472 1 for(i=0;i<10;i++)for(j=1;j;j++); //开机延时
473 1 lcd_init();
474 1 lcd_clr();
475 1 dprintf(10,1,"I AM CHINESE!",0); //说明/在up 行从第10列开始显示/正常
476 1 //显示
477 1 disp_ram_data(10,0,2,1); //说明/在dowm行从第10列开始显示/反白//显示
478 1 while(1);
479 1 }
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 946 ----
CONSTANT SIZE = 1042 ----
XDATA SIZE = ---- ----
PDATA SIZE = ---- ----
DATA SIZE = 36 39
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
C51 COMPILER V7.09 12_4 08/11/2005 18:46:34 PAGE 9
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -