找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2408|回复: 16
打印 上一主题 下一主题
收起左侧

KS0108 12864的屏幕显示字断开

  [复制链接]
跳转到指定楼层
楼主
本帖最后由 米花卷 于 2021-5-17 12:21 编辑


请问这样情况应该怎么解决
#include <reg52.h>
#include<intrins.h>
#include<string.h>
#include "hanzi.h"  //汉字库头文件
#include "shuzi.h"  //字符库头文件
#define uchar unsigned char
#define uint unsigned int

//   lcd12864(ks0108)
#define LCD_DATA P0  //LCD8位并行数据口   
sbit LCD_RS=P1^2;          //寄存器选择
sbit LCD_RW=P1^1;          //读/写选择
sbit LCD_EN=P1^0;          //读写使能
sbit LCD_CS1=P1^3;          //右半屏选择,1有效
sbit LCD_CS2=P1^4;          //左半屏选择,1有效
sbit LCD_RST=P1^5;          //复位信号  
//*********************************************//
// 函数声明
void init_lcd(void);
void lcd_delay(uint time);            //延时
void lcd_write_com(uchar cmdcode);    //写命令
void lcd_write_data(uchar Rsspdata);  //写数据
void lcd_Clr_Scr(void);               //清屏
void lcd_werite_x_y(uchar x,uchar y); //写地址
void lcd_write_chinese(uchar x,uchar y, uchar hz,uchar *dat); //任意位置显示任意汉字
void lcd_write_english(uchar x,uchar y, uchar en,uchar *dat); //任意位置显示任意字符
void lcd_write_english2(uchar x,uchar y, uchar en,uchar *dat);
//****************************************************************************//
//---------------------------------------
//    主函数
//---------------------------------------
void main(void)
{
          init_lcd();     //初始化
          lcd_Clr_Scr();  //清屏
        while(1)
        {
                lcd_write_chinese(0,40,9,HANZI);
                lcd_write_chinese(0,56,10,HANZI);
                lcd_write_chinese(0,72,11,HANZI);
               
                //lcd_write_english(2,0,0,SHUZI);
                //lcd_write_english(2,8,1,SHUZI);
                //lcd_write_english(2,16,2,SHUZI);
               
                lcd_write_english2(2,28,5,SHUZI24);
                lcd_write_english2(2,52,5,SHUZI24);
                lcd_write_english2(2,76,5,SHUZI24);
       
               
               
               
               
                while(1);
        }
}
//---------------------------------------
//   延时函数
//---------------------------------------
void lcd_delay(uint time)
{
          uint i;
          for(i=0;i<time;i++);
}
//---------------------------------------
//   12864初始化函数
//---------------------------------------
void init_lcd(void)
{          
          LCD_RST=0;              //液晶复位
          lcd_delay(250);         //适当延时
          LCD_RST=1;              //复位结束
          LCD_CS1=1;                         //左半屏选通
          LCD_CS2=1;                             //右半屏选通       
          lcd_delay(250);         //适当延时
          lcd_write_com(0x3f);    //显示开
}
//---------------------------------------
//   写命令函数
//---------------------------------------
void lcd_write_com(uchar cmdcode)
{                                          
          LCD_RS=0;                        //选择命令寄存器
          LCD_RW=0;                         //写选通
          LCD_DATA=cmdcode;   //将命令写入总线
          _nop_();            //空操作,做短暂的延时
          LCD_EN=1;           //E的下降沿,数据写入
          _nop_();            //空操作,做短暂的延时
          LCD_EN=0;           //E的下降沿,数据写入
}
//---------------------------------------
//   写数据函数
//---------------------------------------
void lcd_write_data(uchar Rsspdata)
{

          LCD_RS=1;                        //选择数据寄存器
          LCD_RW=0;                         //写选通
          LCD_DATA=Rsspdata;  //将数据写入总线
          _nop_();            //空操作,做短暂的延时
          LCD_EN=1;           //E的下降沿,数据写入
          _nop_();            //空操作,做短暂的延时
          LCD_EN=0;           //E的下降沿,数据写入
}
//---------------------------------------
//   清屏函数
//---------------------------------------
void lcd_Clr_Scr(void)
{
          uchar j,k;
          LCD_CS1=1;                                           //左半屏选通
          LCD_CS2=1;                                           //右半屏选通
          lcd_write_com(0x40+0);        //将列地址写入  
          for(k=0;k<8;k++)
          {
                    lcd_write_com(0xb8+k);    //将行地址写入       
                    for(j=0;j<64;j++)               //每行的64列都写0,因为选了左右两屏,
                    {
                              lcd_write_data(0x00); //64列同时写0
                    }
          }
}
//---------------------------------------
//    地址写入函数
//---------------------------------------
void lcd_werite_x_y(uchar x,uchar y)
{
          y=y&0x7f;                                 //限定范围,列不能超过128
          x=x&0x07;                             //限定范围,行不能超过8
          if(y<64)                    //如果列小于64
          {
                    LCD_CS1=1;                  //选通左半屏
                    LCD_CS2=0;                  //关闭右半屏
                    lcd_write_com(0x40+y);  //将列地址写入  
          }
          else
          {
                    LCD_CS1=0;                  //关闭左半屏
                    LCD_CS2=1;                  //选通右半屏
                    y&=0x3f;
                    lcd_write_com(0x40+y);  //将列地址写入         
          }
          lcd_write_com(0xb8+x);      //将行地址写入       
}
//---------------------------------------
//     指定位置写16*16汉字函数
//---------------------------------------
void lcd_write_chinese(uchar x,uchar y, uchar hz,uchar *dat)
{
          uchar i=0;       
          lcd_werite_x_y(x,y);             //设定起始地址
          for(i=0;i<16;i++)
          lcd_write_data(dat[hz*32+i]);    //先写上半个字,共16个字节
          lcd_werite_x_y(x+1,y);           //设定起始地址,此次将行地址加1,以便写下行
          for(i=0;i<16;i++)
          lcd_write_data(dat[hz*32+16+i]); //再写下半个字,共16个字节
}       
//---------------------------------------
//     指定位置写8*16字符函数
//---------------------------------------
void lcd_write_english(uchar x,uchar y, uchar en,uchar *dat)
{
    uchar i=0;       
          lcd_werite_x_y(x,y);            //设定起始地址
          for(i=0;i<8;i++)
          lcd_write_data(dat[en*16+i]);   //先写上半个字,共8个字节
          lcd_werite_x_y(x+1,y);          //设定起始地址,此次将行地址加1,以便写下行
          for(i=0;i<8;i++)
          lcd_write_data(dat[en*16+8+i]); //再写下半个字,共8个字节
}

//     指定位置写24*48字符函数
//---------------------------------------
void lcd_write_english2(uchar x,uchar y, uchar en,uchar *dat)
{
    uchar i=0;       
          lcd_werite_x_y(x,y);            //设定起始地址
          for(i=0;i<24;i++)
          lcd_write_data(dat[en*144+i]);   //先写上半个字,共8个字节
          lcd_werite_x_y(x+1,y);          //设定起始地址,此次将行地址加1,以便写下行
          for(i=0;i<24;i++)
          lcd_write_data(dat[en*144+24+i]); //再写下半个字,共8个字节
        lcd_werite_x_y(x+2,y);          //设定起始地址,此次将行地址加1,以便写下行
          for(i=0;i<24;i++)
          lcd_write_data(dat[en*144+48+i]); //再写下半个字,共8个字节
        lcd_werite_x_y(x+3,y);          //设定起始地址,此次将行地址加1,以便写下行
          for(i=0;i<24;i++)
          lcd_write_data(dat[en*144+72+i]); //再写下半个字,共8个字节
        lcd_werite_x_y(x+4,y);          //设定起始地址,此次将行地址加1,以便写下行
          for(i=0;i<24;i++)
          lcd_write_data(dat[en*144+96+i]); //再写下半个字,共8个字节
        lcd_werite_x_y(x+5,y);          //设定起始地址,此次将行地址加1,以便写下行
        for(i=0;i<24;i++)
          lcd_write_data(dat[en*144+120+i]); //再写下半个字,共8个字节
       
       
}
问题出在左右半屏的交接出,感觉右半屏没及时开,但程序里找不到改动的地方,我把代码补上,麻烦各位看看怎么改
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:35873 发表于 2021-5-17 05:12 | 只看该作者
估计你这程序是3片选的 显示数据叠加造成的  改改就好了
回复

使用道具 举报

板凳
ID:505032 发表于 2021-5-17 07:03 | 只看该作者
时序 、清屏;这方面多试试
回复

使用道具 举报

地板
ID:71233 发表于 2021-5-17 08:10 | 只看该作者
用Proteus仿真吗?如果是仿真的结果,建议用实物试试,实物的结果才比较可信。
回复

使用道具 举报

5#
ID:247623 发表于 2021-5-17 08:10 | 只看该作者
程序问题,修改一下即可
回复

使用道具 举报

6#
ID:554500 发表于 2021-5-17 08:33 | 只看该作者
这种情况多数是显示数据的地址错误造成的,检查下代码吧!
回复

使用道具 举报

7#
ID:16255 发表于 2021-5-17 10:53 | 只看该作者
新新科技 发表于 2021-5-17 08:10
用Proteus仿真吗?如果是仿真的结果,建议用实物试试,实物的结果才比较可信。

的确,很多时候,Proteus仿真和实际电路的运行结果有很大的差距。
回复

使用道具 举报

8#
ID:600695 发表于 2021-5-17 12:12 | 只看该作者
jialishoushi 发表于 2021-5-17 05:12
估计你这程序是3片选的 显示数据叠加造成的  改改就好了

KS0108 12864应该是左右分屏的,字模在分屏处断开了
回复

使用道具 举报

9#
ID:600695 发表于 2021-5-17 12:14 | 只看该作者
sZhou 发表于 2021-5-17 07:03
时序 、清屏;这方面多试试

也感觉是这个问题,左半屏写完右半屏没开,但怎么改没有思路了
回复

使用道具 举报

10#
ID:600695 发表于 2021-5-17 12:14 | 只看该作者
新新科技 发表于 2021-5-17 08:10
用Proteus仿真吗?如果是仿真的结果,建议用实物试试,实物的结果才比较可信。

实物也一样,只是这样好截图
回复

使用道具 举报

11#
ID:600695 发表于 2021-5-17 12:15 | 只看该作者
新新科技 发表于 2021-5-17 08:10
用Proteus仿真吗?如果是仿真的结果,建议用实物试试,实物的结果才比较可信。

字体16*16的时候仿真显示正常,实物断开,字体大了仿真都断开
回复

使用道具 举报

12#
ID:452984 发表于 2021-7-2 15:36 | 只看该作者
ks0108是左右半屏显示的。NT7534是上下半屏显示的,我遇到过类似的现象,液晶初始化程序里的起始位0x40改成0x60就行了。你可以试试此方法。
回复

使用道具 举报

13#
ID:88256 发表于 2021-7-2 17:53 | 只看该作者
米花卷 发表于 2021-5-17 12:15
字体16*16的时候仿真显示正常,实物断开,字体大了仿真都断开

说明你仿真的屏和实物屏还不完全一样,这是程序上的问题,只能自己慢慢排查了
回复

使用道具 举报

14#
ID:943857 发表于 2021-7-2 21:10 来自手机 | 只看该作者
仿真和实际往往相差,你要看下资料,即12864然后再找出原因
回复

使用道具 举报

15#
ID:939710 发表于 2021-7-7 04:55 | 只看该作者
这个屏是分左右的,左边列号从0-63   右边列号0-63.你如果要在交界处描点需要修改函数。你的中  列号超过63默认从0开始了。你可以改成 超过63打开右边屏继续显示
回复

使用道具 举报

16#
ID:939710 发表于 2021-7-7 05:14 | 只看该作者
E:\项目文件\参考例程\51黑论坛_stm32_12864\stm32_12864\1.png
回复

使用道具 举报

17#
ID:939710 发表于 2021-7-7 05:18 | 只看该作者
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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