打印

设计时**

[复制链接]
楼主: 古道热肠
手机看帖
扫描二维码
随时随地手机跟帖
21
古道热肠|  楼主 | 2008-8-24 17:17 | 只看该作者 回帖奖励 |倒序浏览

有个打包的可执行文件,可以直接用

使用特权

评论回复
22
jack.king| | 2008-8-24 17:40 | 只看该作者

LcdShowString(1,0,"时钟管理");这个函数能不能贴出来!?

使用特权

评论回复
23
zealane| | 2008-8-24 20:38 | 只看该作者

哈哈,不错,正在找这个呢。

好好研究。精简一下我们的字库

使用特权

评论回复
24
平常人| | 2008-8-24 21:55 | 只看该作者

俺比较懒惰,把每幅菜单做成一个个图片直接显示

程序简单而且可以显示任何语言文字。

使用特权

评论回复
25
yewuyi| | 2008-8-24 22:17 | 只看该作者

哈哈,爽歪歪。。。

使用特权

评论回复
26
电子尘埃| | 2008-8-25 08:41 | 只看该作者

古版主一句话,胜读十年书呀.

使用特权

评论回复
27
sz_kd| | 2008-8-25 10:29 | 只看该作者

路过,顶

使用特权

评论回复
28
LPcfANS| | 2008-8-25 11:24 | 只看该作者

我也用结构....看来也的优化一下...

使用特权

评论回复
29
电子尘埃| | 2008-8-25 11:25 | 只看该作者

单独索引的草稿

/*---------------------------------------------------------------------------

功能:   查找汉字起始地址
输入:  汉字机内码
输出:   该汉字的首地址
---------------------------------------------------------------------------*/
static INT8U*  GetHzModelInMem(INT16U uiHZCode) 
{
        #define  hzNum  7

        INT8U hzIndex[hzNum]  = {    //汉字机内码定义
                0xb0,0xe6,0xb1,0xbe,0xb1,0xe3,0xb2,0xc9,
                0xb3,0xfd,0xb6,0xaf,0xb6,0xc8,0xb7,0xb6,
                0xb7,0xe5,0xba,0xc5,0xbc,0xc6,0xbc,0xd3,
                0xbc,0xe4,0xbd,0xe2,0xc0,0xad,0xc1,0xa6,
                0xc1,0xe3,0xc2,0xca,0xc7,0xe5,0xc9,0xe8,
                0xca,0xb1,0xca,0xbd,0xcb,0xd9,0xcd,0xc6,
                0xce,0xa7,0xd0,0xaf,0xd0,0xcd,0xd1,0xf9,
                0xd6,0xb5,0xd6,0xc3,0xd6,0xd8,0xd7,0xd4
        };
        INT8U   code_n = 0;
        INT8U *code_ptr = hzdot;

        for( code_n = 0;code_n<hzNum;code_n++ ) {
                if (uiHZCode == hzIndex[code_n] ) { //-找到地址
                        break;
                }
        }
        return(code_ptr + (code_n*32) );
}

#endif

INT8U * ptr = GetHzModelInMem('便'); //'便'字的首地址

没有办法.想要方便得多出这些        INT8U hzIndex[hzNum]  = {    //汉字机内码定义
                0xb0,0xe6,0xb1,0xbe,0xb1,0xe3,0xb2,0xc9,
                0xb3,0xfd,0xb6,0xaf,0xb6,0xc8,0xb7,0xb6,
                0xb7,0xe5,0xba,0xc5,0xbc,0xc6,0xbc,0xd3,
                0xbc,0xe4,0xbd,0xe2,0xc0,0xad,0xc1,0xa6,
                0xc1,0xe3,0xc2,0xca,0xc7,0xe5,0xc9,0xe8,
                0xca,0xb1,0xca,0xbd,0xcb,0xd9,0xcd,0xc6,
                0xce,0xa7,0xd0,0xaf,0xd0,0xcd,0xd1,0xf9,
                0xd6,0xb5,0xd6,0xc3,0xd6,0xd8,0xd7,0xd4
        }; ROM不够的像这我样定义,RAM不够的加code

使用特权

评论回复
30
农民讲习所| | 2008-8-25 11:32 | 只看该作者

还可以更进一步

描述GUI界面的不是字模,是字符串ID。这样可以使界面和程序无关。
比如想在(20,20)显示“我是一个兵”,程序应该是这样的:

struct StringId
{
    U8 x,
    U8 y,
    U8 *ps;
};

enum {
  eS_YiGeBing,
};
Gui_StringId( eS_YiGeBing );

eS_YiGeBing枚举信息包含了默认的X,Y坐标,还可以包括颜色,再加上字符串信息。其中字符串信息中每个字模包含宽度和高度,这样设计可以随意改变字模大小而程序不动。

使用特权

评论回复
31
LPcfANS| | 2008-8-25 11:35 | 只看该作者

所长把LCD再讲讲吧,让我们也学习一下.呵呵.

以前所长说了一部分..我现在的LCD界面都是用的函数指针....看了所长的一部分,感觉很好啊...

使用特权

评论回复
32
农民讲习所| | 2008-8-25 11:39 | 只看该作者

想办法让程序和资源无关

比如:资源可以是单独一个BIN文件,可以用C数组形式包含,也可以单独放在EEPROM或NANDFKASH中。更改资源,程序不动。做到这个地步,GUI设计也就入门了。

使用特权

评论回复
33
古道热肠|  楼主 | 2008-8-25 11:44 | 只看该作者

贴上LCD_ShowString等函数的实现代码

#define c_LCD_MaxColNumber 10
bool bLCDDisplayReverseFlag;    //定义标志位用于是否进行反白显示
code   uchar ucMaskCode[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};

void GetHZDot(uint uiHZCode,uchar *ucHZDotData);
void LCD_GetHZDot(uchar ucHZHighByte,uchar ucHZlowByte,uchar *ucHzDotBuff)        //获取汉字的点 阵
{
    uint uiHZCode;
    uchar uci;


    uiHZCode = ucHZHighByte;
    uiHZCode <<=8;
    uiHZCode |= ucHZlowByte;

    GetHZDot(uiHZCode,ucHzDotBuff);
    if(bLCDDisplayReverseFlag)
    {
        for(uci=0; uci<32; uci++)
        {
            ucHzDotBuff[uci] = ~ucHzDotBuff[uci];
        }
    }
}

extern code unsigned char   EnglishCharDot8X16[][16];

void LCD_GetEnglishCharDot(uchar ucCharID,uchar *ucHzDotBuff)
{
    uchar uci;

    for(uci=0; uci<16; uci++)
    {
        if(bLCDDisplayReverseFlag)
        {
            ucHzDotBuff[uci] = ~EnglishCharDot8X16[ucCharID-' '][uci];
        }
        else
        {
            ucHzDotBuff[uci] = EnglishCharDot8X16[ucCharID-' '][uci];
          }

    }
}

unsigned char code MaskBit[8]={128,64,32,16,8,4,2,1};
//----------------------------------------------------------------------------
// 函 数 名:void ShowWord(unsigned char ucCharRow,unsigned char ucCharCol,const unsigned char *sucWord)
// 用    途:在指定的行和列显示字符
// 入口参数:ucCharRow  : 字符显示所在的行数 1,2,3,4;
//           ucCharCol  :字符显示所在的列数 1~12;
//           sucWord    :待显示的字符,西文字符 1 个字节,一个汉字坠有两个字节
// 返    回: 无
//-----------------------------------------------------------------------------
void ShowWord(uchar ucCharRow, uchar ucCharCol, uchar *sucWord)
{   
    uchar  data uci;
    uchar ucj;
    uchar  xdata ucHzDot[32];      //必须设置在DATA区,因为SelectFlashPageAddress(0);在下面

    uchar   ucX;              //一个区中列计数器
    uchar   ucY;
//    uchar   ucPage;

//    LCD_Init();
    //判断是否为汉字
    //0x80 = 128   ASCII码000~127为标准的,判断是否为汉字,汉字的ASCII码一定大于128D
    if(sucWord[0] > 0x80 && sucWord[1] > 0x80)
       {   //如果是汉字
        LCD_GetHZDot(sucWord[0],sucWord[1],ucHzDot);        //获取汉字的点 阵
        ucX = ucCharCol*8;
        ucY = ucCharRow*16;
        for(uci=0;uci<16;uci++)
        {
            for(ucj=0;ucj<8;ucj++)
            {
                if(ucHzDot[2*uci] & MaskBit[ucj])
                {
                    LCD_Set_Pixel(ucX+ucj,uci+ucY,1);
                   }
                else
                {
                    LCD_Set_Pixel(ucX+ucj,uci+ucY,0);
                }
                if(ucHzDot[2*uci+1] & MaskBit[ucj])
                {
                    LCD_Set_Pixel(ucX+8+ucj,uci+ucY,1);
                  }
                else
                {
                    LCD_Set_Pixel(ucX+8+ucj,uci+ucY,0);
                }
            }
        }

    }
    else
     {   //如果是西文
        LCD_GetEnglishCharDot(sucWord[0],ucHzDot);
        ucX = ucCharCol*8;
        ucY = ucCharRow*16;
        for(uci=0;uci<16;uci++)
        {
            for(ucj=0;ucj<8;ucj++)
            {
                if(ucHzDot[uci] & MaskBit[ucj])
                {
                    LCD_Set_Pixel(ucX+ucj,uci+ucY,1);
                   }
                else
                {
                    LCD_Set_Pixel(ucX+ucj,uci+ucY,0);
                }
            }
        }
        //WriteDataToRS232(0x01, ucHzDot, 16);
    }
}


//----------------------------------------------------------------------------
// 函 数 名:void LcdShow(uchar ucCharRow,uchar ucCharCol,const uchar *sucWord)
// 用    途:在指定的行和列显示一串字符,包括汉字
// 入口参数:ucCharRow  :第一个字符显示所在的行数 1,2,3,4;
//           ucCharCol  :第一个字符显示所在的列数 1~24;
//           ucLength   :需显示字符的个数,一个汉字两个字符
//           sucWord    :待显示的字符,西文字符 1 个字节,一个汉字坠有两个字节
// 返    回: 无
//-----------------------------------------------------------------------------
void LcdShowString(uchar ucCharRow, uchar ucCharCol, uchar *DispString)
{
    uchar  uci;
    uchar  ShowBuff[2];
    uchar ucStringLength;
    
    ucStringLength = strlen(DispString);
    for(uci = 0; uci < ucStringLength; )
    {
        if (DispString[uci] <= 0x80)
        {
             ShowBuff[0] = DispString[uci];
            ShowBuff[1] = 0x00;
            ShowWord(ucCharRow,( ucCharCol + uci), ShowBuff);
            uci += 1;
        }
        else
        {
            ShowBuff[0] = DispString[uci];
            ShowBuff[1] = DispString[uci + 1];
            ShowWord(ucCharRow,( ucCharCol + uci), ShowBuff);
            uci += 2;
        }
        //超出LCD显示范围时,截尾。
        if((ucCharCol+uci)>c_LCD_MaxColNumber)
        {
            break;
        }

    }
}
//在液晶屏上反显字符串
void LcdShowString_Reverse(uchar ucCharRow, uchar ucCharCol, uchar *DispString)
{
    bLCDDisplayReverseFlag = true;
    LcdShowString(ucCharRow,ucCharCol,DispString);
    bLCDDisplayReverseFlag = false;
}

void TestLCDDriver(void)
{
    while(1)
    {
        LCD_ClearScreen();
        Delay_1S(1);
        LCD_FillScreen();
        Delay_1S(1);
        LCD_ClearScreen();

        LcdShowString(1, 0, "时钟管理");
        LcdShowString(0, 1,"音乐播放");
//        LcdShowString(3, 1,"Abc时钟DEF");
        LcdShowString_Reverse(2, 0, "时钟管理");

        Delay_1S(1);
        Delay_1S(1);
        Delay_1S(1);

      }
}

使用特权

评论回复
34
农民讲习所| | 2008-8-25 11:49 | 只看该作者

按照前面按说的,西文和中文都无所谓了

即使混合显示也可以,只要在字模加上宽度和高度信息。
以后改葡萄牙语也好,法语也好,很轻松搞定。

不要在程序要用if(sucWord[0] > 0x80 && sucWord[1] > 0x80)
       {   //如果是汉字
之类硬代码。

使用特权

评论回复
35
农民讲习所| | 2008-8-25 11:51 | 只看该作者

以后更改语言,只要使用不同资源文件就可以。

一个简单的指针指向不同的资源。

使用特权

评论回复
36
古道热肠|  楼主 | 2008-8-25 11:54 | 只看该作者

所说提到的结构体归类有道理

要做GUI,结构体是必不可少的,使用结构体把一个元素的属性都归到一起,用起来很方便.如果再加上指向函数的指针,则可以架构面过事件的消息驱动,这一块是GUI的核心.

使用特权

评论回复
37
农民讲习所| | 2008-8-25 11:59 | 只看该作者

设计时**

“程序和数据无关”,自然而然就会产生很多奇妙的非常有意思想法。

使用特权

评论回复
38
古道热肠|  楼主 | 2008-8-25 12:11 | 只看该作者

回电子尘埃

您写的INT8U * ptr = GetHzModelInMem('便'); //'便'字的首地址
好象有问题.
'便'是两个字符,是字符串,只有英文字符可以用单引号,字符串用双引号.

使用特权

评论回复
39
电子尘埃| | 2008-8-25 13:41 | 只看该作者

强转成INT类型了.没有问题.通过编译了

使用特权

评论回复
40
电子尘埃| | 2008-8-25 13:57 | 只看该作者

所长,你好.

   我只搞过单片机的程序设计.别的没有弄过.
   这是我目前水平的理解,
   如果一切与资源无关.代码得大好多吧?
   所长你能帮我等菜鸟对程序设计(嵌入式)的思想提高一步吗?好像市面上关于此类的书特少.

使用特权

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

本版积分规则