xou822 发表于 2013-8-17 23:49:17

求助: 12864 ST7920 并口驱动的问题

大家好
我从淘宝买了一块ST7920驱动芯片的12864液晶屏
想要驱动它通过画图的方式显示数字和图像。于是按照手册写了一个程序,从串口接收数据,保存到STC12C5A60S2的一个1024byte的缓冲区内,然后主程序循环把缓冲区内的信息从左上角的位置顺序写入屏幕的GDRAM,写入期间关闭了显示
程序如下,但是无论如何都无法正确显示,求高人指点

#include "STC/STC12C5A60S2.h"
#include "intrins.h"
typedef unsigned char uchar;
typedef unsigned int uint;
sbit RS = P0^5 ;
sbit RW = P0^6 ;
sbit EN = P0^7 ;
#define DATA P2

bit flag=0;                                          //用来指示是否收到中断

uchar tmp;                                 //用来缓存中断收到的内容
uint cachecount=0;                //用来存储缓存位
uchar xdata cache;//用来保存串口收到的信息

void Checkbusy( void )      //忙检测函数
{
unsigned int timeout = 0 ;
RS = 0;
RW = 1;
EN = 0;
EN = 1;
while( ( DATA & 0x80 ) && ( ++timeout != 0 ) ) ;         //循环256次
EN = 0;
RS = 0;
RW = 1;
}

void Sendcmd( unsigned char cmd )   //发送命令
{
Checkbusy() ;
RS = 0;
RW = 1;
EN = 0;
DATA = cmd ;
_nop_();
_nop_();
EN = 1;   
_nop_();
_nop_();
EN = 0;
RW = 1;
RS = 0;
}

void Senddata( uchar value ) //发送数据
{
Checkbusy() ;
RS = 1;
RW = 0;
EN = 0;
DATA = value ;
_nop_();
_nop_();
EN = 1;   
_nop_();
_nop_();
EN = 0;
RW = 1;
RS = 0;
}

void Delayms( unsigned int ms )      //延时
{
uint i ;
for( ; ms > 0 ; ms-- )
{
   for( i = 125 ; i > 0 ; i-- ) ;
}
}

void lcdinit()            //初始化
{
Sendcmd( 0x30 ) ;       //基本指令集
Delayms( 50 ) ;
Sendcmd( 0x01 ) ;       //清屏
Delayms( 50 ) ;
Sendcmd( 0x06 ) ;       //光标右移
Delayms( 50 ) ;

Sendcmd( 0x34 ) ;           //扩展指令
Delayms( 50 ) ;
Sendcmd( 0x34 ) ;           //扩展指令
Delayms( 50 ) ;
Sendcmd( 0x36 ) ;           //开绘图
Delayms( 50 ) ;
   
Sendcmd( 0x0c ) ;       //开显示
}
void SetGD( unsigned char vertical, horizontal )   //地址转换
{
Sendcmd( vertical ) ;
Sendcmd( horizontal ) ;
}

void Putstring( unsigned char x, unsigned char y, unsigned char *pData )
{
SetGD( x, y ) ;
while( *pData != '\0' )
{
Senddata( *pData++ ) ;
}      
}

void UartInit(void)                //115200bps@11.0592MHz
{
        PCON &= 0x7F;                //波特率不倍速
        SCON = 0x50;                //8位数据,可变波特率
        AUXR |= 0x40;                //定时器1时钟为Fosc,即1T
        AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
        TMOD &= 0x0F;                //清除定时器1模式位
        TMOD |= 0x20;                //设定定时器1为8位自动重装方式
        TL1 = 0xFD;                //设定定时初值
        TH1 = 0xFD;                //设定定时器重装值
        ET1 = 0;                //禁止定时器1中断
        TR1 = 1;                //启动定时器1
}

void UART_SER(void) interrupt 4 //串口中断
{       flag=1;
   if(RI)                      //判断是否是接收中断
   {
      tmp= SBUF;               //保存中断的值
      RI=0;                      //标志位清零

          cache=tmp;
          cachecount++;
          if(cachecount>1023)
          cachecount=0;
       }
          if(TI)                                       //如果是串口标志志位,直接清零
   {
       TI=0;
       }
}

void main( void )
{
uchar i,j,k;
k=0;

lcdinit() ;
UartInit();//开始串口

Delayms( 50 ) ;

SetGD(0x80,0x80);

EA=1;
ES=1;
Sendcmd( 0x01 ) ;       //清屏

while( 1 )
{

if (flag==1)
{
k=0;
SetGD(0x80,0x80); //AC指向原点
Senddata(0x8);                  //关显示
for (i=0;i<64;i++)
        {
        SetGD((0x80+i),0x80);//先设vertical地址,每次不同,horizon地址次次为0
                for(j=0;j<16;j++)
                {

                Senddata(cache);

                k++;
                }
        }
                Senddata(0xC);                  //开显示

}

}          
}

xou822 发表于 2013-8-17 23:51:37

论坛里面用12864的很多但是很少有用51驱动,并且用并口的可以参考的驱动12864的文章

如果有高人指教 真的很感谢啊

这两天被这个弄得好郁闷哦

ccstc 发表于 2013-8-17 23:54:32

没时间慢慢帮你看代码
给你两个建议:
1、调代码前调对比度到所有点过驱动(黄绿屏调绿,灰屏调黑,蓝白屏调白);
2、使用逻辑分析仪或万用表在程序中设置合理断点来检查时序是否满足Datasheet;

xou822 发表于 2013-8-17 23:58:59

感谢楼上的回帖

我感觉是驱动地址设置的问题   

又没办法做proteus仿真   你说得逻辑分析仪哪儿可以买得到啊

lxa0 发表于 2013-8-18 00:56:08

显示数字的话
你直接用常规方法就可以
显示图像比较麻烦
典型的做法是:
先把图像变换成点阵数据
然后按典型方法编写程序
就可以显示出来

xou822 发表于 2013-8-18 10:04:17

回楼上的   我就是想要用绘图的方法

常规的很简单 但是没法显示自己想要的东西
页: [1]
查看完整版本: 求助: 12864 ST7920 并口驱动的问题