搜索
bottom↓
回复: 179

发一个ST7920控制器LCD12864源代码,有画点、画线功能

  [复制链接]

出0入0汤圆

发表于 2009-6-28 23:01:30 | 显示全部楼层 |阅读模式
最近做个项目,要用到一块12864的液晶CM12864-12,使用ST7920控制器,这款控制器内置了汉字库显示字符汉字方便,但是汉字库是16*16点阵的,我要显示点别的怎么??可以用图形RAM画图。我想显示12*12的汉子,这样就能显示五行了!我的实现思路是实现画点函数,画点函数需要对GDRAM读,不然显示一团糟!这里用7920的并行模式,串行模式虽然节省IO口,但是不能读出数据!那就开始吧!
在网上找了7、8个版本的7920驱动,发现几乎都只用了基本的显示字符汉字功能,即使使用的画图,也没有画点!!
自己写!看着液晶手册写,但是显示乱七八糟,怎么改都不行,以前也过KS0108的画点函数不难啊??怎么这个就不行了!一点点着,发现读GDRAM数据有问题,读出的数据不正确!液晶手册不是很详细,还是看7920的手册!
终于找到问题所在:原来7920读出数据时,需要DUMMY READ,就是要读两次!!液晶手册很害人,就说个大概!看来以后要注意啊,要从跟上看!!!
简单一改,就OK了!!
现在把照片,电路(非常简单),源码都亮出来!!希望阿莫给个COOL!(7920的实现画点的代码网上可能没有啊,反正我没找到!嘿嘿)


电路

(原文件名:12864.JPG)
显示效果

(原文件名:IMG_3244.JPG)
实验板

(原文件名:IMG_3245.JPG)
源码
点击此处下载 ourdev_456695.rar(文件大小:424K) (原文件名:OM_test.rar)

阿莫论坛20周年了!感谢大家的支持与爱护!!

你熬了10碗粥,别人一桶水倒进去,淘走90碗,剩下10碗给你,你看似没亏,其实你那10碗已经没有之前的裹腹了,人家的一桶水换90碗,继续卖。说白了,通货膨胀就是,你的钱是挣来的,他的钱是印来的,掺和在一起,你的钱就贬值了。

出0入0汤圆

发表于 2009-6-28 23:04:41 | 显示全部楼层
cool!

出0入0汤圆

发表于 2009-6-28 23:20:56 | 显示全部楼层
cool

出0入0汤圆

发表于 2009-6-28 23:27:22 | 显示全部楼层
这么长时间了,我抢了靠前的位置,哈哈,板凳学习

出0入0汤圆

发表于 2009-6-29 01:15:13 | 显示全部楼层
源码。。。。。。。

出0入0汤圆

 楼主| 发表于 2009-6-29 07:43:35 | 显示全部楼层
昨晚忘传代码了,不好意思,现在已经补上了!!!

出0入0汤圆

发表于 2009-6-29 08:01:02 | 显示全部楼层
好!

出0入0汤圆

发表于 2009-6-29 08:18:15 | 显示全部楼层
dddddddddddd

出0入0汤圆

 楼主| 发表于 2009-6-29 08:44:59 | 显示全部楼层
程序的基本操作,是从51中移植过来的,感谢原作者!
程序还不是特别完善,请大家多提建议!
目前程序支持8bit并行和串行操作(串行不能读)
下一步看看手中的模块是否支持4bit并行,争取弄出来,继续公布源码!

出0入0汤圆

发表于 2009-6-29 10:23:52 | 显示全部楼层
无语,我发过两次ST7920芯片的程序,
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=3349967&bbs_page_no=1&search_mode=3&search_text=liudeee&bbs_id=9999
上面这个事第一发,有几处有问题。
http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=3411711&bbs_page_no=1&search_mode=3&search_text=liudeee&bbs_id=9999
这个是后来修改又发的,

画线,画点,画圆,用绘图方法写任意大小的字体,函数都有,LZ怎么说没找到。无语,绝对方便在AVR上移植

同样是并行


画图方法写任意大小字体 (原文件名:ourdev_445191.jpg)

出0入0汤圆

 楼主| 发表于 2009-6-29 10:34:00 | 显示全部楼层
真的没找到啊!在这个坛子就找了5、6个版本呢!呵呵,用搜索找的,大海捞针呢,不一定就捞得到想要的啊!

出0入0汤圆

发表于 2009-6-29 21:45:23 | 显示全部楼层
能否放出GUI里面的画点程序阿,为什么网上找的东西都是不完全的呢?

不过楼主的程序真漂亮,呵呵,我觉得用漂亮来形容比较合适.我现在写的东西还是很乱那,不过以后争取写得规范些.

出0入0汤圆

发表于 2009-6-30 00:38:16 | 显示全部楼层
//**********************************************************
// 名称:GUI_Point(unsigned char y,unsigned char x,unsigned colour)
// 功能:在指定位置上画点。
// 入口参数:x                指定点所在行的位置
//           y                指定点所在列的位置
//          color             显示颜色(对于黑白色LCD12864,为0时灭,为1时显示)
// 出口参数:无
//**********************************************************
void GUI_Point(unsigned char y,unsigned char x,unsigned colour)
{
    unsigned char GDRAM_hbit,GDRAM_lbit;
    unsigned char x_Dyte,x_byte;                 //定义列地址的字节位,及在字节中的哪1位
    unsigned char y_Dyte,y_byte;        
    x--;y--;                                                                         //定义为上下两个屏(取值为0,1),行地址(取值为0~31)
    /***X,Y坐标互换,即普通的X,Y坐标***/
    x_Dyte=y/16;                                         //计算在16个字节中的哪一个
    x_byte=y&0x0f;                                     //计算在该字节中的哪一位
    y_Dyte=x/32;                                         //0为上半屏,1为下半屏
    y_byte=x&0x1f;                                     //计算在0~31当中的哪一行
   
    LCD12864_Write(COMMAND,0x80+y_byte);                     //设定行地址(y坐标)
    LCD12864_Write(COMMAND,0x80+x_Dyte+8*y_Dyte);         //设定列地址(x坐标),并通过8*y_Dyte选定上下屏
                           
    LCD12864_Read();
    GDRAM_hbit=LCD12864_Read();                         //读取当前显示高8位数据
    GDRAM_lbit=LCD12864_Read();                         //读取当前显示低8位数据
    Delay_nus(1);
   
    if(colour==1)
    {
                LCD12864_Write(COMMAND,0x80+y_byte);                     //设定行地址(y坐标)
                LCD12864_Write(COMMAND,0x80+x_Dyte+8*y_Dyte);         //设定列地址(x坐标),并通过8*y_Dyte选定上下屏
                Delay_nus(1);

        if(x_byte<8)                                             //判断其在高8位,还是在低8位
                {
                        LCD12864_Write(DATA,GDRAM_hbit|(0X01<<(7-x_byte)));     //显示GDRAM区高8位数据
                        LCD12864_Write(DATA,GDRAM_lbit);                             //显示GDRAM区低8位数据
        }
        else
        {
                        LCD12864_Write(DATA,GDRAM_hbit);
                        LCD12864_Write(DATA,GDRAM_lbit|(0x01<<(15-x_byte)));
        }
    }
    else
    {
                LCD12864_Write(COMMAND,0x80+y_byte);                     //设定行地址(y坐标)
                LCD12864_Write(COMMAND,0x80+x_Dyte+8*y_Dyte);         //设定列地址(x坐标),并通过8*y_Dyte选定上下屏
                Delay_nus(1);

        if(x_byte<8)                                             //判断其在高8位,还是在低8位
                {
                        LCD12864_Write(DATA,GDRAM_hbit & ~(0X01<<(7-x_byte)));     //显示GDRAM区高8位数据
                        LCD12864_Write(DATA,GDRAM_lbit);                             //显示GDRAM区低8位数据
        }
        else
        {
                        LCD12864_Write(DATA,GDRAM_hbit);
                        LCD12864_Write(DATA,GDRAM_lbit & ~(0x01<<(15-x_byte)));
        }
        }
       
}


/***********************************************************
* 名称:GUI_Line(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char colour)
* 功能:在指定位置上画线。
* 入口参数:x0                指定线起点所在行的位置
*           y0           指定线起点所在列的位置
*           x1                指定线终点所在行的位置
*           y1           指定线终点所在列的位置
*          color             显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
/**********************************************************/
void GUI_Line(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char colour)
{
    int temp;
    int dx,dy;               //定义起点到终点的横、纵坐标增加值
    int s1,s2,status,i;
    int Dx,Dy,sub;

    dx = x1 - x0;
    if(dx >= 0)                 //X的方向是增加的
        s1 = 1;
    else                     //X的方向是降低的
        s1 = -1;     
    dy = y1 - y0;                 //判断Y的方向是增加还是降到的
    if(dy >= 0)
        s2 = 1;
    else
        s2 =- 1;
  
    Dx = abs(x1-x0);             //计算横、纵标志增加值的绝对值
    Dy = abs(y1-y0);
      
    if(Dy > Dx)                              
    {                     //以45度角为分界线,靠进Y轴是status=1,靠近X轴是status=0
        temp = Dx;
        Dx = Dy;
        Dy = temp;
    status = 1;
    }
    else
        status = 0;


/*********Bresenham算法画任意两点间的直线********/
    sub = Dy + Dy - Dx;                 //第1次判断下个点的位置
    for(i = 0;i < Dx;i ++)
    {
        GUI_Point(x0,y0,colour);           //画点
        if(sub >= 0)                              
        {
            if(status == 1)               //在靠近Y轴区,x值加1
                x0 += s1;
            else                     //在靠近X轴区,y值加1               
                y0 += s2;
            sub -= (Dx + Dx);                 //判断下下个点的位置
        }
        if(status == 1)
            y0 += s2;
        else      
            x0 += s1;
        sub += Dy + Dy;
        
    }
}


       

/****************************************************************************
* 名称:plotC(int x,int y,int xc,int yc,unsigned char colour)
* 功能:八分点画圆函数
* 入口参数:x                指定线起点所在行的位置
*           y           指定线起点所在列的位置
*          color             显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
****************************************************************************/
void plotC(int x,int y,int xc,int yc,unsigned char colour)
{
    GUI_Point(xc+x,yc+y,colour);
    GUI_Point(xc+x,yc-y,colour);
    GUI_Point(xc-x,yc+y,colour);
    GUI_Point(xc-x,yc-y,colour);
    GUI_Point(xc+y,yc+x,colour);
    GUI_Point(xc+y,yc-x,colour);
    GUI_Point(xc-y,yc+x,colour);
    GUI_Point(xc-y,yc-x,colour);
}

/****************************************************************************
* 名称:GUI_Circle(int xc,int yc,int r,unsigned char colour)
* 功能:画圆
* 入口参数:xc                圆心的行坐标
*           yc           圆心的列坐标
*           r                半径
*          color             显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
****************************************************************************/
void GUI_Circle(int xc,int yc,int r,unsigned char colour)
{
    int x,y,d;
    y = r;
    d = 3 - (r + r);
    x = 0;
    while(x <= y)
    {
        plotC(x,y,xc,yc,colour);
        if(d < 0)
            d += (x + x + x + x) + 6;
        else
        {
            d+=((x - y) + (x - y) + (x - y) + (x - y)) + 10;
            y = y - 1;
        }
        x = x + 1;
    }
}

/****************************************************************************
* 名称:GUI_Full(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char colour)
* 功能:用绘图的方法填充一个矩形
* 入口参数:x0                起始点横坐标
*           y0           起始点纵坐标
*           x1                终止点横坐标
*           y1      终止点纵坐标
*          color             显示颜色(对于黑白色LCM,为0时灭,为1时显示)
* 出口参数:无
****************************************************************************/
void GUI_Full(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char colour)
{
    unsigned char i,j;
        for(j = y0;j <= y1;j ++)
            for(i = x0;i <= x1;i ++)
                    GUI_Point(i,j,colour);
}

出0入0汤圆

 楼主| 发表于 2009-6-30 08:39:12 | 显示全部楼层
//******************************************************************************
//*函数名称:void LCD_Point(unsigned char x,unsigned char y,unsigned char color)*
//*函数功能:使用绘图的方法,在(x,y)处画一个16*16点阵的图案,也可以是字符                   *
//*形式参数:unsigned char x,unsigned char y,unsigned char color                *
//*                        x取值范围:0~127                                                                                                           *
//*                        y取值范围:0~63 (针对CM12864-12型液晶)                                                       *
//*形参说明:坐标水平位置,坐标垂直位置                                                                      *
//*液晶屏坐标说明:                                                                                                                           *
//*      ________________128个像素______________________              *
//*      |(0,0)                                    (7,0)|             *
//*      |                                              |             *
//*   64 |                                              |             *
//*   个 |(0,31)                                  (7,31)|             *
//*   像 |(8,0)                                   (15,0)|             *
//*   素 |                                              |             *
//*      |                                              |             *
//*      |(8,31)                                 (15,31)|             *
//*      |______________________________________________|             *
//*                                                                   *
//*返回参数:无                                                              *
//*使用说明:此函数适用于CM12864-12型液晶                        *
//******************************************************************************
void LCD_Point(unsigned char x,unsigned char y,unsigned char color)
{
        unsigned char i,AddrX,AddrY;        //寄存器地址
        unsigned char BitTemp;                //该点在16bit的位置
        unsigned char DataH,DataL;

        AddrX = x>>4;                                // x/16
        AddrY = y&0x3F;                                // y%64
        if(y > 31)
        {
                AddrX += 8;
                AddrY -= 32;
        }
        BitTemp = x&0x0F;                        // x%16

       
        LCD_GraphModeSet(0x00);                //先关闭图形显示功能
    //LCD_Write(LCD_COMMAND,LCD_EXTEND_FUNCTION);
       
        for(i=0;i<4;i++)
        {
        LCD_GDRAM_AddressSet(0x80+AddrY);
        LCD_GDRAM_AddressSet(0x80+AddrX);
        //LCD_Write(LCD_COMMAND,LCD_BASIC_FUNCTION);                        //基本指令集
        DataH = LCD_ReadData();
        DataH = LCD_ReadData();
        DataL = LCD_ReadData();
        //DataH = LCD_ReadData();
        //DataL = LCD_ReadData();
        }

        if(color == LCD_COLOR_BLACK)
        {
                if(BitTemp > 7)
                {
                        DataL |= (0x80>>(BitTemp-8));
                }
                else
                {
                        DataH |= (0x80>>(BitTemp));
                }
        }
        else
        {
        }

        LCD_GDRAM_AddressSet(0x80+AddrY);
        LCD_GDRAM_AddressSet(0x80+AddrX);
        LCD_Write(LCD_DATA,DataH);
        LCD_Write(LCD_DATA,DataL);
       
        LCD_GraphModeSet(0x01);                                //最后打开图形显示功能
}

出0入0汤圆

 楼主| 发表于 2009-6-30 08:40:34 | 显示全部楼层
【11楼】 zhseedling
谬赞了!我写的一般,比起高手差很多啊!不过一直在学习呢!

出0入0汤圆

发表于 2009-7-1 19:32:51 | 显示全部楼层
我用楼主的程序写的,呵呵,研究了好多天呢,终于会用了。

我想用12864作为屏幕做魏坤示波器(本论坛里的开源项目)的屏,楼主有没有好建议啊

只是图片,没有实质的东西


(原文件名:1.jpg)


(原文件名:2.jpg)


(原文件名:3.jpg)

出0入0汤圆

 楼主| 发表于 2009-7-1 21:30:32 | 显示全部楼层
【15楼】 zhseedling
刚刚才用7920的LCD,是从一个一起上拆下的,呵呵!明天就要给人家装上了,要拿走!
所以就玩了这几天!
我的感觉如果显示图形,特别是需要频繁刷新图形(示波器恰恰如此),7920并不适合,因为他需要频繁的关闭显示,这样感觉闪烁,不如KS0108方便!7920更适合显示字符!

以上愚见,请高手指正!

出0入0汤圆

发表于 2009-7-1 23:58:29 | 显示全部楼层
为了这个示波器,12864已经是我买的第二个屏了,之前买了一个320240的tft,hx8347主控的,也研究了好些天,首先是没资料,后来东凑西凑的终于找到一些资料,可始终点不亮那个屏,没办法,才买了12864,后来才发现,12864画图可真够费劲的了

出0入0汤圆

 楼主| 发表于 2009-7-2 09:59:31 | 显示全部楼层
如果做示波器还是320240比较好,分辨率高,27元那个液晶就不错,有驱动和示例代码,好像没有资料!现在好像35元了!
在 淘宝超值推荐论坛有他的连接,你可以看看!

出0入0汤圆

发表于 2009-7-4 18:55:48 | 显示全部楼层
能留下联系方式么?
hfd2k@qq.com

根据你的程序改写后,画长的斜线是一节一节的。
垂线和水平线就没问题

出0入0汤圆

发表于 2009-7-4 20:00:23 | 显示全部楼层
很好!
标记!

出0入0汤圆

发表于 2009-7-4 20:31:53 | 显示全部楼层
哇。。。。帅气。。。。。。。。。。。

出0入0汤圆

发表于 2009-7-10 16:13:27 | 显示全部楼层
楼主 我怎么把你的程序复制到我的界面下 怎么好多错误的呀  我用的CVAVR 可以把你的源程序 给我看看嘛?我的QQ 619089960 谢了
zhseedling  你是怎么移植的呀?你用的什么编译软件?

出0入0汤圆

 楼主| 发表于 2009-7-10 17:32:16 | 显示全部楼层
【19楼】 hfd999  
估计是读数据有问题!
我的EMAIL:jackielau1980@sohu.com
欢迎交流,最近在外地!
【22楼】 wuyuwuqi
当然了  我用的GCC,呵呵看看什么错误,改改就好了
我不懂CVAVR啊

出0入0汤圆

发表于 2009-7-11 08:52:45 | 显示全部楼层
头文件看了一下,好像原有的设计应该是并行、串行都可以用的,不知为什么串行的没用出来,那我就花点功夫看看并行的吧。

出0入0汤圆

发表于 2009-7-11 08:58:13 | 显示全部楼层
好东西,留名

出0入0汤圆

发表于 2009-7-13 10:29:09 | 显示全部楼层
mark一个,回头继续看

出0入0汤圆

 楼主| 发表于 2009-7-14 09:14:52 | 显示全部楼层
【24楼】 haozi_1989
本来打算把串行的弄出来,但是手上LCD拿走了,再加上最近出差没空,也就一直没写!!
这个控制器有个缺点,就是串行不能读操作,这样花点画线就很难实现,(除非在RAM中开辟一块1024B的缓存,我用的M16,好像只有1KRAM,所以比较难实现了),所以就尽头不大了!!

出0入0汤圆

 楼主| 发表于 2009-7-14 09:18:51 | 显示全部楼层
通用24CXXX读写程序(GCC),兼容24C系列存储器(24C01到24C1024),支持跨器件跨页读写,支持连续读写32K字节
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=3444492&bbs_page_no=1&search_mode=3&search_text=jackielau&bbs_id=9999
也是我也写的,呵呵,欢迎提出意见

出0入0汤圆

发表于 2009-7-16 21:12:09 | 显示全部楼层
同文件兼顾了串行和并行两种方式,但是发的好像有问题,头文件里的函数和测试程序里的好像不匹配,不知是何原因

出0入0汤圆

 楼主| 发表于 2009-7-17 11:15:11 | 显示全部楼层
【29楼】 haozi_1989
呵呵,找到问题了,你看的是main。c,测试程序不是这个文件!!是OM_test.c.c
重新上传!!!

点击此处下载 ourdev_462016.rar(文件大小:421K) (原文件名:ourdev_456695.rar)

出0入0汤圆

发表于 2009-7-25 20:32:00 | 显示全部楼层
受教了!

出0入0汤圆

发表于 2009-7-28 14:28:53 | 显示全部楼层
jihao

出0入0汤圆

 楼主| 发表于 2009-7-28 15:32:41 | 显示全部楼层
字符汉字显示用7920很方便,但是画图还是KS0108的感觉好一些

出0入0汤圆

发表于 2009-7-29 10:35:05 | 显示全部楼层
我的7920屏有个问题:一进入图形模式就花屏(黑白点乱乱的),害得我每次都要全屏写零一次。不知道是啥原因?
请高手帮忙找找原因。

出0入0汤圆

发表于 2009-7-29 13:33:13 | 显示全部楼层
mark!

出0入0汤圆

 楼主| 发表于 2009-7-29 15:29:05 | 显示全部楼层
【35楼】 vipxuliang
应该是屏RAM数据没有全部变零。你的是不是有大电容或者掉电时间很多才出啊?关机很长时间也出这个问题吗?
另外,我觉得开机对屏RAM清零是必要的!

出0入0汤圆

发表于 2009-7-29 16:27:16 | 显示全部楼层
记号

出0入0汤圆

发表于 2009-7-31 18:51:00 | 显示全部楼层
我用楼主的程序,怎么画一条竖线时会同时出现三条竖线呢?环境:M16,studio 4.16,(GCC)WinAVR-20080610,金鹏OCMJ4X8C型12864液晶,一直没搞明白哪地方错了,希望楼主能帮忙看一下...本人在校生...QQ:897772871,同时欢迎各位朋友加友交流,注明avr论坛...

程序自己稍稍改了一下,如下:
#include<avr/io.h>
#include<delay.h>
#include<math.h>
#include <string.h>

#define uchar unsigned char
#define uint unsigned int
#define CTRL_PORT  PORTA
#define CTRL_DDR  DDRA
#define CTRL_PIN  PINA
#define RS 5                         //CS   第四引脚
#define RW 6                        //SIO  第五引脚
#define E  7                        //SCK  第六引脚
     
#define DATA_DDR DDRD
#define DATA_PIN PIND
#define DATA_PORT PORTD

#define CTRL_OUT() CTRL_DDR |= (1<<(RS))|(1<<(RW))|(1<<(E))

#define  CLR_RS() CTRL_PORT &= ~(1<<RS)
#define  SET_RS() CTRL_PORT |= (1<<RS)

#define CLR_RW() CTRL_PORT &= ~(1<<RW)
#define SET_RW() CTRL_PORT |= (1<<RW)

#define CLR_E()  CTRL_PORT &= ~(1<<E)
#define SET_E()     CTRL_PORT |= (1<<E)


#define DATA_IN() DATA_DDR &= ~0xFF
#define DATA_OUT() DATA_DDR |= 0xFF
#define DATA_GET() DATA_PIN

//液晶基本参数
#define X_MAX 127
#define Y_MAX 63

//每行的首地址
#define ONE   0x80
#define TWO   0x90
#define THREE 0x88
#define FOUR  0x98

//基本指令集预定义
#define DATA                1          //数据位
#define COMMAND             0         //命令位
#define CLEAR_SCREEN        0x01      //清屏
#define ADDRESS_RESET       0x02      //地址归零   
#define BASIC_FUNCTION      0x30       //基本指令集
#define EXTEND_FUNCTION     0x34      //扩充指令集

//扩展指令集预定义
#define AWAIT_MODE 0x01                //待命模式
#define ROLLADDRESS_ON 0x03           //允许输入垂直卷动地址
#define IRAMADDRESS_ON 0x02           //允许输入IRAM地址
#define SLEEP_MODE 0x08               //进入睡眠模式
#define NO_SLEEP_MODE 0x0c           //脱离睡眠模式
#define GRAPH_ON 0x36               //打开绘图模式
#define GRAPH_OFF 0x34               //关闭绘图模式

#ifndef COLOR
#define BLACK      1
#define WHITE      0
#endif


void SendByte(unsigned char a)
{
unsigned char i,d;
SET_RS();
CLR_RW();
for(i=0;i<8;i++)
{
CLR_E();           //clrbit(LCD_CTRL,E);   
d = a&0x80;
if(d)
SET_RW(); //setbit(LCD_CTRL,RW);
else
CLR_RW(); //clrbit(LCD_CTRL,RW);
a<<=1;
SET_E();         //setbit(LCD_CTRL,E); //上升弦发送
}
CLR_RS();
}



void CheckBusy(void)
{
unsigned char temp;
DATA_IN();   
CLR_RS();             //RS = 0;指令
SET_RW();             //RW = 1;读模式
delay3us();           //延时
delay3us();            //延时
SET_E();              //E  = 1,使能
do
{
temp = DATA_GET();                       //temp = BUSY;
}
while( 0x80==(temp&0x80) );         //等待不忙,temp=0x00时不忙
CLR_E();                                   //E  = 0;
}



void Write( unsigned char Data_Command , unsigned char uc_Content )
{  
CheckBusy();
DATA_OUT();

if(Data_Command==COMMAND)
{
CLR_RS();               //RS = 0;指令
}
else  
{
SET_RS();                //RS = 1; 数据
}
CLR_RW();                //RW = 0;   //写模式
DATA_PORT = uc_Content;
SET_E();                   //E = 1;
delay3us();                 //延时
CLR_E();                 //E = 0;
}



unsigned char ReadData(void)
{
unsigned char uc_Content;
CheckBusy();
DATA_PORT = 0xff ;
DATA_IN();                     //P1 = 0xff;//输入前置1
SET_RS();                    //RS = 1;   //数据
SET_RW();                    //RW = 1; //读模式
SET_E();                    //E = 1; //使能
delay3us();                     //延时很重要  
uc_Content = DATA_GET();    //uc_Content = P1;    //P1口的内容放到变量中
CLR_E();                    //E = 0;
delay3us();                 //延时很重要  
return uc_Content;
}

void DDRAM_AddressSet(unsigned char ucDDramAdd)
{
Write(COMMAND,BASIC_FUNCTION);          //基本指令集
Write(COMMAND,ucDDramAdd);              //设定DDRAM地址到地址计数器AC
}

void CGRAM_AddressSet(unsigned char ucCGramAdd)
{
Write(COMMAND,BASIC_FUNCTION); //基本指令集
Write(COMMAND,ucCGramAdd); //设定CGRAM地址到地址计数器AC
}

void GDRAM_AddressSet(unsigned char ucGDramAdd)
{
Write(COMMAND,EXTEND_FUNCTION); //扩展指令集
Write(COMMAND,ucGDramAdd);
}

void Init(void)
{
CTRL_OUT();
Write(COMMAND,BASIC_FUNCTION); //基本指令动作   
delay50us();
Write(COMMAND,CLEAR_SCREEN);   //清屏,地址指针指向00H
delay50us();
Write(COMMAND,0x06);       //光标的移动方向
delay50us();
Write(COMMAND,0x0C);   //开显示,关游标
}


void ClearRam(void)
{
Write(COMMAND,BASIC_FUNCTION); //基本指令集
Write(COMMAND,CLEAR_SCREEN); //清屏
}

void GraphModeSet(unsigned char Select)
{
Write(COMMAND,EXTEND_FUNCTION); //扩展指令集
if(Select==1)
{
Write(COMMAND,GRAPH_ON); //打开绘图模式
}
else
{
Write(COMMAND,GRAPH_OFF); //关闭绘图模式
}
}


void DisplayCLR()
{
unsigned char i,j;
GraphModeSet(0); //先关闭图形显示功能
for(j=0;j<32;j++)
    {
     for(i=0;i<8;i++)
       {
       Write(COMMAND,0x80+j); //设定垂直坐标
       Write(COMMAND,0x80+i); //设定水平坐标
           Write(DATA,0x00); //放入数据高字节
       Write(DATA,0x00); //放入数据低字节
      }
    }
   for(j=32;j<64;j++)
    {
     for(i=0;i<8;i++)
      {
       Write(COMMAND,0x80+j-32);
       Write(COMMAND,0x88+i);
       Write(DATA,0x00);
       Write(DATA,0x00);
      }
    }
GraphModeSet(1);//最后打开图形显示功能
}

void LCD_Point(unsigned char x,unsigned char y,unsigned char color)
{
        unsigned char i,AddrX,AddrY;                  //寄存器地址
        unsigned char BitTemp;                //该点在16bit的位置
        unsigned char DataH,DataL;
        AddrX = x>>4;                                // x/16
        AddrY = y&0x3F;                                // y%64
        if(y > 31)
        {
                AddrX += 8;
                AddrY -= 32;
        }
        BitTemp = x&0x0F;                        // x%16
        GraphModeSet(0x00);                          //先关闭图形显示功能          
        for(i=0;i<4;i++)
        {
        GDRAM_AddressSet(0x80+AddrY);
        GDRAM_AddressSet(0x80+AddrX);
        DataH = ReadData();
        DataH = ReadData();
        DataL = ReadData();
        }
        if(color == BLACK)
        {
                if(BitTemp > 7)
                {
                        DataL |= (0x80>>(BitTemp-8));
                }
                else
                {
                        DataH |= (0x80>>(BitTemp));
                }
        }
        else
        {
        }
        GDRAM_AddressSet(0x80+AddrY);
        GDRAM_AddressSet(0x80+AddrX);
        Write(DATA,DataH);
        Write(DATA,DataL);       
        GraphModeSet(0x01);                                //最后打开图形显示功能
}


int main()
{
    uchar i;
    Init();                                                 //液晶屏初始化
    ClearRam();                                             //清除显示存储区内的内容
    DisplayCLR();
   
    for(i=0;i<50;i++)
        {     
            LCD_Point(0,i,1);
        }
}

出0入0汤圆

发表于 2009-7-31 23:23:47 | 显示全部楼层
先做个记号,,,,,

出0入85汤圆

发表于 2009-7-31 23:40:57 | 显示全部楼层
【39楼】 coolc : ReadData 有错哦~
unsigned char ReadData(void)  
{  
  unsigned char uc_Content;  
  CheckBusy();

  /*!!*/
  DATA_PORT = 0xff ; /*!!*/
  /*!!*/

  DATA_IN();                     //P1 = 0xff;//输入前置1  
  SET_RS();                    //RS = 1;   //数据  
  SET_RW();                    //RW = 1; //读模式  
  SET_E();                    //E = 1; //使能  
  delay3us();                     //延时很重要   
  uc_Content = DATA_GET();    //uc_Content = P1;    //P1口的内容放到变量中  
  CLR_E();                    //E = 0;  
  delay3us();                 //延时很重要   
  return uc_Content;  
}  

应改为
unsigned char ReadData(void)  
{  
  unsigned char uc_Content;  
  CheckBusy();

  DATA_IN();                  //P1设置为输入

  DATA_IN();                     
  SET_RS();                    //RS = 1;   //数据  
  SET_RW();                    //RW = 1; //读模式  
  SET_E();                    //E = 1; //使能  
  delay3us();                     //延时很重要   
  uc_Content = DATA_GET();    //uc_Content = P1;    //P1口的内容放到变量中  
  CLR_E();                    //E = 0;  
  delay3us();                 //延时很重要   

  DATA_OUT();                //P1设置为输出
  
  return uc_Content;  
}

出0入0汤圆

发表于 2009-8-1 09:20:59 | 显示全部楼层
谢了!!楼上的,这个地方确实有点问题,但是我改过了,还是在(0,0)写一点在其后又出现两点,画一条竖线出现三条竖线的情况啊!!附上12864连接图,PSB接的是高电平,不会是连接的问题或是液晶屏的问题吧....
还有楼主的程序:这里为什么要循环读四次呢?
for(i=0;i<4;i++)
{
GDRAM_AddressSet(0x80+AddrY);
GDRAM_AddressSet(0x80+AddrX);
DataH = ReadData();
DataH = ReadData();
DataL = ReadData();
}

(原文件名:12864.jpg)

出0入0汤圆

发表于 2009-8-1 10:41:24 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2009-8-3 08:55:40 | 显示全部楼层
【42楼】 coolc
那个实在最初试验时加的,当时没有明白“假读”,用多循环几次解决问题!现在说应该是没用的

“在(0,0)写一点在其后又出现两点,画一条竖线出现三条竖线的情况”
估计是读数据出的问题,画点需要读数据,如果有足够的RAM,建议不用他,在RAM建立镜像BUF

出0入0汤圆

发表于 2009-8-4 12:53:36 | 显示全部楼层
..嗯 不错 学习了

出0入0汤圆

发表于 2009-8-8 11:24:25 | 显示全部楼层
谢谢啊

出0入0汤圆

发表于 2009-8-9 17:10:18 | 显示全部楼层
【42楼】 coolc
那个实在最初试验时加的,当时没有明白“假读”,用多循环几次解决问题!现在说应该是没用的

“在(0,0)写一点在其后又出现两点,画一条竖线出现三条竖线的情况”
估计是读数据出的问题,画点需要读数据,如果有足够的RAM,建议不用他,在RAM建立镜像BUF


我也出现类似的问题,读数据出现什么问题了,能否具体说明!!!!!!!!

出0入0汤圆

发表于 2009-8-9 19:00:07 | 显示全部楼层
//读数据
unsigned char Lcd_Readdata()
{  
  idata uchar dudata ;
   wait();
   RS=1;
   RW=1;
   E=0;
   delay_us(1);          
   dudata=LcdData;
   E=1;
   delay_us(1);       
   E=0;               
   return dudata;
}



void GUI_Point(uchar x,uchar y)
{   
   
   uchar x_Dyte,x_byte; //定义列地址的字节位,及在字节中的哪1位  
   uchar y_Dyte,y_byte;//定义为上下两个屏(取值为0,1),行地址(取值为0~31)
   uchar GDRAM_hbit,GDRAM_lbit;                     
   /***X,Y坐标互换,即普通的X,Y坐标***/
   x_Dyte=x/16; //计算在16个字节中的哪一个
   x_byte=x&0x0f; //计算在该字节中的哪一位
   y_Dyte=y/32;   //0为上半屏,1为下半屏
   y_byte=y&0x1f;  //计算在0~31当中的哪一行

   Lcd_WriteCmd(0x36); //绘图模式命令
   Lcd_WriteCmd(0x80+y_byte);//设定行地址(y坐标)
   Lcd_WriteCmd(0x80+x_Dyte+8*y_Dyte);//设定列地址(x坐标),并通过8*y_Dyte选定上下屏  
   
   Lcd_Readdata();
   GDRAM_hbit=Lcd_Readdata();
   GDRAM_lbit=Lcd_Readdata();
           
    Lcd_WriteCmd(0x80+y_byte);//设定行地址(y坐标)
    Lcd_WriteCmd(0x80+x_Dyte+8*y_Dyte); //设定列地址(x坐标),并通过8*y_Dyte选定上下屏
       
         if(x_byte<8)//判断其在高8位,还是在低8位
         {
          Lcd_Writedata(GDRAM_hbit|(0X01<<(7-x_byte))); //显示GDRAM区高8位数据
          Lcd_Writedata(GDRAM_lbit); //显示GDRAM区低8位数据  
         }
         else
         {
          Lcd_Writedata(GDRAM_hbit);
          Lcd_Writedata(GDRAM_lbit|(0x01<<(15-x_byte)));
         }  

   Lcd_WriteCmd(0x30);      
}


这是我的画点函数,用的是12楼的程序,不知哪里有错啊!!!!!  知道的兄弟请指点!!!!!

出0入85汤圆

发表于 2009-8-9 19:15:13 | 显示全部楼层
【49楼】 jiang0603
读函数错了,首先读时序就错了,
应该是置位E再读延时后E清零
还有如果是AVR等真正双向I/O口(51是伪双向的)LcdData的方向要改为输入

出0入0汤圆

发表于 2009-8-9 20:08:17 | 显示全部楼层
我试过这种写法,用的是STC的51单片机
//读数据
unsigned char Lcd_Readdata()
{  
  idata uchar dudata ;
   wait();//判忙
   RS=1;
   RW=1;
   E=1;       
   delay_us(1);          
   dudata=LcdData;
   delay_us(1);       
   E=0;               
   return dudata;
}
但问题还是没有解决啊!!!!!!

出0入0汤圆

发表于 2009-8-9 20:15:46 | 显示全部楼层
好东西 ,谢谢

出0入85汤圆

发表于 2009-8-9 20:32:13 | 显示全部楼层
【51楼】 jiang0603
你问题是什么啊??现象呢

出0入0汤圆

发表于 2009-8-9 21:12:01 | 显示全部楼层
现象是:不能写直线,写直线时二个字节只能写一个点,写斜线和竖线没问题,所以我觉得问题应该是没有把上一次的数据给读会来!!
不知道各位高手有没其它意见啊!!!!!

出0入0汤圆

发表于 2009-8-9 21:13:34 | 显示全部楼层
ps:
   也就是这里:
    Lcd_Readdata();
   GDRAM_hbit=Lcd_Readdata();
   GDRAM_lbit=Lcd_Readdata();

出0入0汤圆

发表于 2009-8-14 10:39:56 | 显示全部楼层
用过 顶个

出0入0汤圆

发表于 2009-8-14 10:57:20 | 显示全部楼层
好东西,留名

出0入0汤圆

 楼主| 发表于 2009-8-14 17:19:16 | 显示全部楼层
【54楼】 jiang0603

从现象上看,应该是读数据有问题!
你可以具体试一试,比如向某一位置写入数据(例如0x55),然后读出看看还是不是这个值啊?!
你说的问题,没出现,试了多次!可能器件不同有点差别!

出0入0汤圆

发表于 2009-8-15 19:59:16 | 显示全部楼层
jiang0603,我的也是这样,“写直线时二个字节只能写一个点,写斜线和竖线没问题”
不知道你的问题解决了没有哇?

出0入0汤圆

发表于 2009-8-15 20:04:05 | 显示全部楼层
为什么水平画线就会出现 一个字只能显示一个点?而竖直画线也只能在特定的列画出来。有没有高手指点下?

出0入0汤圆

发表于 2009-8-16 08:16:41 | 显示全部楼层
十五楼你好。请问你现在示波器做怎么样了?我也在也做。遇到点问题。可以交流下吗?

出0入0汤圆

发表于 2009-8-16 17:19:17 | 显示全部楼层
jiang0603,我的也是这样,“写直线时二个字节只能写一个点,写斜线和竖线没问题”
不知道你的问题解决了没有哇?


问题已经发现了,确实出现在读数据上面啊!!!!把我的对数据函数贴出来你看看:
//读数据
unsigned char Lcd_Readdata()
{  
  idata uchar dudata ;
   wait();
   LcdData=0xff;//关键!!!!!      就是要加这一句就ok了!!!!!!!!!!
   RS=1;
   RW=1;
   E=1;       
   delay_us(1) ;          
   dudata=LcdData;       
   E=0;               
   return dudata;
}

出0入0汤圆

 楼主| 发表于 2009-8-17 09:31:17 | 显示全部楼层
【62楼】 jiang0603
你用的不是AVR?是51吗??

出0入0汤圆

发表于 2009-8-17 13:21:47 | 显示全部楼层
用的不是avr单片机,用的是51(stc)

出0入0汤圆

 楼主| 发表于 2009-8-17 15:34:22 | 显示全部楼层
【64楼】 jiang0603
知道了,51的IO口做输入时,必须输出高,它没有IO方向控制!呵呵,我一直以为用的AVR呢!

出0入0汤圆

发表于 2009-8-17 16:22:15 | 显示全部楼层
标个记

出0入0汤圆

发表于 2009-8-20 18:51:01 | 显示全部楼层
很好 很强大

出0入0汤圆

发表于 2009-8-22 14:28:08 | 显示全部楼层
先标记一个!以后肯定用的着!

出0入0汤圆

发表于 2009-8-22 14:29:10 | 显示全部楼层
鱼和熊掌不能兼得,我用串行弄了半天却发现串行不能读数据。得买个可位操作的液晶。

出0入0汤圆

 楼主| 发表于 2009-8-27 15:30:11 | 显示全部楼层
【69楼】 hxjsini 似泥
呵呵,这也是我为什么不在更新程序了!!
7920这个片子不咋地,所以写着没劲了!

出0入0汤圆

发表于 2009-9-18 15:06:15 | 显示全部楼层
真棒 我正需要 谢谢楼主 共享

出0入0汤圆

发表于 2009-9-22 00:14:37 | 显示全部楼层
好贴啊.这几天正在做12864相关的实验....
谢谢LZ共享

出0入0汤圆

发表于 2009-10-18 22:59:51 | 显示全部楼层
MARK

出0入0汤圆

发表于 2009-11-2 23:25:08 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-26 18:59:59 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-26 19:38:24 | 显示全部楼层
mark~

出0入0汤圆

发表于 2009-11-26 21:26:04 | 显示全部楼层
mark~

出0入0汤圆

发表于 2009-11-27 11:20:48 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-11-30 02:30:34 | 显示全部楼层
mark

出0入0汤圆

发表于 2009-12-29 00:07:57 | 显示全部楼层
mark。

出0入0汤圆

发表于 2010-2-9 12:13:59 | 显示全部楼层
thanks 。

出0入0汤圆

发表于 2010-2-24 11:49:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-24 13:55:31 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-2-26 16:11:55 | 显示全部楼层
回复【12楼】liudeee 小菜
-----------------------------------------------------------------------

我想请教下:Dx = abs(x1-x0);             //计算横、纵标志增加值的绝对值 次句中abs是什么意思?????


新手来着!!!

出0入0汤圆

发表于 2010-4-8 12:25:26 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-11 16:03:45 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-5-18 14:10:13 | 显示全部楼层
一年了。很有用,适合于金鹏的12864OCMJ4X8C,套用楼主程序,文字,图片都可以,就是画点是出现花屏,点已经画上去了就是花屏,不知什么原因。

出0入0汤圆

发表于 2010-6-4 16:03:27 | 显示全部楼层
我以前写过12864的驱动,觉得很奇怪,如果显示一小块图形的时候,其它的地方就是花的,害我一次就得刷整块屏,
楼主有没有写过TFT的,最近写一块2.6"的TFT,几天过去了,还没初始化,

出0入0汤圆

 楼主| 发表于 2010-6-29 17:26:23 | 显示全部楼层
回复【88楼】AAVVRR  
一年了。很有用,适合于金鹏的12864ocmj4x8c,套用楼主程序,文字,图片都可以,就是画点是出现花屏,点已经画上去了就是花屏,不知什么原因。
-----------------------------------------------------------------------

估计是读屏幕数据时有问题

出0入0汤圆

发表于 2010-6-29 18:21:17 | 显示全部楼层
好像mark过
头像被屏蔽

出0入0汤圆

发表于 2010-7-6 15:47:32 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽

出0入0汤圆

发表于 2010-7-6 21:16:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-7-25 19:30:17 | 显示全部楼层
多谢 多谢!!

出0入0汤圆

发表于 2010-8-12 15:13:32 | 显示全部楼层
谢谢   我很汗  用了串行方式 难怪测试了这么多次 就是读不出来,还准备加上周立功的gui了,看来 要改改了

出0入0汤圆

发表于 2010-9-30 20:15:34 | 显示全部楼层
mark,谢谢了

出0入0汤圆

发表于 2010-9-30 23:13:20 | 显示全部楼层
收藏了,正想画圆呢。

出0入0汤圆

发表于 2010-10-9 21:58:19 | 显示全部楼层
很好 学习了...

出0入0汤圆

发表于 2010-10-11 21:12:47 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-13 14:06:11 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-11-13 18:02:49 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-11-17 22:23:13 | 显示全部楼层
请问楼主 怎么会出现这样的提示信息
Build started 17.11.2010 at 22:21:57
      0 [main] sh.exe" 3264 fork_copy: user/cygwin data pass 0 failed, 0x46F000..0x474434, done 1776, windows pid 2400, Win32 error 5
"D:/Program Files/WinAVR-20090313/utils/bin/sh.exe": fork: Resource temporarily unavailable
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex OM_test.elf OM_test.eep || exit 0
      0 [main] sh.exe" 1824 fork_copy: user/cygwin data pass 0 failed, 0x46F000..0x474434, done 1784, windows pid 3816, Win32 error 5
"D:/Program Files/WinAVR-20090313/utils/bin/sh.exe": fork: Resource temporarily unavailable
make: [OM_test.eep] Error 128 (ignored)
avr-objdump -h -S OM_test.elf > OM_test.lss
      0 [main] sh.exe" 1252 fork_copy: user/cygwin data pass 0 failed, 0x46F000..0x474434, done 1784, windows pid 1364, Win32 error 5
"D:/Program Files/WinAVR-20090313/utils/bin/sh.exe": fork: Resource temporarily unavailable
make: *** [OM_test.lss] Error 128
Build failed with 1 errors and 0 warnings...
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-10-3 01:30

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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