4522|6

84

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

诡异的12864 proteus仿真 [复制链接]

废话先不多说,先上全部程序:
打点函数,用proteus仿真结果让我郁闷,都不知道错在哪。
#include


#define DataPort P2                  //数据端口



sbit E                 = P1^0;                    //指令数据控制                  
sbit RW         = P1^1;                    //读写控制
sbit CS1        = P1^2;                   //左屏幕选择,低电平有效
sbit CS2        = P1^3;                   //右屏幕选择
sbit Reset        = P1^4;                   //复位
sbit RS         = P1^5;                   //指令数据选择


void InitLcd12864(void);
void CheckBusy(void);
void WriterByte(unsigned char);
unsigned char ReadByte(void);
void WriterCom(unsigned char);
void SetPage(unsigned char);
void SetCol(unsigned char);
void SetStartLine(unsigned char);
void SetOnOff(unsigned char);
void SelectScreen(unsigned char);
void ClearScreen(unsigned char);
void DotX64Y128(unsigned char,unsigned char,bit);



void CheckBusy(){                //读忙函数
        unsigned char dy=10;
        while(dy--);
        return ;
        E=1;
        RS=0;
        RW=1;  
        DataPort=0xFF;
        while((DataPort&0x80)==0x00);                         
}

void WriterByte(unsigned char dat){           //写数据
          CheckBusy();

        E=1;
        RS=1;
        RW=0;
        DataPort=dat;
        E=0;

}

unsigned char ReadByte(void){
        unsigned char dat=0;
        CheckBusy();
        DataPort=0xFF;        
        RS=1;
        RW=1;       
        E=1;
        E=1;
        dat=DataPort;
        ;
        E=0;

                                                  
        DataPort=0xFF;
        RS=1;
        RW=1;
        E=1;
        E=1;
        dat=DataPort;
        E=0;            
        return dat;
}

void WriterCom(unsigned char com){         //写命令
        CheckBusy();

        E=1;
        RS=0;
        RW=0;
        DataPort=com;
        E=0;
}       

void SetPage(unsigned char page){                //设置页地址 0~7
        page&=0x07;
        page|=0xB8;        //1011 1XXX
        WriterCom(page);
}

void SetCol(unsigned char col){                 //设置列地址 0~63
        col&=0x3F;
        col|=0x40;//0100 XXXX
        WriterCom(col);
}

void SetStartLine(unsigned char startline){                  //设置开始行地址 0~63
        startline&=0x3F;
        startline|=0xC0;
        WriterCom(startline);               
}

void SetOnOff(unsigned char onoff){                                  //开关显示,1为开,0为关
        if(onoff==1){
                WriterCom(0x3F);         
        }else{
                WriterCom(0x3E);
        }  
}

void SelectScreen(unsigned char screen){                           //选择屏幕,0-全屏  1-左屏  2-右屏
        switch(screen){
                case 0:{
                        CS1=0;
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        CS2=0;
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                }
                break;
                case 1:{
                        CS1=0;
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        CS2=1;
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                }
                break;
                case 2:{
                        CS1=1;
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                        CS2=0;
                        ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                }
                break;
                default:
                break;
        }
}

void ClearScreen(unsigned char screen){                  //选择所清屏幕,0-全屏  1-左屏  2-右屏
        unsigned char i=0,j=0;
        SelectScreen(screen);
        for(i=0;i<8;i++){
                SetPage(i);
                SetCol(0);
                for(j=0;j<64;j++){
                        WriterByte(0x00);
                }
        }
}

void DotX64Y128(unsigned char x,unsigned char y,bit flag){
/*
        x :横坐标 0~63
        y :纵坐标 0~127
        flag:1为置位,0为清零
*/
        unsigned char rev=0;
        if(x>64 || y>128){
                return ;
        }
        if(y<64){
                SelectScreen(1);
        }else{
                SelectScreen(2);
        }
        SetPage(x>>3);
        SetCol(y);
        rev=ReadByte();

        if(flag==1){
                rev|=(0x01<<(x&0x07));
        }else{
                rev&=(~(0x01<<(x&0x07)));
        }

          SetPage(x>>3);
        SetCol(y);
        WriterByte(rev);
}
         
void InitLcd12864(){

        Reset=0;
        ;;;
        Reset=1;
        ;;;
        SetOnOff(1);
        ClearScreen(0);
        SetPage(0);
        SetCol(0);
          SelectScreen(0);
        SetStartLine(0);
        SetOnOff(1);
}

void main(){
        unsigned char i=0,j=0;
        unsigned int  k;  

        InitLcd12864();                  
        ClearScreen(0);

        for(i=0;i<128;i++){
                DotX64Y128(0,i,1);
                for(k=0;k<1000;k++);               
        }
        for(i=0;i<128;i+=1){
                DotX64Y128(8,i,1);
                DotX64Y128(63,127,1);
                for(k=0;k<1000;k++);
        }       
        for(i=0;i<2;i++){
                for(j=i;j<128;j+=2){
                        DotX64Y128(16,j,1);
                        for(k=0;k<1000;k++);
                }
        }
        SelectScreen(1);
        SetPage(3);
    SetCol(0);
        for(i=0;i<24;i++)
                WriterByte(0xFF);
        for(i=0;i<8;i++){  
                for(k=0;k<30000;k++);
                DotX64Y128(24,i,0);                       
        }
        for(i=0;i<8;i++){  
                for(k=0;k<30000;k++);
                DotX64Y128(24+i,8,0);                       
        }

        for(i=0;i<8;i++){  
                for(k=0;k<30000;k++);
                DotX64Y128(24+i,16+i,0);                       
        }
        for(i=0;i<8;i++){  
                for(k=0;k<30000;k++);
                DotX64Y128(24+i,i,0);                       
        }

        while(1);
}
结果是第一行第一列可以打个点,然后第二列就打一整列(即0xFF),然后第三行就又可以打个点,直到该行结束。
第二行我是先打个点,然后在(63,127)处打个点,然后再回到远处下一列打点,结果左半边现实不正常有半边现实正常。
第三行我是先打列数为偶数的点,打完该行之后我打列数为奇数的点,结果正常。
第四行是想看下清点函数,问题应该跟打点函数一个样。
就是纳闷为什么我打一个点,然后再在下一列打点就不行。
我都不知道怎么描述,巨囧,各位大侠如果如果有安装Keil c和proteus可以下载仿真下,跪谢各位大侠。

最新回复

你有12864的库元件吗  详情 回复 发表于 2018-4-18 02:39
点赞 关注

回复
举报

82

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
先用软件仿真下吧,用keilc51 v3的还带时序逻辑仿真的。你这个没带硬件的电路图也看不出什么啊。如果有51的仿真芯片也可以硬件仿真的,用逻辑分析仪或者示波器抓一下再分析。袂你的环境别人也开不出什么所以然的
 
 

回复

57

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
引用 1 楼 cbyibby 的回复:
先用软件仿真下吧,用keilc51 v3的还带时序逻辑仿真的。你这个没带硬件的电路图也看不出什么啊。如果有51的仿真芯片也可以硬件仿真的,用逻辑分析仪或者示波器抓一下再分析。袂你的环境别人也开不出什么所以然的
硬件电路图就是LCD与单片机连接,没其他的了。那个逻辑分析仪不会用。囧
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(初级)

4
 
给你个源码参考一下,借花献佛了
#include
#include"zifuku.h"
#define uchar unsigned char
#define uint unsigned int
sbit CS1=P2^0;                        //LCD右屏幕
sbit CS2=P2^1;                        //LCD左屏幕
sbit RS=P2^2;                        //LCD数据、指令寄存器
sbit RW=P2^3;                        //LCD读、写操作
sbit E=P2^4;                        //LCD使能信号,下降沿有效


/*
        自定义延时子函数
*/
void delayms(uchar z)
{
         int x,y;
         for(x=z;x>0;x--)
            for(y=110;y>0;y--);
}

/*
     判断LCD忙信号状态
*/
void buys()
{
         int dat;
         RW=1;
         RS=0;
         do
           {       
                P0=0x00;
                E=1;
                        dat=P0;
                        E=0;
                        dat=0x80 & dat;
                } while(!(dat==0x00));
}

/*
     LCD写指令函数
*/
void w_com(uchar com)
{
         //buys();
         RW=0;
         RS=0;
         E=1;
         P0=com;
         E=0;
}

/*
     LCD写数据函数
*/
void w_date(uchar date)
{
         //buys();
         RW=0;
         RS=1;
         E=1;
         P0=date;
         E=0;
}


/*
           LCD选屏函数
*/
void select_screen(uchar screen)
{
           switch(screen)
           {
                             case 0:     //选择全屏
                                     CS1=0;
                                                 CS2=0;
                                                    break;
                          case 1:     //选择左屏
                                     CS1=0;
                                                 CS2=1;
                                                    break;
                                   
                                case 2:     //选择右屏
                                     CS1=1;
                                                 CS2=0;
                                                    break;
                        /*  case 3:     //选择右屏
                                     CS1=1;
                                                   CS2=1;
                                                 break;
                        */
           }                     
          
}

/*
         LCDx向上滚屏显示
*/
void lcd_rol()
{
           int x;
           for(x=0;x<64;x++)
              {
                                  select_screen(0);
                                w_com(0xc0+x);
                                  delayms(500);
                  }


}

/*
           LCD清屏函数:清屏从第一页的第一列开始,总共8页,64列
*/
void clear_screen(screen)
{
         int x,y;
         select_screen(screen);                   //screen:0-选择全屏,1-选择左半屏,2-选择右半屏
         for(x=0xb8;x<0xc0;x++)                        //从0xb8-0xbf,共8页
            {
                        w_com(x);
                        w_com(0x40);                        //列的初始地址是0x40
                        for(y=0;y<64;y++)
                           {
                                       w_date(0x00);
                          
                            }
             }          
}

/*
                LCD显示汉字字库函数
*/
void lcd_display_hanzi(uchar screen,uchar page,uchar col,uint mun)
{                //screen:选择屏幕参数,page:选择页参数0-3,col:选择列参数0-3,mun:显示第几个汉字的参数
      int a;
          mun=mun*32;
          select_screen(screen);
          w_com(0xb8+(page*2));
          w_com(0x40+(col*16));
          for (        a=0;a<16;a++)
             {
                            w_date(hanzi[mun++]);
                 
                 }
          w_com(0xb8+(page*2)+1);
          w_com(0x40+(col*16));
          for (        a=0;a<16;a++)
             {
                            w_date(hanzi[mun++]);
                 
                 }
}

/*
                LCD显示字符字库函数
*/
void lcd_display_zifuk(uchar screen,uchar page,uchar col,uchar mun)
{                //screen:选择屏幕参数,page:选择页参数0-3,col:选择列参数0-7,mun:显示第几个汉字的参数
      int a;
          mun=mun*16;
          select_screen(screen);
          w_com(0xb8+(page*2));
          w_com(0x40+(col*8));
          for (        a=0;a<8;a++)
             {
                            w_date(zifu[mun++]);
                 
                 }
          w_com(0xb8+(page*2)+1);
          w_com(0x40+(col*8));
          for (        a=0;a<8;a++)
             {
                            w_date(zifu[mun++]);
                 
                 }
}

/*
                LCD显示数字字库函数
*/
void lcd_display_shuzi(uchar screen,uchar page,uchar col,uchar mun)
{                //screen:选择屏幕参数,page:选择页参数0-3,col:选择列参数0-7,mun:显示第几个汉字的参数
      int a;
          mun=mun*16;
          select_screen(screen);
          w_com(0xb8+(page*2));
          w_com(0x40+(col*8));
          for (        a=0;a<8;a++)
             {
                            w_date(shuzi[mun++]);
                 
                 }
          w_com(0xb8+(page*2)+1);
          w_com(0x40+(col*8));
          for (        a=0;a<8;a++)
             {
                            w_date(shuzi[mun++]);
                 
                 }
}

/*
                LCD初始化函数
*/
void lcd_init()
{
         w_com(0x3f);                 //LCD开显示
         w_com(0xc0);                 //LCD行初始地址,共64行
         w_com(0xb8);                 //LCD页初始地址,共8页
         w_com(0x40);                 //LCD列初始地址,共64列
   
}

/*
                LCD显示主函数
*/
void main()
{
  //第一行
      int x;
          lcd_init();                          //LCD初始化
          clear_screen(0);                  //LCD清屏幕
          lcd_display_shuzi(1,0,0,5);                  //LCD显示数字
          lcd_display_shuzi(1,0,1,1);                  //LCD显示数字
      lcd_display_hanzi(1,0,1,0);                  //LCD显示汉字
          lcd_display_hanzi(1,0,2,1);                  //LCD显示汉字                  //LCD字符汉字
          lcd_display_hanzi(1,0,3,2);                  //LCD显示汉字
          lcd_display_shuzi(2,0,0,5);                  //LCD显示数字
          lcd_display_shuzi(2,0,1,1);                  //LCD显示数字
      lcd_display_hanzi(2,0,1,0);                  //LCD显示汉字
          lcd_display_hanzi(2,0,2,1);                  //LCD显示汉字                  //LCD字符汉字
          lcd_display_hanzi(2,0,3,2);                  //LCD显示汉字
  //第二行         
          lcd_display_zifuk(1,1,2,0);                  //LCD显示字符
          lcd_display_zifuk(1,1,3,0);                  //LCD显示字符
          lcd_display_zifuk(1,1,4,0);                  //LCD显示字符
          lcd_display_zifuk(1,1,5,4);                  //LCD显示字符
          lcd_display_shuzi(1,1,6,8);                  //LCD显示字符
          lcd_display_shuzi(1,1,7,9);                  //LCD显示字符
          lcd_display_shuzi(2,1,0,5);                  //LCD显示字符
          lcd_display_shuzi(2,1,1,1);                  //LCD显示字符
          lcd_display_zifuk(2,1,2,4);
          lcd_display_zifuk(2,1,3,1);
          lcd_display_zifuk(2,1,4,2);
          lcd_display_zifuk(2,1,5,3);
  //第三行
          for(x=0;x<4;x++)
             {
                          lcd_display_hanzi(1,2,x,3+x);                  //LCD显示汉字
                 }
       
          for(x=0;x<4;x++)
             {
                          lcd_display_hanzi(2,2,x,7+x);                  //LCD显示汉字
                 }
  //第四行

           for(x=0;x<4;x++)
             {
                          lcd_display_zifuk(1,3,x,5+x);                  //LCD显示汉字
                 }
           lcd_display_shuzi(1,3,4,7);
           lcd_display_shuzi(1,3,5,5);
           lcd_display_shuzi(1,3,6,5);
           lcd_display_zifuk(1,3,7,9);
           lcd_display_shuzi(2,3,0,8);
           lcd_display_shuzi(2,3,1,9);
           lcd_display_shuzi(2,3,2,9);
           lcd_display_shuzi(2,3,3,5);
           lcd_display_shuzi(2,3,4,6);
           lcd_display_shuzi(2,3,5,8);
           lcd_display_shuzi(2,3,6,9);
           lcd_display_shuzi(2,3,7,2);
       while(1);
          /* while(1)
           {                                 //         LCD向上滚屏显示
                     lcd_rol();
           }
          */
}

 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

5
 
楼主您好:您的问题我没弄过,帮您顶一下
我想请问您在您文件后面的图形是怎么加进来的,我想发一个帖子,想在里面加一个电路图,不知怎么做能在帖子;里加进去,请赐教.非常感谢!!
 
 
 

回复

83

帖子

0

TA的资源

一粒金砂(初级)

6
 
问题描述得有点乱啊,呵呵,我看得一头雾水。。。。。。。只能默哀了,呵呵,祈祷楼主早点搞定
 
 
 

回复

28

帖子

0

TA的资源

一粒金砂(中级)

7
 
你有12864的库元件吗
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/6 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表