找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10663|回复: 15
打印 上一主题 下一主题
收起左侧

在LCD12864上显示正弦曲线—按键可调频率和幅度以及显示文字,动态图片仿真

  [复制链接]
跳转到指定楼层
楼主
51单片机控制的12864显示,有文字,图片,动态图片,以及PROTUES仿真等非常全面

以上压缩包所有内容下载: LCD12864.zip (13.61 MB, 下载次数: 235)

部分程序预览:
  1. /***
  2. 程序:LCD12864显示图形
  3. 内容:在12864上显示正弦曲线——按键可调频率和幅度
  4. 学习板:HOT-51
  5. 软件:keil uVision3
  6. 液晶:QY12864HZ1
  7. 作者:大海橡树
  8. 整理日期:2010-12-08
  9. 修改:无


  10. 备注:有什么错误的地方,欢迎网友们到空间留言

  11.                                         O(∩_∩)O~


  12. *****/
  13. #include<AT89X52.h>
  14. #include<math.h>
  15. #include"ZB.h"
  16. #define uchar unsigned char
  17. #define uint  unsigned int

  18. #define LCD_databus P0 //LCD数据总线连接P0口

  19. sbit RS=P2^5;
  20. sbit RW=P2^6;
  21. sbit EN=P2^7;//LCD12864三个控制位

  22. sbit DQ=P2^3;//DS18B20数据线
  23. sbit KEY1=P3^2;
  24. sbit KEY2=P3^3;
  25. sbit KEY3=P3^4;
  26. uchar key_value;

  27. uchar HZ1[]="周期";
  28. uchar HZ2[]="幅度";
  29. void delay(uint i)        //延时函数
  30. {
  31.         while(--i);
  32. }
  33. void Read_busy()        //LCD12864忙检测
  34. {
  35.         RS=0;
  36.         RW=1;
  37.         EN=1;
  38.         LCD_databus=0xFF;
  39.         while(LCD_databus & 0x80);        //判断最高位,1---busy,0---Nobusy
  40.         EN=0;
  41. }

  42. void write_LCD_command(uchar value)//写指令
  43. {
  44.         RS=0;
  45.         RW=0;
  46.         EN=1;
  47.         LCD_databus=value;
  48.         delay(7);
  49.         EN=0;
  50. }

  51. void write_LCD_data(uchar value)//写数据
  52. {
  53.         RS=1;
  54.         RW=0;
  55.         EN=1;
  56.         LCD_databus=value;
  57.         delay(7);
  58.         EN=0;
  59. }

  60. void init_LCD()                //初始化LCD
  61. {
  62.         write_LCD_command(0x30);        //8位数,基本指令
  63.         delay(100);
  64.         write_LCD_command(0x30);
  65.         delay(37);
  66.         write_LCD_command(0x0C);        //开显示,不显示光标,光标不闪烁
  67.         delay(100);
  68.         write_LCD_command(0x01);        //清屏指令
  69.         delay(100);
  70.         write_LCD_command(0x06);        //没写入数据,地址指针加1
  71. }

  72. void Clear_GDRAM()                //清楚GDRAM
  73. {
  74.         uchar x,y;
  75.         for(y=0;y<64;y++)
  76.         {
  77.                 for(x=0;x<16;x++)
  78.                 {
  79.                         write_LCD_command(0x34);
  80.                         write_LCD_command(y+0x80);        //先送垂直地址
  81.                         write_LCD_command(x+0x80);        //后送水平地址
  82.                         write_LCD_command(0x30);        //基本指令
  83.                         write_LCD_data(0x00);                //写入数据0
  84.                         write_LCD_data(0x00);
  85.                 }
  86.         }
  87. }

  88. uchar ReadByte()        //读LCD
  89. {
  90.         uchar Read_value;
  91.         Read_busy();
  92.         RS=1;
  93.         RW=1;
  94.         EN=0;
  95.         EN=1;
  96.         Read_value=LCD_databus;       
  97.         EN=0;
  98.        
  99.         return Read_value;
  100. }

  101. void display_BMP(uchar *address)//显示图片
  102. {
  103.         uchar i,j;
  104.         for(i=16;i<32;i++)
  105.         {
  106.                 write_LCD_command(0x80+i);        //先送垂直地址
  107.                 write_LCD_command(0x80);        //再送水平地址
  108.                 for(j=0;j<16;j++)
  109.                 {
  110.                         write_LCD_data(*address);//写入数据
  111.                         address++;
  112.                 }
  113.         }
  114.        
  115.         for(i=0;i<32;i++)
  116.         {
  117.                 write_LCD_command(0x80+i);//先送垂直地址
  118.                 write_LCD_command(0x88);        //再送水平地址
  119.                 for(j=0;j<16;j++)
  120.                 {
  121.                         write_LCD_data(*address);
  122.                         address++;
  123.                 }
  124.         }
  125.        
  126. }

  127. void Draw_dots(uchar x,uchar y,uchar color)
  128. {
  129.         uchar ROW,xlabel,xlabel_bit;
  130.         uchar Read_H,Read_L;                 //读LCD中的数据
  131.         write_LCD_command(0x34);        //扩充指令
  132.         write_LCD_command(0x36);        //打开绘图指令
  133.         xlabel=x>>4;                                //取16*16首地址
  134.         xlabel_bit=x & 0x0F;                //计算该点在16位数据的第几位       
  135.         if(y<32)                                        //如果是上半屏,上下半屏y都是0--31
  136.         {
  137.                 ROW=y;
  138.         }
  139.         else                                                //显示的是下半屏
  140.         {
  141.                 ROW=y-32;
  142.                 xlabel+=8;                           //规定显示在下半屏
  143.         }
  144.         write_LCD_command(ROW+0x80); //送入垂直地址
  145.         write_LCD_command(xlabel+0x80);//再送入水平地址
  146.         ReadByte();        //读取当前GDRAM数据前腰进行一次空读,接下来就可以读出数据了
  147.         Read_H=ReadByte(); //读高8位
  148.         Read_L=ReadByte(); //读低8位
  149.        
  150.         write_LCD_command(ROW+0x80);         //送入垂直地址
  151.         write_LCD_command(xlabel+0x80);        //再送入水平地址
  152.        
  153.         if(xlabel_bit<8)
  154.         {
  155.                 switch(color)
  156.                 {
  157.                         case 0:Read_H &= (~(0x01<<(7-xlabel_bit)));//若变白
  158.                         break;
  159.                         case 1:Read_H |= (0x01<<(7-xlabel_bit));//若涂黑
  160.                         break;
  161.                         case 2:Read_H ^= (0x01<<(7-xlabel_bit));//若反转
  162.                         break;       
  163.                         default:break;
  164.                 }
  165.                 write_LCD_data(Read_H);//将数据写入GDRAM
  166.                 write_LCD_data(Read_L);//先写高位,再写低位(地址指针顺序)
  167.         }
  168.         else
  169.         {
  170.                 switch(color)//color设置
  171.                 {
  172.                         case 0: Read_L &= (~(0x01<<(15-xlabel_bit)));//若变白
  173.                         break;
  174.                         case 1: Read_L |= (0x01<<(15-xlabel_bit));//若涂黑
  175.                         break;
  176.                         case 2: Read_L ^= (0x01<<(15-xlabel_bit));//若反转
  177.                         break;
  178.                         default:break;
  179.                 }
  180.                 write_LCD_data(Read_H);
  181.                 write_LCD_data(Read_L);//写入数据
  182.         }
  183.        
  184.         write_LCD_command(0x30);//回到普通模式
  185. }

  186. void main()
  187. {
  188.         uchar i,j;
  189.         uchar num;
  190.         uchar w=10,A=6;
  191.         init_LCD();
  192.         Clear_GDRAM();
  193.         write_LCD_command(0x36);
  194.         display_BMP(ZB);
  195.         while(1)
  196.         {
  197.                 write_LCD_command(0x30);
  198.                 write_LCD_command(0x80);
  199.                 write_LCD_data('T');
  200.                 write_LCD_data(':');
  201.                 write_LCD_data(2*w/100+0x30);
  202.                 write_LCD_data(2*w%100/10+0x30);
  203.                 write_LCD_data(2*w%10+0x30);

  204.                 write_LCD_command(0x83);
  205.                 write_LCD_data('A');
  206.                 write_LCD_data(':');
  207.                 write_LCD_data(A/10+0x30);
  208.                 write_LCD_data(A%10+0x30);
  209.                 write_LCD_command(0x36);
  210.                 for(i=13;i<128;i++)
  211.                 {
  212.                         j=35-A*sin((i-13)*3.14/w);
  213.                         Draw_dots(i,j,1);
  214.                         delay(400);
  215.                 }
  216. /**********以下为按键扫描函数**************/
  217.                 if(KEY1==0)                        //模式键按下
  218.                 {
  219.                         delay(2000);
  220.                         if(KEY1==0)
  221.                         {
  222.                                 while(!KEY1);
  223.                                 key_value++;
  224.                                 if(key_value>2)
  225.                                         key_value=0;
  226.                         }
  227.                 }
  228.                 if(key_value==1)                         //若选择的是周期模式
  229.                 {
  230.                         write_LCD_command(0x30);
  231.                         write_LCD_command(0x86);
  232.                         for(num=0;num<4;num++)
  233.                         {
  234.                                 write_LCD_data(HZ1[num]);         //显示"周期"汉字
  235.                         }
  236.                         if(KEY2==0)                                                //加键按下时
  237.                         {
  238.                                 delay(1500);
  239.                                 if(KEY2==0)
  240.                                 {
  241.                                         while(!KEY2);
  242.                                         w=w+5;                                        //w加
  243.                                         if(w==65)
  244.                                                 w=10;
  245.                                         Clear_GDRAM();
  246.                                         write_LCD_command(0x36);//重新显示图形
  247.                                         display_BMP(ZB);       
  248.                                 }          
  249.                         }
  250.                         if(KEY3==0)
  251.                         {
  252.                                 delay(2000);
  253.                                 if(KEY3==0)
  254.                                 {
  255.                                         while(!KEY3);
  256.                                         if(w>=10)
  257.                                                 w=w-5;
  258.                                         Clear_GDRAM();
  259.                                         write_LCD_command(0x36);
  260.                                         display_BMP(ZB);                //重新显示图形
  261.                                 }
  262.                         }       
  263.                 }

  264.                 if(key_value==2)                                //若选择的是幅度模式
  265.                 {
  266.                         write_LCD_command(0x30);
  267.                         write_LCD_command(0x86);
  268.                         for(num=0;num<4;num++)
  269.                         {
  270.                                 write_LCD_data(HZ2[num]);  
  271.                         }
  272.                         if(KEY2==0)
  273.                         {
  274.                                 delay(1500);
  275.                                 if(KEY2==0)
  276.                                 {
  277.                                         while(!KEY2);
  278.                                         A=A+2;
  279.                                         if(A==22)
  280.                                                 A=8;
  281.                                         Clear_GDRAM();
  282.                                         write_LCD_command(0x36);
  283.                                         display_BMP(ZB);       
  284.                                 }          
  285.                         }
  286.                         if(KEY3==0)
  287.                         {
  288.                                 delay(2000);
  289.                                 if(KEY3==0)
  290.                                 {
  291.                                         while(!KEY3);
  292.                                         if(A>=6)
  293.                                                 A=A-2;
  294.                                         Clear_GDRAM();
  295.                                         write_LCD_command(0x36);
  296.                                         display_BMP(ZB);
  297.                                 }
  298.                         }       
  299.                 }
  300.         }       
  301. }
复制代码



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:96682 发表于 2016-4-10 21:52 | 只看该作者
非示波器,是网友练练手的一个好题材。
回复

使用道具 举报

板凳
ID:221708 发表于 2017-7-24 10:28 | 只看该作者
波形出来了,很适合学习
回复

使用道具 举报

地板
ID:251848 发表于 2017-11-21 13:00 | 只看该作者

波形出来了,很适合学习
回复

使用道具 举报

5#
ID:251848 发表于 2017-11-21 13:01 | 只看该作者
学习学习 谢谢楼主!!!
回复

使用道具 举报

6#
ID:256814 发表于 2017-12-3 15:33 | 只看该作者
波形显示每一个点都控制吗
回复

使用道具 举报

7#
ID:265974 发表于 2017-12-24 11:52 | 只看该作者
哇感谢楼主,作业刚好要用到
回复

使用道具 举报

8#
ID:326407 发表于 2018-5-18 15:55 | 只看该作者
QAQ压缩包下到一半就停了这是怎么回事啊
回复

使用道具 举报

9#
ID:326407 发表于 2018-5-18 16:17 | 只看该作者
换了个网下下来了_(:з」∠)_感谢楼主分享!很实用!
回复

使用道具 举报

10#
ID:290716 发表于 2018-5-18 19:37 | 只看该作者
51能用吗?
回复

使用道具 举报

11#
ID:356773 发表于 2018-11-9 10:03 | 只看该作者
波形出不来啊楼主,能教教我吗
回复

使用道具 举报

12#
ID:537018 发表于 2019-5-13 18:15 | 只看该作者
ZB。h文件是什么啊
回复

使用道具 举报

13#
ID:739573 发表于 2020-5-9 17:17 | 只看该作者
为什么我无字库显示无法仿真
回复

使用道具 举报

14#
ID:739573 发表于 2020-5-9 17:46 | 只看该作者
这个无字库显示的我烧的是楼主给得hex文件,但在proteus上却仿真不出来,相关引脚的电平和楼主的有出入,这是什么原因呢?
回复

使用道具 举报

15#
ID:650426 发表于 2020-5-10 00:41 | 只看该作者
可以keil uVision4的编译吗?我一直编译不行,是我哪里出错了吗
就是一直显示这样的:
Build target 'Target 1'
assembling STARTUP.A51...
compiling main.c...
main.c(7): warning C318: can't open file 'AT89C52.h'
MAIN.C(16): error C202: 'P2': undefined identifier
MAIN.C(17): error C202: 'P2': undefined identifier
........
........
回复

使用道具 举报

16#
ID:688460 发表于 2020-6-19 08:21 | 只看该作者
不错的思路,学习了!谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表