12864绘图时,图像周围有杂点,是不是绘图有特殊的设置?

2020-02-05 08:44发布

本帖最后由 paradisespace 于 2012-5-29 10:03 编辑

只显示字符很正常,添加绘图后就出现很多杂点。用的是st7820控制器的液晶显示。
20120528_002.jpg (662.73 KB, 下载次数: 0) 下载附件 2012-5-28 12:08 上传

程序是用模块写的 就直接上传文件了吧,贴出来太长了。
代码:
code.zip (129.77 KB, 下载次数: 34) 2012-5-29 10:02 上传 点击文件名下载附件


我把相关代码贴上来。大神帮我看看吧。什么时候需要清GDRAM,12864的绘图让人纠结。。。
  1. void main()
  2. {
  3.         
  4.         /********************DS1302初始值设置************************/
  5.         DS1302_Init();        
  6.         DS1302_Set_RTC();                                //设置时钟初值                                
  7.         /*************************定时器*****************************/
  8.         Init_Timer0();                                        //Timer0初始化                                
  9.         /***********************液晶初始化***************************/
  10.         Display_Init();
  11.         Display_Clear();        //清除屏幕                                                                                                               
  12.         
  13. //        interface_clock();

  14.         while(1)
  15.         {
  16.                 if(Read_RTC_Flag==1)                        //1S定时到
  17.                  {
  18.                         Read_RTC_Flag=0;                //清空1S定时到标志
  19.                  //        interface_two();                //使用界面2时需打开interface_clock
  20.                         interface_three();                                 
  21.                 }         
  22.         }               
  23. }


  24. void interface_clock()
  25. {

  26.         Display_Clear();
  27.                 /***********************绘制模拟时钟*************************/
  28.         Clean_12864_GDRAM();                                                        //填充GDRAM
  29.         GUI_Circle(96,32,31,1);                                                        //画圆
  30.         GUI_Point(96,32,1);                                                                //画圆心
  31.         //画刻度        
  32. //        GUI_RLine(96,1,4,1);                                                         //画垂直线

  33.         GUI_Line(112,5,110,8,1);
  34.         GUI_Line(123,17,120,18,1);
  35. //        GUI_HLine(123,127,32,1);                                                //画水平线        
  36.         GUI_Line(123,48,120,46,1);
  37.         GUI_Line(111,59,110,56,1);
  38. //        GUI_RLine(96,59,63,1);                                                         //画垂直线
  39.         GUI_Line(80,59,82,56,1);
  40.         GUI_Line(69,47,72,46,1);
  41. //        GUI_HLine(65,69,32,1);                                                        //画水平线        
  42.         GUI_Line(69,16,72,18,1);
  43.         GUI_Line(81,5,82,8,1);
  44.         //显示刻度3,6,9,12
  45.         GUI_Put_Area(94,3,(unsigned char *)NUM5x5_12,5,5,0);//显示12
  46.         GUI_Put_Area(95,55,(unsigned char *)NUM3x5_6,3,5,0);//显示6
  47.         GUI_Put_Area(68,30,(unsigned char *)NUM3x5_9,3,5,0);//显示9
  48.         GUI_Put_Area(122,30,(unsigned char *)NUM3x5_3,3,5,0);//显示3        
  49. }

  50. /*需要绘图显示的:时、分、秒--------------------------------------------------*/
  51. void displaytime(void)
  52. {
  53.         
  54. /*往液晶屏填写 小时 数据-----------------------------------------*/
  55. //        hour = read_clock(0x85);                                         //读取DS1302的 时
  56.         Write1632GDRAM(1,2,num1632[hour/10]);
  57.         Write1632GDRAM(2,2,num1632[hour%10]);
  58.         Write1632GDRAM(3,2,num1632[10]);        //时钟分隔符“:”

  59. /*往液晶屏填写 分钟 数据-----------------------------------------*/
  60. //        min = read_clock(0x83);                 //读取DS1302的 分                                
  61.         Write1632GDRAM(4,2,num1632[minute/10]);
  62.         Write1632GDRAM(5,2,num1632[minute%10]);
  63.         Write1632GDRAM(6,2,num1632[10]);        //时钟分隔符“:”

  64. /*往液晶屏填写 秒钟 数据-----------------------------------------*/
  65. //        sec= read_clock(0x81);                  //读取DS1302的 秒
  66.         Write1632GDRAM(7,2,num1632[second/10]);
  67.         Write1632GDRAM(8,2,num1632[second%10]);        
  68. }

  69. /**************************************************************************************
  70. //函数功能:显示16X32图形,适用于st7920型液晶
  71. //形式参数:uchar x,uchar y,uchar *bmp
  72. //行参说明:横坐标X列,纵坐标Y行,要显示的图形BMP
  73. //************************************************************************************/           
  74. void Write1632GDRAM(unsigned char x,unsigned char y,unsigned char *bmp)        
  75. {
  76.         unsigned char i,j,basex,basey;
  77.         switch(y)         //由y纵坐标定是上半屏还是下半屏
  78.         {
  79.           case 1: basex=0x80; break;  //上半屏
  80.           case 2: basex=0x80; break;  //先上半屏,下面再下半屏。
  81.           case 3: basex=0x88; break;  //下半屏
  82.           default:   return;   //别的则返回
  83.         }
  84.         basey=basex+x-1;
  85.         LcdWcom(0x36);  
  86.         if(y==1||y==3)        //如为第一第三行,则直接是在同一半屏,直接绘完32行点阵数据。
  87.         {
  88.                   for(i=0;i<32;i++)         //写入32行点阵
  89.                   {                                                                                                               
  90.                             LcdWcom(0x80+i);  //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80
  91.                             LcdWcom(basey);     //再写入水平位址(选上下半屏)
  92.                             for(j=0;j<2;j++)           //2个8位元的数据,即16BIT宽度
  93.                                     LcdWdata(*bmp++);   
  94.                   }         
  95.         }
  96.         if(y==2)  //从第二行开始则画图将上下半屏都有,所以先画完上半屏16行,再画下半屏16行。
  97.         {                                       
  98.                   for(i=0;i<16;i++)         //写入上半屏16行点阵
  99.                   {                                                                                                               
  100.                             LcdWcom(0x90+i);  //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80,第二行为0X90。
  101.                             LcdWcom(basey);    //(选上半屏)再写入水平位址
  102.                             for(j=0;j<2;j++)           //2个8位元的数据,即16BIT宽度
  103.                                     LcdWdata(*bmp++);   
  104.                   }
  105.                   for(i=0;i<16;i++)         //写入下半屏16行点阵
  106.                   {                                                                                                               
  107.                             LcdWcom(0x80+i);  //先写入垂直位址,选上下32行的哪一行,不管上下半屏,首行都为0X80
  108.                             LcdWcom(basey+8);   //(选下半屏)再写入水平位址
  109.                             for(j=0;j<2;j++)           //2个8位元的数据,即16BIT宽度
  110.                                     LcdWdata(*bmp++);   
  111.                   }         
  112.         }
  113.         LcdWcom(0x36);  //写完数据,开图片显示     
  114. }

  115. /**************************************************************************************
  116. //函数名称:Clean_12864_GDRAM(void)                                                
  117. //函数功能:清屏函数
  118. //使用说明:GDRAM填满0
  119. //************************************************************************************/
  120. void Clean_12864_GDRAM(void)
  121. {
  122.     unsigned char x,y;
  123.     LcdWcom(0x36);
  124.     init_12864_GDRAM();                //设置扩展指令集,按手册说明,仅设置了绘图位,
  125.      LcdWcom(0x36);        //需要两次,本次设置扩展指令集。
  126.     for (y=0;y<32;y++)
  127.     {
  128.          LcdWcom(0x80+y);  //设置y=1000+00xx,y+1则往下一行
  129.          LcdWcom(0x80);        //设置x=1000 0000
  130.         for (x=0;x<16;x++)
  131.         {
  132.              LcdWdata(0x00);   //高字节数据
  133.              LcdWdata(0x00);        //低字节数据
  134.         }
  135.     }
  136. }
复制代码
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
35条回答
paradisespace
1楼-- · 2020-02-08 05:47
joing2000 发表于 2012-5-29 09:44
void wr_lcd (uchar dat_comm,uchar content)
{
  chk_busy ();

我没加忙检测。昨天加了忙检测效果更乱,我今天再试试。若是你现在有时间的话,帮我把程序看看吧。辛苦了!
joing2000
2楼-- · 2020-02-08 11:03
paradisespace 发表于 2012-5-29 09:49
我没加忙检测。昨天加了忙检测效果更乱,我今天再试试。若是你现在有时间的话,帮我把程序看看吧。辛苦了 ...

我看了。关键不在你发的那部分程序上面呀。我发我的例程给你看看。


#include <reg52.h>

#define uint  unsigned int
#define uchar unsigned char
#define x     0x80
#define y     0x80
#define comm  0
#define dat   1

sbit rs = P3^0;   //H=data; L=command;
sbit rw = P3^1;   //H=read; L=write;
sbit  e = P3^2;   //input enable;
sbit psb= P3^3;   //H=并口; L=串口;
sbit rst= P3^4;   //Reset Signal 低电平有效

sbit busy=P1^7;   //lcd busy bit

void wr_lcd (uchar dat_comm,uchar content);
void chk_busy (void);
void delay (uint us);

uchar code tab1[]={
"锐显科技有限公司"
"NS:www.rxlcd.com"
};

uchar code tab5[]={
/*------------------------------------------------------------------------------
;  若数据乱码,请检查字模格式设置,注意选择正确的取模方向和字节位顺序。
;  源文件 / 文字 : C:Documents and SettingsAdministrator桌面新建文件夹图片16032(1).bmp字模
;  宽×高(像素): 128×32
;  字模格式/大小 : 单 {MOD}点阵液晶字模,横向取模,字节正序/512字节
;  数据转换日期  : 2011-4-25 9:28:51
------------------------------------------------------------------------------*/
0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x07,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x0F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x1F,0xF8,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x3E,0xFC,0x0C,0x00,0x70,0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x7C,0x7E,0x1E,0x00,0xF0,0xF2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0xF8,0x3F,0x3F,0x00,0x70,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0xF0,0x1F,0xFF,0x80,0x79,0xEF,0x0F,0x9E,0xF7,0x80,0x00,0x00,0x00,0x00,0x00,
0x03,0xE0,0x0F,0xFB,0xC0,0x79,0xEF,0x1F,0xDE,0xF7,0x80,0x00,0x00,0x00,0x00,0x00,
0x07,0xC0,0x07,0xF1,0xE0,0x39,0xC7,0x39,0xDE,0xF7,0x80,0x00,0x00,0x00,0x00,0x00,
0x0F,0x80,0x03,0xE0,0xF0,0x39,0xC7,0x3F,0xCF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,
0x1F,0x00,0x07,0xC0,0x78,0x19,0x87,0x3F,0xCF,0x9F,0x00,0x38,0x00,0x00,0x00,0x00,
0x3E,0x00,0x0F,0x80,0x3C,0x1F,0x87,0x38,0x0F,0x9F,0x3F,0x38,0x00,0x00,0x00,0x00,
0x7C,0x00,0x1F,0x00,0x1E,0x0F,0x07,0x3C,0xC7,0x9E,0x7F,0xB8,0x00,0x00,0x00,0x00,
0xFC,0x00,0x3E,0x00,0x0F,0x0F,0x07,0x1F,0xC7,0x9E,0x7B,0xB8,0x00,0x00,0x00,0x00,
0x7E,0x00,0x3E,0x00,0x0F,0x0F,0x07,0x1F,0x87,0x9E,0x70,0x3F,0x87,0xC6,0x6F,0xF0,
0x3F,0x00,0x1F,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x70,0x3F,0xC7,0xE7,0xEF,0xF8,
0x1F,0x80,0x0F,0x80,0x3C,0x00,0x00,0x00,0x00,0x00,0x7E,0x3D,0xE0,0xF7,0x8F,0x78,
0x0F,0xC0,0x07,0xC0,0x78,0x00,0x00,0x00,0x00,0x00,0x3F,0x38,0xE7,0xF7,0x0E,0x38,
0x07,0xE0,0x0F,0xE0,0xF0,0x00,0x00,0x00,0x00,0x00,0x0F,0xB8,0xE7,0xF7,0x0E,0x38,
0x03,0xF0,0x1F,0xF1,0xE0,0x00,0x00,0x00,0x00,0x00,0x03,0xB8,0xEE,0x77,0x0E,0x38,
0x01,0xF8,0x3F,0xFB,0xC0,0x00,0x00,0x00,0x00,0x00,0x7F,0xB8,0xEE,0x77,0x0F,0x78,
0x00,0xFC,0x7E,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x7F,0xB8,0xEF,0xF7,0x0F,0xF8,
0x00,0x7E,0xFC,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x38,0xE7,0xFF,0x0E,0xF0,
0x00,0x3F,0xF8,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,
0x00,0x1F,0xF0,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,
0x00,0x0F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,
0x00,0x07,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};



/*------------------初始化-----------------*/
void init_lcd (void)
{
  rst=1;
  psb=1;
  wr_lcd (comm,0x30);  /*30---基本指令动作*/   
  wr_lcd (comm,0x01);  /*清屏,地址指针指向00H*/
  wr_lcd (comm,0x06);  /*光标的移动方向*/
  wr_lcd (comm,0x0c);  /*开显示,关游标*/
}
/*---------------显示汉字或字符----------------*/
void chn_disp (uchar code *chn)
{
  uchar i,j;
  wr_lcd (comm,0x30);
  wr_lcd (comm,0x80);
  j=0;
  for (i=0;i<16;i++)
  wr_lcd (dat,chn[j*16+i]);
  wr_lcd (comm,0x90);
  j=1;
  for (i=0;i<16;i++)
  wr_lcd (dat,chn[j*16+i]);
}
/*----------------显示图形-----------------*/
void img_disp (uchar code *img)
{
  uchar i,j;
  for(j=0;j<32;j++)
  {
    for(i=0;i<8;i++)
    {
      wr_lcd (comm,0x34);
      wr_lcd (comm,y+j);
      wr_lcd (comm,x+i);
      wr_lcd (comm,0x30);
      wr_lcd (dat,img[j*16+i*2]);
      wr_lcd (dat,img[j*16+i*2+1]);
    }
  }
  wr_lcd (comm,0x36);
}
/*--------------显示点阵----------------*/
void lat_disp (uchar data1,uchar data2)
{
  uchar i,j;
  for(j=0;j<16;j++)
  {
    for(i=0;i<8;i++)
    {
      wr_lcd (comm,0x34);
      wr_lcd (comm,y+j*2);
      wr_lcd (comm,x+i);
      wr_lcd (comm,0x30);
      wr_lcd (dat,data1);
      wr_lcd (dat,data1);
    }
    for(i=0;i<8;i++)
    {
      wr_lcd (comm,0x34);
      wr_lcd (comm,y+j*2+1);
      wr_lcd (comm,x+i);
      wr_lcd (comm,0x30);
      wr_lcd (dat,data2);
      wr_lcd (dat,data2);
    }
  }
  wr_lcd (comm,0x36);
}
/*-----------------------------------------------*/
//当data1=0xff,data2=0xff时,在x0,y0处反白显示16xl*yl.
void con_disp (uchar data1,uchar data2,uchar x0,uchar y0,uchar xl,uchar yl)
{
  uchar i,j;
  for(j=0;j<yl;j++)
  {
    for(i=0;i<xl;i++)
    {
      wr_lcd (comm,0x34);
      wr_lcd (comm,y0+j);
      wr_lcd (comm,x0+i);
      wr_lcd (comm,0x30);
      wr_lcd (dat,data1);
      wr_lcd (dat,data2);
    }
  }
  wr_lcd (comm,0x36);
}
/*--------------清DDRAM------------------*/
void clrram (void)
{
  wr_lcd (comm,0x30);
  wr_lcd (comm,0x01);
}
/*---------------------------------------*/
void wr_lcd (uchar dat_comm,uchar content)
{
  chk_busy ();
  if(dat_comm)
   {
    rs=1;   //data
    rw=0;   //write
   }
  else
   {
    rs=0;   //command
    rw=0;   //write
   }
  P1=content;   //output data or comm
  e=1;
  ;
  e=0;
}

void chk_busy (void)
{
  P1=0xff;
  rs=0;
  rw=1;
  e =1;
  while(busy==1);
  e =0;
}
/*---------------------------------------*/
void delay (uint us)   //delay time
{
  while(us--);
}
void delay1 (uint ms)
{
  uint i,j;
  for(i=0;i<ms;i++)
  for(j=0;j<15;j++)
  delay(1);
}
/*------------------主程序--------------------*/
void main ()
{
  SP=0x5f;
  init_lcd ();
  while (1)
  {
    lat_disp (0x00,0x00);
    chn_disp (tab1);
    con_disp (0xff,0xff,0x80,0x90,1,16);
    delay1 (5000);
    clrram();
    lat_disp (0xcc,0xcc);
    delay1 (5000);
    clrram();
    lat_disp (0xff,0x00);
    delay1 (5000);
    img_disp (tab5);
    delay1 (5000);
  }
}
brahen
3楼-- · 2020-02-08 15:54
我没看代码。
楼主有没有写一个for loop,尝试不断刷新该图片?
BDXing6
4楼-- · 2020-02-08 19:37
 精彩回答 2  元偷偷看……
paradisespace
5楼-- · 2020-02-08 20:05
brahen 发表于 2012-5-29 09:51
我没看代码。
楼主有没有写一个for loop,尝试不断刷新该图片?

我试过把绘图的所有函数都放在一个while里死循环,但是还是有杂点,唯一区别就是屏幕一直刷新,显示的也不流畅
paradisespace
6楼-- · 2020-02-09 00:23
joing2000 发表于 2012-5-29 09:51
我看了。关键不在你发的那部分程序上面呀。我发我的例程给你看看。


#include

整个工程文件我上传了,我对着你的代码看看。你也帮我看看我的代码吧。

一周热门 更多>