搜索
bottom↓
回复: 8

求救:AVR atmega16驱动M12864无字库液晶问题

[复制链接]

出0入0汤圆

发表于 2012-9-26 21:33:32 | 显示全部楼层 |阅读模式
我是用的单片机是ATmega16,驱动M12864无字库液晶,可以显示点,但是同一页同一列显示有问题,不能同时显示,感觉读液晶函数有问题,就是没有发现问题出在哪儿,求大侠帮忙看看,不胜感激。
程序如下:
#include <avr/io.h>
#include <util/delay.h>
//#include <avr/pgmspace.h>        //此连接为使用FLASH中的常量而设,
//#include "M12864.h"                        //如定义方式const prog_uchar tmpled[],读方式pgm_read_byte(tmpled+i)
#define RS_H                PORTB|=0X01                //p1.0=1 数据0000 0001
#define RS_L                PORTB&=0XFE                //p1.0=0 指令1111 1110
#define RW_H                PORTB|=0X02                //p1.1=1 读  0000 0010
#define RW_L                PORTB&=0XFD                //p1.1=0 写  1111 1101
#define EN_H                PORTB|=0X04                //p1.2=1 使能 0000 0100
#define EN_L                PORTB&=0XFB                //p1.2=0  1111 1011
#define CS1_H                PORTD|=0X40                //p3.6=0  0100 0000
#define CS1_L                PORTD&=0XBF                //p3.6=0  1011 1111
#define CS2_H                PORTD|=0X80                //p3.7=0  1000 0000
#define CS2_L                PORTD&=0X7F                //p3.7=0  0111 1111
//#define lcd_data        PORTC                        //输出数据的端口
//#define lcd_data_in        PINC                        //输入数据

#define Disp_on    0x3f           //开显示                                               
#define Disp_off   0x3e           //关显示
#define Col_add    0x40           //列起始地址
#define Page_add   0xb8           //页起始地址
#define Start_line 0xc0           //行起始地址

void write_com(unsigned char cmdcode);                //向LCD写命令
void write_data(unsigned char dispdata);        //向LCD写数据
char read_data(void);                                                //读LCD显示数据
void read_busy(void);                                                //读LCD忙函数
void clr_lcd();                                                                //清LCD
void disp_rgw(unsigned x,unsigned y,unsigned disy);//画点
void disp_frame();                                                        //画框架函数
//void disp_huadian(unsigned char x,unsigned char y);//画点函数
void init_lcd();                                                        //初始化LCD
//void disp_hz16(unsigned char pag,unsigned char col, unsigned char *hzk);          //行列显示汉字

void write_com(unsigned char cmdcode)                                 //写指令
  {
        RS_L;                  //di=0;
        RW_L;                  //rw=0;
        PORTC=cmdcode;
        EN_H;
        _delay_us(10);
        EN_L;                       
  }

void write_data(unsigned char dispdata)                                  //写数据
  {
        RS_H;                  //di=1;
        RW_L;                  //rw=0;
        PORTC=dispdata;
        EN_H;
        _delay_us(10);
        EN_L;               
  }
char read_data(void)                                                                //读数据
  {
    unsigned char dat=0;
        DDRC=0X00;
        PORTC=0X00;                        //带上拉电阻的输出
        _delay_us(10);
        read_busy();
        RS_H;                 
        RW_H;                 
        EN_H;
        dat=PINC;                       
        _delay_us(10);
        EN_L;
        DDRC=0XFF;
        return dat;
  }       
void read_busy(void)                                                                //读状态
  {
        unsigned char i=0;
        DDRC=0X00;
        PORTC=0X00;
        RS_H;                  //di=0;
        RW_H;                  //rw=0;
        EN_H;
        _delay_us(10);
        i=PINC;                        //读状态
        while(i&=0x80);
        EN_L;
        DDRC=0XFF;
  }
void disp_rgw(unsigned x,unsigned y,unsigned disy)//读显示数据,修改,写回函数;相当于画点函数
  {
        unsigned char temp=0 ,n;
        n=y;y/=8;n%=8;
       
        if(x<64)
          {
                CS1_H;CS2_L;       
          }
        else
          {
                x-=64;
                CS1_L;CS2_H;
          }

        write_com(Page_add+y);
        write_com(Col_add+x);
       
        temp=read_data();//空读
    temp=read_data();
    temp=read_data();
       
        switch(disy)
          {
                case 0: temp&=~_BV(n);break;//此点不显示
                case 1: temp|=_BV(n); break;//此点显示
                case 2: temp=~_BV(n);break;//此点反显
                default : break;
          }
        if(x<64)
          {
                CS1_H;CS2_L;       
        write_com(Page_add+y);
                write_com(Col_add+x);
                write_data(temp);
        //_delay_us(10);
          }
        else
          {
                x-=64;
                CS1_L;CS2_H;
                write_com(Page_add+y);
                write_com(Col_add+x);
                write_data(temp);
        //_delay_us(10);
          }
       
  }


void clr_lcd()                                                                                  //清屏函数
  {
        unsigned char j,k;
        CS1_H;CS2_H;                //cs1=1;cs2=1;
        write_com(Page_add+0);
        write_com(Col_add+0);
        for(k=0;k<8;k++)
          {
           write_com(Page_add+k);
           for(j=0;j<64;j++)
               write_data(0x00);
          }
  }

/*void disp_huadian(unsigned char x,unsigned char y)        //画点函数
  {
       
        unsigned char i=0x01,j=0,l=0;
        disp_frame();
        l=y;
        y=(y/8);
        if(x<64)
          {
                CS1_H;CS2_L;
                write_com(Page_add+y);
                write_com(Col_add+x);
                 //read_data();
                //j=read_data();
                //j=read_data();
               
                l%=8;
                i<<=l;
                //i |=j;
                write_data(i);
          }
        else
          {
                x-=64;
                CS1_L;CS2_H;
                write_com(Page_add+y);
                write_com(Col_add+x);
                 //read_data();
                //j=read_data();
                //j=read_data();
                l%=8;
                i<<=l;
                //i |=j;
                write_data(i);
               
          }       
  }
*/
void init_lcd()                                                                                   //显示初始化
  {
       
        DDRC=0XFF;
        DDRB|=0X07;
        DDRD|=0XC0;
       
        PORTC=0XFF;
        PORTB=0X07;
        PORTD=0XC0;
       
        CS1_H;CS2_H;
       
        write_com(Disp_off);
        write_com(Page_add);                //页起始地址
        write_com(Start_line);                //行起始地址
        write_com(Col_add);                        //列起始地址
        write_com(Disp_on);
  }

void disp_frame()                                                                        //显示框架
  {   
       
        unsigned char i;
        CS1_H;CS2_H;
       
        write_com(Page_add+0);                      //画横线
        write_com(Col_add+0);                                 
        for(i=0;i<64;i++) write_data(0x01);
       
        write_com(Page_add+7);
        write_com(Col_add+0);
        for(i=0;i<64;i++) write_data(0x80);
       
        for(i=0;i<8;i++)
          {
                CS1_H;CS2_L;                                          //画竖线
                write_com(Page_add+i);
                write_com(Col_add+0);
                write_data(0xff);
               
                CS1_L;CS2_H;
                write_com(Page_add+i);
                write_com(Col_add+63);
                write_data(0xff);
          }
  }



int main(void)                                                                                 //主程序
  {
        init_lcd();
        while(1)
          {       
                clr_lcd();
               
                disp_frame();
                _delay_ms(1000);
               
                disp_rgw(6,5,2);
                _delay_ms(1000);
               
               
               
                disp_rgw(6,6,2);
                _delay_ms(1000);
               
                disp_rgw(6,7,1);
                _delay_ms(1000);
               
               
               
                disp_rgw(12,12,1);
                _delay_ms(1000);
               
               
               
                disp_rgw(14,16,1);
                _delay_ms(1000);
               
                disp_rgw(16,18,1);
                _delay_ms(1000);
               
                disp_rgw(18,20,1);
                _delay_ms(1000);
               
                disp_rgw(20,22,1);
                _delay_ms(1000);
          }
  }

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

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2012-9-26 23:36:13 | 显示全部楼层
像是0108的驱动芯片,个人推荐程序中定义一个缓冲空间,与液晶的显存对应,不要使用读函数(用了显示太慢),在缓冲区中画点画图等等,然后把修改过的位置(应是0-8页,0-63列)写到对应位置

出0入0汤圆

 楼主| 发表于 2012-9-27 00:07:40 | 显示全部楼层
是两片0108的驱动芯片,我就是想学习一下,使用读函数的用法,结果是啥数据也没读出来,不知啥原因,不知道是不是程序的问题。

出0入0汤圆

发表于 2012-9-27 08:33:52 | 显示全部楼层
dpjaihaozhe 发表于 2012-9-27 00:07
是两片0108的驱动芯片,我就是想学习一下,使用读函数的用法,结果是啥数据也没读出来,不知啥原因,不知道 ...

如果学习一下读数据的话,我记得0108手册说像是要读两次

出0入0汤圆

 楼主| 发表于 2012-9-27 19:37:33 | 显示全部楼层
是的,需要读两次。我写的程序读了三次也没读出什么数据。
请问是什么原因呢?
是不是读函数有问题,请教。

出0入0汤圆

发表于 2012-9-27 20:25:08 | 显示全部楼层
这是我的读函数,ICC的,用的延时,测试的19264,12864都是可以的,液晶厂家不一样延时长不一样,需要你自己测试调整,你看看有没有用

unsigned char lcd_read_data(unsigned char x, unsigned char page)          /*  读显示数据 */
{
        unsigned char data;
       
        lcd_set_x(x);  
        lcd_set_page(page);
       
        CLEAR_LCD_E;
       
Delayus(2);       
       
        SET_LCD_DATA;
        SET_LCD_READ;

       
    LCD_DIR_PORT = 0x00;
    LCD_OP_PORT = 0xff;

       
        SET_LCD_E;
       
Delayus(2);
       
   data=LCD_IP_PORT;

Delayus(2);

    CLEAR_LCD_E;

Delayus(2);       
       
    SET_LCD_WRITE;
       
//第二次读

        SET_LCD_DATA;
    SET_LCD_READ;
       
    LCD_DIR_PORT = 0x00;
    LCD_OP_PORT = 0xff;
       
Delayus(2);

        SET_LCD_E;
       
Delayus(2);

   data=LCD_IP_PORT;
   
Delayus(2);
  
    CLEAR_LCD_E;
       
Delayus(2);
       
    SET_LCD_WRITE;


        return data;
       
}

出0入0汤圆

 楼主| 发表于 2012-9-27 23:14:01 | 显示全部楼层
首先,谢谢你的帮助,我在试试。

出0入0汤圆

 楼主| 发表于 2012-9-27 23:35:28 | 显示全部楼层
你发的程序我已经试过了,很好用,已经可以正常读取液晶的显示数据了,真的非常感谢。

出0入0汤圆

发表于 2013-12-9 21:43:46 | 显示全部楼层
收藏了,谢谢
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-7-23 23:40

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

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