打印

12864 刷新会闪烁,我加了1S的延时还是会闪烁

[复制链接]
4768|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
肥羊|  楼主 | 2017-11-28 09:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
pi, gp, GPIO, IO, ST
下面是我的代码请大神看看void LCD12864_Data_State(GPIOMode_TypeDef state)
{

        u8 i=0;
        GPIO_InitTypeDef GPIO_InitStructure;
       
        GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable , ENABLE);

        //--------------------------------------------------------------------------------
        //LCD-GPIO 口配置(数据接口)
        for(i=0;i<8;i++)
        {
       GPIO_InitStructure.GPIO_Pin  = LCD_DATA_Pin[i].Pin_No;                //数据口配置成开漏输出模式,此模式下读输入寄存器的值得到IO口状态
           GPIO_InitStructure.GPIO_Mode = state;           //开漏输出
           GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  
           GPIO_Init(LCD_DATA_Pin[i].IoPort , &GPIO_InitStructure);    //IO口初始化函数(使能上述配置)
        }

}


void LCD_WriteData(u8 dat)
{
    u8 i;
        LCD12864_Data_State(GPIO_Mode_Out_PP);

        for(i=0;i<8;i++)
        {
      if(dat&0x80)
      {
           GPIO_SetBits(LCD_DATA_Pin[i].IoPort,LCD_DATA_Pin[i].Pin_No);
          }else
          {
           GPIO_ResetBits(LCD_DATA_Pin[i].IoPort,LCD_DATA_Pin[i].Pin_No);
          }
          dat=dat<<1;
        }
       
}       


/*
4
D/I(RS)
H/L
D/I=“H”,表示DB7∽DB0为显示数据
D/I=“L”,表示DB7∽DB0为显示指令数据
5
R/W
H/L
R/W=“H”,E=“H”数据被读到DB7∽DB0
R/W=“L”,E=“H→L”数据被写到IR或DR
6
E
H/L
R/W=“L”,E信号下降沿锁存DB7∽DB0
R/W=“H”,E=“H”DDRAM数据读到DB7∽DB0
*/


void WaitBusy(void)          //等待12864的忙状态结束的函数。
{
     //把所有引脚定义为输出。
        u8 lcdtemp = 0;
        u16 timecnt;
        LCD12864_Data_State(GPIO_Mode_IN_FLOATING);
    LCD_DI_L();
    LCD_RW_H();
    LCD_EN_H();
        timecnt=0;
    do                       //判忙
    {   
        LCD_EN_H();                                       
               lcdtemp = GPIO_ReadInputDataBit(LCD_DATA_Pin[0].IoPort,LCD_DATA_Pin[0].Pin_No);
                //delay_us(1);       
               LCD_EN_L();
        timecnt++;
    }
        while(lcdtemp==1);//这里以后要加上超时操作
    LCD_EN_L();
        LCD12864_Data_State(GPIO_Mode_Out_PP);
}


/*******************************************
函数名称:Write_Cmd
功    能:向液晶中写控制命令
参    数:cmd--控制命令
返回值  :无
********************************************/
void Write_Cmd(u8 cmd)
{

    WaitBusy();   

        LCD_RW_L();
        LCD_EN_H();
    LCD_DI_L();

        LCD_WriteData(cmd);
        delay_us(20);                                                                         
    LCD_EN_L();
        delay_us(1);
}
/*******************************************
函数名称:Write_Data
功    能:向液晶中写显示数据
参    数:dat--显示数据
返回值  :无
********************************************/
void  Write_Data(u8 dat)
{   
    WaitBusy();  
       
    LCD_DI_H();
    LCD_RW_L();
    LCD_EN_H();
        LCD_WriteData(dat);
       
        delay_us(20);
    LCD_EN_L();
}  



/*******************************************
函数名称:Ini_Lcd
功    能:初始化液晶模块
参    数:无
返回值  :无
********************************************/
void Ini_Lcd(void)
{                  
    LCD12864_Data_State(GPIO_Mode_Out_PP); //液晶控制端口设置为输出
    LCD_CSA_H();

    //复位
        LCD_RS_L() ;
        delay_ms(20);
        LCD_RS_H();
       
   // Delay_Nms(500);
    Write_Cmd(0x30);   //基本指令集
    delay_ms(1);
        Write_Cmd(0x30);   //基本指令集
    delay_ms(1);

        Write_Cmd(0x80);   //设定显示的起始地址
        delay_ms(1);

        Write_Cmd(0x0c);  //开显示,无游标,不反白.
    delay_ms(1);
       
    Write_Cmd(0x01);//Clear DDRAM and set DDRAM address to AC
    Delay_Nms(15);//> 10ms

    Write_Cmd(0x06);   //游标右移
    delay_ms(1);

}

/*******************************************
函数名称:Clear_GDRAM
功    能:清除液晶GDRAM中的随机数据
参    数:无
返回值  :无
********************************************/
void Clear_GDRAM(void)
{
    u8 i,j,k;

        Write_Cmd(0x34);        //打开扩展指令集
        i = 0x80;            
        for(j = 0;j < 32;j++)
        {
        Write_Cmd(i++);
        Write_Cmd(0x80);
                  for(k = 0;k < 16;k++)
                  {
                      Write_Data(0x00);
                  }
        }
        i = 0x80;
        for(j = 0;j < 32;j++)
        {
            Write_Cmd(i++);
        Write_Cmd(0x88);          
                  for(k = 0;k < 16;k++)
                  {
                       Write_Data(0x00);
                   }
        }   
        Write_Cmd(0x30);        //回到基本指令集
}



/*******************************************
函数名称:Draw_TX
功    能:显示一个8*16大小的图形
参    数:Yaddr--Y地址
          Xaddr--X地址
          flash--是否要闪
          FangBai--是否要反白
          dp--指向图形数据存放地址的指针
          横向高点8位
返回值  :无
********************************************/
void Draw_TX8x16(u8 Yaddr,u8 Xaddr,const u8 * dp)
{
    u8 j;
    u8 k=0;
    u8 data;
   // Write_Cmd(0x01);  //清屏,只能清除DDRAM
    Write_Cmd(0x34);  //使用扩展指令集,关闭绘图显示


    for(j=0;j<16;j++)
    {
            Write_Cmd(Yaddr++);           //Y地址
        Write_Cmd(Xaddr);//X地址
        data=dp[k++];
              Write_Data(data);
                //data=dp[k++];
              //Write_Data(data);
    }
    Write_Cmd(0x36);  //打开绘图显示
    Write_Cmd(0x30);  //回到基本指令集模式
}


//取反白
void Draw_TX8x16F(u8 Yaddr,u8 Xaddr,const u8 * dp)
{
    u8 j;
    u8 k=0;
    u8 data;
   // Write_Cmd(0x01);  //清屏,只能清除DDRAM
    Write_Cmd(0x34);  //使用扩展指令集,关闭绘图显示


    for(j=0;j<16;j++)
    {
            Write_Cmd(Yaddr++);           //Y地址
        Write_Cmd(Xaddr);//X地址
        data=~dp[k++];
              Write_Data(data);
                //data=~dp[k++];
              //Write_Data(data);
    }
    Write_Cmd(0x36);  //打开绘图显示
    Write_Cmd(0x30);  //回到基本指令集模式
}

函数名称:Draw_TX
功    能:显示一个16*16大小的图形
参    数:Yaddr--Y地址
          Xaddr--X地址
          flash--是否要闪
          FangBai--是否要反白
          dp--指向图形数据存放地址的指针
          横向高点8位
返回值  :无
********************************************/
void Draw_TX16x16(u8 Yaddr,u8 Xaddr,const u8 * dp)
{
    u8 j;
    u8 k=0;
    u8 data;
   // Write_Cmd(0x01);  //清屏,只能清除DDRAM
    Write_Cmd(0x34);  //使用扩展指令集,关闭绘图显示

                

    for(j=0;j<16;j++)
    {
                Write_Cmd(Yaddr++);    //Y地址
                Write_Cmd(Xaddr);//X地址
        data=dp[k++];
              Write_Data(data);
                data=dp[k++];
              Write_Data(data);
    }
    Write_Cmd(0x36);  //打开绘图显示
    Write_Cmd(0x30);  //回到基本指令集模式
}



//取反白
void Draw_TX16x16F(u8 Yaddr,u8 Xaddr,const u8 * dp)
{
    u8 j;
    u8 k=0;
    u8 data;
   // Write_Cmd(0x01);  //清屏,只能清除DDRAM
    Write_Cmd(0x34);  //使用扩展指令集,关闭绘图显示


    for(j=0;j<16;j++)
    {
            Write_Cmd(Yaddr++);           //Y地址
        Write_Cmd(Xaddr);//X地址
        data=~dp[k++];
              Write_Data(data);
                data=~dp[k++];
              Write_Data(data);
    }
    Write_Cmd(0x36);  //打开绘图显示
    Write_Cmd(0x30);  //回到基本指令集模式
}


//---------------------------------------------
//最多显示八个中文汉字
//---------------------------------------------
u8 uartprintf(u8 x,u8 y,u8 * str,u8 flash)
{
        register u8 ch1;
        register u8 ch2;
        register u16 ch16;
        register u16 index;//所在的位置
        u8 hanziBuf[32];//汉字缓存
        u8 AssiiBuf1[16];//ASSIIC缓存
        u8 AssiiBuf2[16];//ASSIIC缓存
        static u8 Youflag=0;
        static u8 LastData=0;
        register u8 Posx,Posy;
        u8 i;
        u8 j,k;
       
    if(x>3) return 0;
        if(y>7) return 0;
        switch(x)
        {
       case 0:
         Posy=0x80;
                 Posx=0x80+y;
                 break;
           case 1:
                    Posy=0x90;
                 Posx=0x90+y;
                    break;
           case 2:
         Posy=0x80;
                 Posx=0x88+y;
                 break;
           case 3:
         Posy=0x90;
                 Posx=0x98+y;
                 break;
            default:
                        Posy=0x80;
                        Posx=0x80+y;
                        break;          
        }

        Youflag=0;
        for(;;str++)
        {
                ch1=*str;
                if(ch1==0)break;
                if(ch1<0x80)
                {
                     
                        //point=chardot+((u16)(ch1-0x20)<<4);
                        if(Youflag==0)
                        {
                Youflag=1;
                                LastData=ch1;
                                index=(ch1-0x20)*16;
                                memcpy(AssiiBuf1,&chardot[index],sizeof(AssiiBuf1));
                                if(flash&Flash_**)        Draw_TX8x16(Posy,Posx,AssiiBuf1);
                                else                                 Draw_TX8x16F(Posy,Posx,AssiiBuf1);
                        }else
                        {
                            
                Youflag=0;
                                //把连个字母的字模拼接成16x16

                                index=(LastData-0x20)*16;
                                memcpy(AssiiBuf1,&chardot[index],sizeof(AssiiBuf1));
                               
                                index=(ch1-0x20)*16;
                                memcpy(AssiiBuf2,&chardot[index],sizeof(AssiiBuf2));

                j=0;k=0;
                                for(i=0;i<32;i++)
                                {
                   if(i&0x01)
                           {
                        hanziBuf[i]=AssiiBuf2[j]; j++;       
                                    }
                                   else
                                           {
                         hanziBuf[i]=AssiiBuf1[k]; k++;
                                    }
                                }
                               
                   
                                if(flash&Flash_**)        Draw_TX16x16(Posy,Posx,hanziBuf);
                            else                                 Draw_TX16x16F(Posy,Posx,hanziBuf);

                                Posx++;
                        }

                }
                else
                {
                    if(Youflag==1)
                    {
                 Youflag=0;
                                 Posx++;
                        }
                    
                        str++;
                        ch2=*str;
                        ch16=((u16)ch1<<8)|(u16)ch2;
            index=HanZiIndex(ch16);
                        index=index*32;//计算出真正的偏移
                        memcpy(hanziBuf,&hzdot[index],sizeof(hanziBuf));
                                            
                        if(flash&Flash_**)        Draw_TX16x16(Posx,Posy,hanziBuf);
                        else                                 Draw_TX16x16F(Posx,Posy,hanziBuf);
                        Posx++;
                        //Posy++;
                }
        }
        return y;
}


相关帖子

沙发
肥羊|  楼主 | 2017-11-28 09:32 | 只看该作者
本帖最后由 肥羊 于 2017-11-28 09:34 编辑

下面是主函数
int main(void)
{        
        u8 t;
        u8 len;        
        u16 times=0;
    u8 i;
        delay_init();                     //延时函数初始化        
        //NVIC_Configuration();// 设置中断优先级分组
        //uart_init(9600);         //串口初始化为9600
        //LED_Init();                           //初始化与LED连接的硬件接口
        //RCC_Configuration();
    LCD_GPIOInit();
        Ini_Lcd();
        //InitDis();
        Clear_GDRAM();
        Flash_**=0;
        while(1)
        {
                Clear_GDRAM();//清屏
                uartprintf(0,0,"RRRRRRng",0);
                uartprintf(1,0,"tiantianshang",0);
                uartprintf(2,0,"BBBBadf",0);
                uartprintf(3,0,"AAAAAadf",0);        
                delay_ms(1000);
        }         
}

使用特权

评论回复
板凳
肥羊|  楼主 | 2017-11-28 12:28 | 只看该作者
有没有人啊,自己帮自己顶

使用特权

评论回复
地板
山东电子小菜鸟| | 2017-11-28 21:04 | 只看该作者
1、提高刷新频率
2、看下是否多加了清屏指令
3、放定时器刷新

使用特权

评论回复
5
zhaoyu2005| | 2017-11-28 22:00 | 只看该作者
肥羊 发表于 2017-11-28 12:28
有没有人啊,自己帮自己顶

屏的驱动芯片什么型号,7290速度不行,ST7565 K0108可以

使用特权

评论回复
6
一路向北lm| | 2017-11-28 22:31 | 只看该作者
加下中断试试,在中断例刷新

使用特权

评论回复
7
dsyq| | 2017-11-29 09:09 | 只看该作者
是不是有一阵子清屏了(通常会延时若干毫秒)?

使用特权

评论回复
8
肥羊|  楼主 | 2017-11-29 11:07 | 只看该作者
dsyq 发表于 2017-11-29 09:09
是不是有一阵子清屏了(通常会延时若干毫秒)?

我延时了1S函数这样

使用特权

评论回复
9
肥羊|  楼主 | 2017-11-29 11:08 | 只看该作者
一路向北lm 发表于 2017-11-28 22:31
加下中断试试,在中断例刷新

不解请大神详解

使用特权

评论回复
10
肥羊|  楼主 | 2017-11-29 11:08 | 只看该作者
zhaoyu2005 发表于 2017-11-28 22:00
屏的驱动芯片什么型号,7290速度不行,ST7565 K0108可以

对是7920我用图片的方式做

使用特权

评论回复
11
肥羊|  楼主 | 2017-11-29 11:09 | 只看该作者
山东电子小菜鸟 发表于 2017-11-28 21:04
1、提高刷新频率
2、看下是否多加了清屏指令
3、放定时器刷新

1提高了还就显示不清楚了
2.我在重画的时候是清屏了

使用特权

评论回复
12
zhaoyu2005| | 2017-11-29 11:29 | 只看该作者
肥羊 发表于 2017-11-29 11:08
对是7920我用图片的方式做

那还是不要纠结了,指令速度跟不上,换屏吧。显示字库里的字符或者汉字还行,如果是靠打点程序显示,不要要求太高,你根据指令执行速度,计算下写一屏数据需要多长时间就知道了。指令延时短了直接出错

使用特权

评论回复
13
肥羊|  楼主 | 2017-11-29 11:51 | 只看该作者
zhaoyu2005 发表于 2017-11-29 11:29
那还是不要纠结了,指令速度跟不上,换屏吧。显示字库里的字符或者汉字还行,如果是靠打点程序显示,不要 ...

应该可以吧,如果不用图片方式就不能白反

使用特权

评论回复
14
dsyq| | 2017-11-29 11:52 | 只看该作者
ST7920用图片显示的话,我也测试过。
你往里面发送数据的时候,显示不会改变。发送数据结束,再用那个扩展指令(无需任何延时),按理不会出现闪烁。

如果没有硬件原因,闪烁的原因应该就是显示过程中出现过若干毫秒的“空白”。

使用特权

评论回复
15
dsyq| | 2017-11-29 11:56 | 只看该作者
请问楼主用的什么MCU。

使用特权

评论回复
16
一路向北lm| | 2017-11-29 12:15 | 只看该作者
肥羊 发表于 2017-11-29 11:08
不解请大神详解

把屏幕显示放到中断里面,或者加操作系统管理。

使用特权

评论回复
17
潜力变实力| | 2017-11-29 12:54 | 只看该作者
本帖最后由 潜力变实力 于 2017-11-29 12:57 编辑

不要听他们的,他们基本上没有玩过液晶,12864是静态显示,刷新一次就行了,不是数码管需要一直刷新!看看你自己的程序,刚刚显示就清屏,超快的速度清,你这样子不闪烁才怪呢?你延时1s就是1s清一次,你延时10s就不会闪烁了,因为10s清一次。

while(1)
        {
                Clear_GDRAM();//清屏
                uartprintf(0,0,"RRRRRRng",0);
                uartprintf(1,0,"tiantianshang",0);
                uartprintf(2,0,"BBBBadf",0);
                uartprintf(3,0,"AAAAAadf",0);        
                delay_ms(1000);
        }         

使用特权

评论回复
18
肥羊|  楼主 | 2017-11-29 15:02 | 只看该作者
dsyq 发表于 2017-11-29 11:56
请问楼主用的什么MCU。

stm32

使用特权

评论回复
19
肥羊|  楼主 | 2017-11-29 16:05 | 只看该作者
潜力变实力 发表于 2017-11-29 12:54
不要听他们的,他们基本上没有玩过液晶,12864是静态显示,刷新一次就行了,不是数码管需要一直刷新! ...

现在就是感觉清屏时间有点久和画图时间有点长

使用特权

评论回复
20
ningling_21| | 2017-11-29 17:27 | 只看该作者
肥羊 发表于 2017-11-29 16:05
现在就是感觉清屏时间有点久和画图时间有点长

“”画图时间有点长“”

有多长?

使用特权

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

本版积分规则

35

主题

271

帖子

1

粉丝