This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

液晶12864显示汉字的程序代码问题



如题,这是LCD12864显示字符程序中的一段代码

void LCD_DATA(uchar d)
{
Uint32 i=0;
i = GpioDataRegs.GPADAT.all; //GPIO31~GPIO0
i |= (d<<6)&0x3FC0; //3FC0==0011 1111 1100 0000
i = (~( (d<<6)&0x3FC0) )|(~i);
GpioDataRegs.GPADAT.all = ~i;

就是还是弄不明白 GpioDataRegs.GPADAT.all的值是多少,能否麻烦楼主帮我解释一下GpioDataRegs.GPADAT.all的值是多少,以及这段代码实现的是什么功能,这个地方困扰我好几天了,感谢楼主了!!!

  • yuan nie,

    从你贴的代码来看,GpioDataRegs.GPADAT.all应该在其他地方有赋值,应该是在这个函数调用的前面,将原来的值进行一些移位、与、或等逻辑操作,这些操作你一步一步推就是,最后又重新赋值给它,推测可能是汉字滚动的功能。

  • Mr.Joey Mao,您好,感谢您对我问题的回复,这段代码我自己在下面推过,但是就卡在了 i = GpioDataRegs.GPADAT.all这个语句上,

    曾经还对这两条代码迷惑过GpioCtrlRegs.GPAMUX1.all &= 0xc03f; GpioCtrlRegs.GPADIR.all |= 0x00003FC0;后来在朋友的提示下理解是:因为对照12864的原理图(8条数据线D0~D7对应着核心板上的EPWM4A,EPWM4B,EPWM5A,EPWM5B,EPWM6A,EPWM6B,~TZ1,~TZ2,GpioCtrlRegs.GPAMUX1.all &= 0xc03f(1100 0000 0011 1111)是对EPWM4A,EPWM4B,EPWM5A,EPWM5B,EPWM6A,EPWM6B,~TZ1,~TZ2进行置零操作,而GPAMUX1的其他位则保持, GpioCtrlRegs.GPADIR.all |= 0x00003FC0(0000 0000 0000 0000 0011 1111 1100 0000)则是配置EPWM4A,EPWM4B,EPWM5A,EPWM5B,EPWM6A,EPWM6B,~TZ1,~TZ2的方向为输出,不知道理解对不对,然后就卡在了 i = GpioDataRegs.GPADAT.all这条语句上,下面我把源代码粘贴下来,烦请您指导!

    #include"DSP2833x_Device.h"
    #include "DSP2833x_Examples.h"
    #define EN GpioDataRegs.GPBDAT.bit.GPIO33
    #define RW GpioDataRegs.GPBDAT.bit.GPIO32
    #define RS GpioDataRegs.GPADAT.bit.GPIO20
    #define uchar unsigned char
    extern uchar menu1[]={"选择电机定时设置"};
    extern uchar menu2[]={"开步进电机A"};
    extern uchar menu3[]={"开步进电机B"};
    extern uchar menu4[]={"开步进电机C"};
    void LCDInit(void);
    void Write_order(Uint16 order);
    void Write_data(Uint16 data);
    void delay(Uint16 t);
    void configio(void);
    //void InitXintf(void);
    void display(uchar *hz);

    void LCD_DATA(uchar d){
    Uint32 i=0;
    i = GpioDataRegs.GPADAT.all;
    i |= (d<<6)&0x3FC0;
    i = (~((d<<6)&0x3FC0))|(~i);
    GpioDataRegs.GPADAT.all = ~i;
    }
    void LCDInit(void)
    {
    delay(500);
    Write_order(0x30);// 功能设定:基本指令动作
    delay(5);
    Write_order(0x0c);//显示状态:开
    delay(5);
    Write_order(0x01);//清屏
    delay(6);
    Write_order(0x02);//地址归位:AC=0x00
    delay(4);
    }

    void Write_order(Uint16 order)
    {
    RS=0;delay(1);
    RW=0;delay(1);
    EN=1;delay(1);
    LCD_DATA(order);
    delay(10);
    EN=0;delay(1);
    }

    void Write_data(Uint16 data)
    {
    RS=1;delay(1);
    RW=0;delay(1);
    EN=1;delay(1);
    LCD_DATA(data);
    delay(10);
    EN=0;delay(1);
    }

    void delay(Uint16 t)
    {
    Uint16 i;
    while(t--)
    {
    for(i=0;i<125;i++);
    }
    }

    void configio(void)
    {
    EALLOW;
    GpioCtrlRegs.GPAMUX1.all &= 0xc03f;
    GpioCtrlRegs.GPADIR.all |= 0x00003FC0;
    GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 0;
    GpioCtrlRegs.GPBDIR.bit.GPIO33 = 1;
    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;
    GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;
    GpioCtrlRegs.GPAMUX2.bit.GPIO20= 0;
    GpioCtrlRegs.GPADIR.bit.GPIO20 = 1;
    EDIS;
    }

    void display(uchar *hz)
    {
    while(*hz!='\0')
    {
    Write_data(*hz);
    hz++;
    delay(2);
    }
    }

    void main(void)
    {
    InitSysCtrl();
    // InitXintf();
    InitXintf16Gpio();
    DINT;
    InitPieCtrl();
    IER=0x0000;
    IFR=0x0000;

    configio();
    RS=0;
    delay(5);
    RW=0;
    delay(5);
    EN=0;
    LCDInit();
    delay(5);
    Write_order(0x01);
    delay(50);
    Write_order(0x80);
    delay(5);
    display(menu1);

    Write_order(0x91);
    delay(5);
    display(menu2);

    Write_order(0x89);
    delay(5);
    display(menu3);

    Write_order(0x99);
    delay(5);
    display(menu4);

    while(1);
    }

    //
    //===========================================================================
    // No more.
    //===========================================================================

  • GpioCtrlRegs.GPAMUX1.all &= 0xc03f;         // 是对IO口的复用功能进行配置
    GpioCtrlRegs.GPADIR.all |= 0x00003FC0;      // 是设置IO口7~13方向为输出,其余为输入

    你使用的是哪个芯片?GPA下面的这些IO口是接的12864屏吗?

  • 我用的是研旭的DSP28335实用开发板,GPAMUX1默认是对应GPIO0~GPIO31,使用外设1的话对应的是PWM3A,EPWM3B,EPWM4AEPWM1A,EPWM1B,EPWM2A,EPWM2B,E,EPWM4B,EPWM5A,EPWM5B,EPWM6A,EPWM6B,以及~TZ1,~TZ2,~TZ3/~XHOLD,~TZ4/~XHOLDA.

    12864液晶的八个数据端口D0~D7 对应的就是GPIO6~GPIO13..........这个地方我明白了,感谢您!

    void LCD_DATA(uchar d)

    {
    Uint32 i=0;
    i = GpioDataRegs.GPADAT.all;
    i |= (d<<6)&0x3FC0;
    i = (~((d<<6)&0x3FC0))|(~i);
    GpioDataRegs.GPADAT.all = ~i;
    }

     但是i = GpioDataRegs.GPADAT.all,这个地方怎么理解呢,烦请您再指导一下,不胜感激!!!


  •     这一句的目的是读取显示屏当前D0~D7的状态,后面两句是将要写的命令与显示屏写之前的状态合并,最后重新写入。

        之所以要这么写原因是:写内容的时候看起来比较方便,如主程序中写数据是在液晶屏上一行一行写的
    Write_order(0x80),是写第一行,display(menu1)是第一行的内容。下面几行是一样。
       
        这样写第二行的时候进过LCD_DATA这种处理方法,第二次写进去的实际内容就包含了第一行和第二行的内容,而如果不

    这么处理则写进去的只有第二行而没有第一行的内容。

        如果你还不是完全明白,建议不要光研究程序,要彻底搞清楚12864的读写时序和注意事项,网上有一些介绍的帖子可

    以看看。

  • 嗯,好的,我下去再看看这方面的资料,感谢您的指导!!!