打印

请教控制芯片为T6963C的128*64的液晶驱动程序

[复制链接]
3270|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
hlhfootbal|  楼主 | 2008-11-29 11:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这几天在调试控制芯片为T6963C的128*64的液晶,不过没什么进展。液晶亮都没亮。

驱动程序如下,请各位不啬赐教。
#include <mega16.h>
#include <delay.h>

#define WR PORTA.0
#define RD PORTA.1
#define CE PORTA.2
#define C_D PORTA.3

void init_io()
{
  DDRA=0XFF;//porta is output 
  CE=0;
  DDRC=0XFF;//portc is output
  PORTC=0XFF;
}

void Re_Sta(unsigned char mark)
{
  bit exit=0;
  unsigned char state;
  
  C_D=1;
  RD=1;
  WR=1;
  while(1)
  {
  RD=0;
  state=PINC;
  RD=1;
  switch(mark)
  {
    case 1:if(state&0x03)exit=1;break;/*check commad execution capability or check data read/write capability*/
    case 2:if(state&0x04)exit=1;break;/*check auto mode data read capability*/
    case 3:if(state&0x08)exit=1;break;/*check auto mode data write capability*/
    case 4:if(state&0x40)exit=1;break;/*error flag;used for screen peek and screen copy commads*/
    default:break; 
  }
  if(exit==1)
    break;
  }
}

void send_data(unsigned char dat)
{
  C_D=0;
  PORTC=dat;
  WR=0;
  WR=1;
}

void send_com(unsigned char com)
{
 PORTC=com;
 WR=0;
 WR=1; 
}

void send_d_c(unsigned char sta_sty, unsigned char dat_num,unsigned char dat1,unsigned char dat2,unsigned char com)
{
  if(dat_num)
  {
    Re_Sta(1);
    send_data(dat1);
    if(dat_num==2)
    Re_Sta(1);
    send_data(dat2);
  }                 
  switch(sta_sty)
  {
    case 1:Re_Sta(1);send_com(com);break;
    case 2:Re_Sta(2);send_com(com);break;
    case 3:Re_Sta(3);send_com(com);break;
    case 4:Re_Sta(4);send_com(com);break;
    default:break;
  }
}

void init_lcd(void)
{
  send_d_c(1,2,0x00,0x00,0x21);//set the position of curser
  send_d_c(1,2,0x00,0x00,0x40);//set text home address
  send_d_c(1,2,0X20,0X00,0X41);//set text area
  send_d_c(1,2,0X00,0X80,0X42);//set graphic home address
  send_d_c(1,2,0X20,0X00,0X43);//set graphic area 
  send_d_c(1,0,0x00,0x00,0x80);//set the logic of display,internal character generator mode
  send_d_c(1,0,0x00,0x00,0x9f);//text on,graphic on,cursor on,blink on
  send_d_c(1,0,0x00,0x00,0xaf);//8-line cursor
}

void clear_lcd(void)
{
  unsigned char i,j;
  
  send_d_c(1,2,0X00,0X00,0X24);//set address pointer
  send_d_c(1,0,0x00,0x00,0xb0);//set auto write mode
    for(i=0;i<205;i++)
  {
    for(j=0;j<=40;j++)
    {
     Re_Sta(3);
     C_D=0;
     PORTC=0X00;
     WR=0;
     WR=1; 
    }
  }
  send_d_c(3,0,0x00,0x00,0xb2);//set auto reset
}

main()
{
  delay_ms(200);
  init_io();
  init_lcd();
  //clear_lcd(); 
}

相关帖子

沙发
fangui| | 2008-12-1 21:27 | 只看该作者

我用过

使用特权

评论回复
板凳
hlhfootbal|  楼主 | 2008-12-2 21:16 | 只看该作者

楼上能提供调试通过的程序给我吗?

谢谢!

使用特权

评论回复
地板
keyanfeng| | 2008-12-2 22:23 | 只看该作者

LPC2131的

LPC2131的.


// T6963C.c

#include "T6963.h"

// 软件延时函数。用于LCM显示输出时序控制
// 输入: 无
// 输出: 无
void DELAY5(void)

    int i;
//    for(i=0; i<100; i++);
    for(i=0; i<10; i++);
}


// 读状态位子程序
// 输入: read_bit (0~7)
// 输出: bit(0:disable/no error/display off; 1: enable/error/normal display)
unsigned char LCMReadStatus(unsigned char read_bit)
{
    unsigned char status_rd;
    SET_LCM_CD();
    CLR_LCM_RD();
    LCM_BUS_DIR_IN();
    DELAY5();
    status_rd = LCM_InData();            // LCM data bus
    DELAY5();
    LCM_BUS_DIR_OUT();
    SET_LCM_RD();
    if(status_rd & (1 << read_bit))
        return 1;
    else
        return 0;
}

// 写指令和写数据子程序
// 输入: dat_num:参数数目; dat[2]:参数; cmd_code:命令代码
// 输出: 无
void LCMWriteCmd(unsigned char dat_num,unsigned char dat[2],unsigned char cmd_code)
{
    unsigned char i;
    for(i=0; i<dat_num; i++)
    {
        while(LCMReadStatus(0) == 0);    // 检查命令执行使能
        while(LCMReadStatus(1) == 0);    // 检查数据读写使能
        CLR_LCM_CD();                    // CD=0,写数据
        DELAY5();
        LCM_OutData(dat);            // 写入数据
        CLR_LCM_WR();
        DELAY5();
        SET_LCM_WR();
    }
    while(LCMReadStatus(0) == 0);        // 检查命令执行使能
    while(LCMReadStatus(1) == 0);        // 检查数据读写使能        
    SET_LCM_CD();
    DELAY5();
    LCM_OutData(cmd_code);                // 写入命令代码
    CLR_LCM_WR();
    DELAY5();
    SET_LCM_WR();
}

// 写数据子程序
// 输入: dat:写入数据
// 输出: 无
void LCMWriteDat(unsigned char dat)
{
    CLR_LCM_CD();                        // CD=0,写数据
    DELAY5();
    LCM_OutData(dat);                    // 写入数据
    CLR_LCM_WR();
    DELAY5();
    SET_LCM_WR();
}

// 读数据子程序
// 输入: 无
// 输出: dat_read: 读入的8位数据
unsigned char LCMReadDat(void)
{
    unsigned char dat_read;
    while(LCMReadStatus(0) == 0);
    while(LCMReadStatus(1) == 0);
    CLR_LCM_CD();
    CLR_LCM_RD();
    LCM_BUS_DIR_IN();
    DELAY5();
    dat_read = LCM_InData();            // 读入数据保存在dat_read
    DELAY5();
    LCM_BUS_DIR_OUT();
    SET_LCM_RD();
    return dat_read;
}

// 初始化设置子程序
void LCMInit(void)
{
    unsigned char dat[2];
    LCM_CC_DIR();
    LCM_BUS_DIR_OUT();
    LCM_RESET_L();
    DELAY5();
    DELAY5();
    DELAY5();
    DELAY5();
    DELAY5();
    LCM_RESET_H();
    CLR_LCM_CS();
    
    
    dat[0] = 0x00;                        // 显示首址为0
    dat[1] = 0x00;
    LCMWriteCmd(2,dat,0x42);            // 设置图形显示区域首址
    dat[0] = 0x10;                        // 16*8 = 128 bit
    dat[1] = 0x00;
    LCMWriteCmd(2,dat,0x43);            // 设置图形显示区域宽度
    
/*
    dat[0] = 0x00;
    dat[1] = 0x10;
    LCMWriteCmd(2,dat,0x40);            // 设置文本显示区域首址
    dat[0] = 0x10;
    dat[1] = 0x00;
    LCMWriteCmd(2,dat,0x41);            // 设置文本显示区域

    dat[0] = 0x00;
    dat[1] = 0x00;
    LCMWriteCmd(2,dat,0x21);            // 设置光标指针

*/
    dat[0] = 0x00;
    dat[1] = 0x00;
    LCMWriteCmd(2,dat,0x22);            // 设置移位寄存器
    dat[0] = 0x00;
    dat[1] = 0x00;
    LCMWriteCmd(2,dat,0x24);            // 设置地址指针
    
/*
    LCMWriteCmd(0,dat,0x92);            // 设置闪烁关,光标开
    LCMWriteCmd(0,dat,0xa7);            // 光标形状设置
    LCMWriteCmd(0,dat,0x80);            // 显示方式设置 内部CGROM
    LCMWriteCmd(0,dat,0x9c);            // 显示开关设置 开文本和图形显示
*/
    LCMWriteCmd(0,dat,0x88);            // 显示方式设置,外部CGRAM
    LCMWriteCmd(0,dat,0x98);            // 显示开关设置 开图形显示,关文本显示

}

// LCM显示储存区清0
void LCMClear(void)
{
    unsigned int i;
    unsigned char dat[2];
    dat[0] = 0x00;
    dat[1] = 0x00;
    LCMWriteCmd(2,dat,0x24);            // 设置显示储存器首址
    LCMWriteCmd(0,dat,0xb0);            // 设置自动写方式
    for(i=0x2000; i>0; i--)
    {
        while(LCMReadStatus(3) == 0);    // 检查自动写方式使能
        LCMWriteDat(0);
    }
    LCMWriteCmd(0,dat,0xb2);
}

// 在指定的位置上画点
// 输入: 位置坐标(x,y), 颜色color(1为亮,0为灭)
// 输出: 
void GUIPoint(uint8 x,uint8 y,uint8 color)
{
    uint8 dat[2];                // LCM写入参数
    uint32 temp;
    
    // LCM的左下角为坐标原点(0,0),显示时假设LCM的左上角为坐标原点,故要进行坐标转换
    // y = LCM_Y_MAX - y;            // 坐标转换
    
    temp = (y * LCM_X_MAX + x)/8;        // 计算显示地址指针
    dat[0] = (uint8)(temp % 256);
    dat[1] = (uint8)(temp / 256);
    LCMWriteCmd(2,dat,0x24);            // 设置地址指针
    
    LCMWriteCmd(0,dat,0xc5);            // 读入显示RAM的数据
    dat[0] = LCMReadDat();
    if(color)                            // 修改显示RAM的数据
        dat[0] = dat[0] | (0x01 << (7 - x%8));        // 1 -> dat[0].(7-x%8)
    else
        dat[0] = dat[0] & (~(0x01 << (7 - x%8)));    // 0 -> dat[0].(7-x%8)
    LCMWriteCmd(1,dat,0xc4);            // 更新显示数据
}

// T6963.h
#include "config.h"
#ifndef __T6963_H 
#define __T6963_H

#define LCM_X_MAX    128
#define    LCM_Y_MAX    128

/* 定义LCM与MCU接口的引脚 */
#define    LCM_RST    1 << 17
#define    LCM_WR  1 << 18
#define    LCM_RD    1 << 19
#define    LCM_CS    1 << 20
#define    LCM_CD    1 << 21
#define    LCM_DAT    (0xff << 18)

/* 定义 LCM复位 */
#define    LCM_RESET_H()    IO0SET = LCM_RST
#define    LCM_RESET_L()    IO0CLR = LCM_RST

/* 定义 LCM接口的IO引脚方向 */
#define    LCM_CC_DIR()    IO0DIR = IO0DIR | (LCM_WR | LCM_RD | LCM_CS | LCM_CD | LCM_RST)
#define LCM_BUS_DIR_IN()    IO1DIR = IO1DIR & (~LCM_DAT)
#define    LCM_BUS_DIR_OUT()    IO1DIR = IO1DIR | LCM_DAT

/* 定义LCM数据总线起始的GPIO,即D0对应的GPIO值(P1.18) */
#define  LCM_BUS    18
/* LCM输出总线数据宏定义 */
#define    LCM_OutData(dat)    IO1CLR = 0xff << LCM_BUS;    IO1SET = (dat&0xff) << LCM_BUS
/* LCM读入总线数据宏定义 */
#define    LCM_InData()    (unsigned char)((IO1PIN & LCM_DAT) >> LCM_BUS)

/* 定义控制信号线电平信号 */
#define    SET_LCM_CS()    IO0SET = LCM_CS
#define CLR_LCM_CS()    IO0CLR = LCM_CS
#define    SET_LCM_CD()    IO0SET = LCM_CD
#define    CLR_LCM_CD()    IO0CLR = LCM_CD
#define    SET_LCM_RD()    IO0SET = LCM_RD
#define    CLR_LCM_RD()    IO0CLR = LCM_RD
#define    SET_LCM_WR()    IO0SET = LCM_WR
#define    CLR_LCM_WR()    IO0CLR = LCM_WR

/* 定义外部函数 */
extern    unsigned char LCMReadStatus(unsigned char read_bit);
extern    void LCMWriteCmd(unsigned char dat_num,unsigned char dat[2],unsigned char cmd_code);
extern    void LCMWriteDat(unsigned char dat);
extern    unsigned char LCMReadDat(void);
extern    void LCMInit(void);
extern    void LCMClear(void);
extern    void GUIPoint(uint8 x,uint8 y,uint8 color);

#endif

使用特权

评论回复
5
hlhfootbal|  楼主 | 2008-12-2 22:48 | 只看该作者

DELAY()

请问这个函数延时多长时间?如果没有延时函数会不会影响数据的读写?

使用特权

评论回复
6
hlhfootbal|  楼主 | 2008-12-2 22:51 | 只看该作者

0x2000是怎么来的?

for(i=0x2000; i>0; i--)
    {
        while(LCMReadStatus(3) == 0);    // 检查自动写方式使能
        LCMWriteDat(0);
    }
请问你写的次程序是用在多大的屏上的?0x2000是怎么来的?

使用特权

评论回复
7
keyanfeng| | 2008-12-2 23:06 | 只看该作者

这个好久以前写的

DELAY(),
如果是51,随便插一两个nop就行了,
你没看见我用的是ARM7吗,所以调用了一个delay函数。

我的屏是128*128,
为什么是2000,
得看你的LCM的资料吧。
这个是好久以前的,
我自己都忘记了。

使用特权

评论回复
8
keyanfeng| | 2008-12-2 23:30 | 只看该作者

0x2000指8K显示RAM

楼主可以看这个资料,
http://www.syntoplcd.com/CONPDF/T6963C.pdf

使用特权

评论回复
9
hlhfootbal|  楼主 | 2008-12-3 10:32 | 只看该作者

读不懂GUIPoint()函数

1、uint8是不是unsigned int?
2、temp = (y * LCM_X_MAX + x)/8; 为什么要除以8?你的液晶是否设置成8*8的显示方式?
3、dat[0] = (uint8)(temp % 256);
   dat[1] = (uint8)(temp / 256);看不懂。
4、 LCMWriteCmd(0,dat,0xc5);            // 读入显示RAM的数据
    这个指令是做什么用的?如果是想令液晶显示数据的话,应该用0xc4指令吧?
5、dat[0] = LCMReadDat();
    if(color)                            // 修改显示RAM的数据
        dat[0] = dat[0] | (0x01 << (7 - x%8));        // 1 -> dat[0].(7-x%8)
    else
        dat[0] = dat[0] & (~(0x01 << (7 - x%8)));    // 0 -> dat[0].(7-x%8)
    LCMWriteCmd(1,dat,0xc4);            // 更新显示数据
 dat[0] = dat[0] | (0x01 << (7 - x%8));这个语句看部懂。

谢谢解答!


使用特权

评论回复
10
hlhfootbal|  楼主 | 2008-12-4 15:18 | 只看该作者

自己顶下!

使用特权

评论回复
11
hlhfootbal|  楼主 | 2008-12-4 18:29 | 只看该作者

今天我用示波器挂了下波形

今天我用示波器挂了下波形发现只有RD控制信号起作用。PORTC口只有PORTC.7和PORTC.2有波形,这波形也不正常,是锯齿波,幅度只有3.3V。PORTC.6低电平,PORTC.5高电平,PORTC.4低电平,PORTC.3高电平,PORTC.1高电平,PORTC.0高电平。
根据以上的现象,我推测Re_Sta()有问题,没有读到正确的状态。Re_Sta()函数如下。各位帮我看看有什么问题,具体程序在最上面。谢谢!
void Re_Sta(unsigned char mark)
{
  bit exit=0;
  unsigned char state;
  
  DDRC=0X00;//portc is input
  while(1)
  {
  RD=0;
  //nop
  //nop
  state=PINC;
  //_NOP();
  //_NOP();
  RD=1;
  switch(mark)
  {
    case 1:if(state&0x03)exit=1;break;/*check commad execution capability or check data read/write capability*/
    case 2:if(state&0x04)exit=1;break;/*check auto mode data read capability*/
    case 3:if(state&0x08)exit=1;break;/*check auto mode data write capability*/
    case 4:if(state&0x40)exit=1;break;/*error flag;used for screen peek and screen copy commads*/
    default:break; 
  }
  if(exit==1)
    break;
  }  
  DDRC=0XFF;//PORTC IS OUTPUT
}

使用特权

评论回复
12
yjs1314| | 2008-12-22 14:54 | 只看该作者

根据LCD的时序,先确定硬件有没有问题?

根据LCD的时序,先确定硬件有没有问题? WR RD CD和CS高低状态是否确定,另外LCD的数据口,在操作的时候要注意输入输出方向的变化。这个芯片我用在240128上面,先后在C8051和AVR上面都移植过,很方便就显示起来了!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

133

主题

417

帖子

1

粉丝