liuhongyu 发表于 2010-6-22 22:07:58

请斑竹 傻孩子 帮忙看下这个12864的问题。先谢过。

程序下进mega16后没有显示只有背光,希望斑竹帮忙看下哪里出了问题。
在此先谢过。

电路
http://cache.amobbs.com/bbs_upload782111/files_30/ourdev_563268XBZAV7.JPG
(原文件名:JCM12864A.JPG)
//***********************************************************
//          文件名:12864.h
//          功能:完成LCD12864的驱动
//          描述: 根据12864与MCU的链接,只需更改LCD宏定义其他不用更改
//          使用:lcd_write_char(uchar x,uchar y,uchar n,uchar fb) 字符
//                  lcd_write_hz(uchar x,uchar y,uchar n,uchar fb)   汉字
//                  lcd_write_picture(uchar fb)                      图片
//          说明:读操作时,E=1 数据读到DB7--DB0
//                  写操作时,E下降沿 数据写到或DR
//          编写:柳宏宇
//          日期:2010.6.17
//***********************************************************
/*12864,mcu连接图:
数据线:
*D7   *D6   *D5   *D4   *D3   *D2   *D1   *D0
|   |      |    |   |   |   |   |
*PC7 *PC6*PC5   *PC4*PC3*PC2*PC1*PC0
控制线:
*DI   *RW    *EN    *CS1   *CS2   *RES
|   |      |      |       |   |         
*PA5*PA4   *PA3   *PA6   *PD7   *PD6
*/
//*************************LCD函数宏定义*********************
#define   lcd_di_0    (PORTA&=~(1<<5))
#define   lcd_di_1    (PORTA|=1<<5)
#define   lcd_rw_0    (PORTA&=~(1<<4))
#define   lcd_rw_1    (PORTA|=1<<4)
#define   lcd_en_0    (PORTA&=~(1<<3))
#define   lcd_en_1    (PORTA|=1<<3)
#define   lcd_cs1_0   (PORTA&=~(1<<6))
#define   lcd_cs1_1   (PORTA|=1<<6)
#define   lcd_cs2_0   (PORTD&=~(1<<7))
#define   lcd_cs2_1   (PORTD|=1<<7)
#define   lcd_rst_0   (PORTD&=~(1<<6))
#define   lcd_rst_1   (PORTD|=1<<6)
#define   data_port   PORTC
#define   data_pin    PINC
#define   data_ddr    DDRC
//***********************************************************
//                  函数名:delay_1us
//                  输入:无
//                  输出:无
//                  描述:1us延时
//***********************************************************
void delay_1us(void)//8M晶振下
{
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
    __no_operation();
}

//***********************************************************
//                  函数名:lcd_bussy
//                  输入:无
//                  输出:无
//                  描述:等待LCD空闲,LCD忙则死循环
//***********************************************************
void lcd_bussy(void)
{
    uchar val;
    lcd_di_0;
    delay_1us();
    lcd_rw_1;
    delay_1us();
    data_port = 0x00;
    while(1)
    {
      lcd_en_1;
      delay_1us();
      data_ddr = 0x00;
      delay_1us();
      val = data_pin;
      if(val < 0x80)break;
      lcd_en_0;
      delay_1us();
    }
    data_ddr = 0XFF;
    lcd_en_0;
    delay_1us();
}

//***********************************************************
//                  函数名:lcd_write_comand
//                  输入:cmd-向LCD写入的指令
//                  输出:无
//                  描述:LCD写指令
//***********************************************************
void lcd_write_comand(uchar cmd)
{
    lcd_cs1_1;
    delay_1us();
    lcd_cs2_1;
    delay_1us();
    lcd_bussy();
    lcd_di_0;
    delay_1us();
    lcd_rw_0;
    delay_1us();
    data_port = cmd;
    delay_1us();
    lcd_en_1;
    delay_1us();
    lcd_en_0;
    delay_1us();
}

//***********************************************************
//                  函数名:lcd_set_onoff
//                  输入:onoff,=1开显示;=0关显示
//                  输出:无
//                  描述:LCD开关显示
//***********************************************************
void lcd_set_onoff(uchar onoff)
{
   uchar dis_onoff;
   dis_onoff = onoff + 0x3E;
   lcd_write_comand(dis_onoff);
}

//***********************************************************
//                  函数名:lcd_set_startline
//                  输入:startlin起始行号,范围:【0-64】
//                  输出:无
//                  描述:设置起始行
//***********************************************************
void lcd_set_startline(uchar startline)
{
    uchar startlinecmd;
    startlinecmd = startline + 0xC0;
    lcd_write_comand(startlinecmd);
}

//***********************************************************
//                  函数名:lcd_set_x
//                  输入:x-页地址,范围【0-7】
//                  输出:无
//                  描述:设置显示页地址
//***********************************************************
void lcd_set_x(uchar x)
{
    uchar page;
    page = x + 0xB8;
    lcd_write_comand(page);
}

//***********************************************************
//                  函数名:lcd_set_y
//                  输入:y-列地址,范围【0-63】
//                  输出:无
//                  描述:设置显示列地址
//***********************************************************
void lcd_set_y(uchar y)
{
    uchar row;
    row = y + 0x40;
    lcd_write_comand(row);
}

//***********************************************************
//                  函数名:lcd_writebyte
//                  输入:dat-显示数据
//                  输出:无
//                  描述:向LCD的DDRAM写显示数据
//***********************************************************
void lcd_writebyte(uchar dat)
{
    lcd_bussy();
    lcd_di_1;
    delay_1us();
    lcd_rw_0;
    delay_1us();
    data_port = dat;
    delay_1us();
    lcd_en_1;
    delay_1us();
    lcd_en_0;
    delay_1us();
}

//***********************************************************
//                  函数名:lcd_clear_line
//                  输入:startline【0-7】,endline【0-7】
//                        -清除显示起始页和结束页
//                  输出:无
//                  描述:清除指定页显示内容
//***********************************************************
void lcd_clear_line(uchar startline,uchar endline)
{
    uchar i,j;
    lcd_cs1_1;
    delay_1us();
    lcd_cs2_1;
    delay_1us();
    for(i=startline;i<=endline;i++)
    {
      lcd_set_x(i);
      lcd_set_y(0);
      for(j=0;j<64;j++)
      {
            lcd_writebyte(0x00);//y自增功能
      }
    }
}

//***********************************************************
//                  函数名:lcd_write_dat
//                  输入:x-写入数据页号,范围【0-7】
//                        y-写入数据列号,范围【0-127】
//                        dat需写入的数据
//                  输出:无
//                  描述:LCD指定位置写入一个数据
//***********************************************************
void lcd_write_dat(uchar x,uchar y,uchar dat)
{
    if(y<64)
    {
         lcd_cs1_1;
         delay_1us();
         lcd_cs2_0;
         delay_1us();
         lcd_set_x(x);
         lcd_set_y(y);
    }
    else
    {
         lcd_cs1_0;
         delay_1us();
         lcd_cs2_1;
         delay_1us();
         lcd_set_x(x);
         lcd_set_y(y-64);
    }
    lcd_writebyte(dat);
}

//***********************************************************
//                  函数名:lcd_write_char
//                  输入:x范围【0-3】,y范围【0-15】,
//                        n 为字符阵码中第n个字符
//                  输出:无
//                  描述:LCD指定单元写入一个字符,是个显示
//                        单元默认为16*8点阵字体,对于12864
//                        X最多显示4行,y最多显示16个字符
//                        采用逐列显示。
//***********************************************************
void lcd_write_char(uchar x,uchar y,uchar n,uchar fb)
{
    uchar i;
    uchar x_address;
    uchar y_address;
    uchar dx;
    if((x<4)&&(y<16))
    {
      x_address = x<<1;//转换成页号
      for(i=0;i<8;i++)
      {
            y_address = (y<<3)+i;//转换成列号
            dx = string[(2*i)+(16*n)];
            if(fb == 1)dx =~dx;
            lcd_write_dat(x_address,y_address,dx);
            dx = string[(2*i)+1+(16*n)];
            if(fb == 1)dx =~dx;
            lcd_write_dat(x_address+1,y_address,dx);
      }

    }
}

//***********************************************************
//                  函数名:lcd_write_hz
//                  输入:x范围【0-3】,y范围【0-14】,显示字符
//                        模组首址,char需写入的数据
//                  输出:无
//                  描述:LCD指定单元写入一个字符,是个显示
//                        单元默认为16*16点阵字体,对于12864
//                        X最多显示4行,y最多显示8个汉字,但不
//                        允许显示半个汉字故y范围为【0-14】
//                        采用逐列显示。
//***********************************************************
void lcd_write_hz(uchar x,uchar y,uchar n,uchar fb)
{
    uchar i;
    uchar x_address;
    uchar y_address;
    uchar dx;
    if((x<4)&&(y<15))
    {
      x_address = x<<1;    //转换成页号
      for(i=0;i<16;i++)
      {
            y_address = (y<<3)+i;//转换成列号
            dx = hz[(2*i)+(32*n)];
            if(fb == 1)dx =~dx;
            lcd_write_dat(x_address,y_address,dx);
            dx = hz[(2*i)+1+(32*n)];
            if(fb == 1)dx =~dx;
            lcd_write_dat(x_address+1,y_address,dx);
      }

    }
}

//***********************************************************
//                  函数名:lcd_write_picture
//                  输入:x范围【0-7】,y范围【0-127】显示起点
//                        x_length纵向像素必须为8的整数倍
//                        y_length横向像素不必是8个整数倍
//                  输出:无
//                  描述:lcd在指定区域显示指定像素的图片
//***********************************************************
void lcd_write_picture(uchar fb)
{
    uchar x_address;//页
    uchar y_address;//列
    uchar dx;
    for(x_address=0;x_address<8;x_address++)   //页循环
    {
      for(y_address=0;y_address<128;y_address++)       //列循环
      {
            dx = picture[(x_address*128)+y_address];
            if(fb == 1)dx = ~dx;
            lcd_write_dat(x_address,y_address,dx);
      }
    }
}

//***********************************************************
//                  函数名:lcd_int
//                  输入:无
//                  输出:无
//                  描述:初始化LCD
//***********************************************************
void lcd_int(void)
{
    lcd_rst_0;
    delay_ms(10);
    lcd_rst_1;
    delay_ms(10);
    lcd_set_startline(0);//设置起始行
    lcd_set_onoff(0);   //关显示
    lcd_clear_line(0,7);//清屏
    lcd_set_onoff(1);   //开显示
    delay_ms(10);
    lcd_set_onoff(1);   //开显示
    delay_ms(10);
}

//**********************OVER******************************



主程序:
int main()
{
````
lcd_int();
lcd_write_hz(0,4,0,0);   //汉字
lcd_write_hz(1,4,1,0);
lcd_write_hz(2,4,2,0);
lcd_write_hz(3,4,3,0);
while(1);
````
}

程序下进mega16后没有显示只有背光,希望斑竹帮忙看下哪里出了问题。
在此先谢过。

Gorgon_Meducer 发表于 2010-6-23 13:01:32

很长时间没有接触了……不好意思……而且手边也没有硬件……

liuhongyu 发表于 2010-6-23 18:04:14

回复【1楼】Gorgon Meducer 傻孩子
-----------------------------------------------------------------------

在这先感谢斑竹了~~,问题今天已找到~~~开关电源功率不够以前数显表的电源功率太小~~~~把背光打开后LCD电流50mA(以前以为LCD省电,原来也那么费,可能是这家的LCD不好吧),换了个大功率电源就可以了~~当然这个程序也有问题,没分左右屏。呵呵~

Gorgon_Meducer 发表于 2010-6-24 12:44:14

to 【2楼】 liuhongyu 柳宏宇
    您的编码风格不错,赞一个~

wangshaosh 发表于 2010-6-26 13:19:42

最好用串行方式,电路简单~~~少用8个引脚~~
页: [1]
查看完整版本: 请斑竹 傻孩子 帮忙看下这个12864的问题。先谢过。