查看: 819|回复: 0
打印 上一主题 下一主题

个占用内存极少的菜单系统的实现"移植到AVR(W

[复制链接]
跳转到指定楼层
沙发
发表于 2016-5-9 22:58:36 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
是基于本站网友liandao著名的:一个占用内存极少的菜单系统的实现,我想把它改在AVR(WinAVR20100110)上执行,经过一番折腾,结果还是不正确,实在没招了,请大家帮忙指点一下.不胜感激.
http://www.ourdev.cn/bbs/bbs_con ... =1&search_text=菜单系统&bbs_id=9999
参考了本站网友xcodes的:一个占用内存极小的菜单系统在AVR上的移植
http://www.ourdev.cn/bbs/bbs_con ... =1&search_text=菜单系统&bbs_id=9999

现在编译通过:
代码(用PN)及proteus仿真文件:点击此处下载 ourdev_536007.rar(文件大小:269K) (原文件名:lcd_menu.rar)

显示字符串正常:GUI_DispStringAtBar(PSTR("Desktop"),0,0,126,GUI_TA_HCENTER);

显示菜单中的内容就不对了:
GUI_DispStringAtBar((PGM_P)(pgm_read_word(&MenuFunc[language].Text)),0,Enter_PosY - 2,126,GUI_TA_HCENTER);
GUI_DispStringAtBar((PGM_P)(&Tip[language].Text),0,Enter_PosY,126,GUI_TA_HCENTER);

显示效果:

(原文件名:disp.jpg)

以下是其中的部分代码:

//Bar型菜单的数据结构
struct Menu
{
    const char **Text;     //指向显示内容数组的指针
//    unsigned char **Text;     //指向显示内容数组的指针
    unsigned char TextNum;         //项个数
    void* (*Action)(void);  //对应的执行函数
};


prog_char TipEN_0[] PROGMEM = "Menu";
prog_char TipEN_1[] PROGMEM = "Select";
prog_char TipEN_2[] PROGMEM = "OK";
prog_char TipEN_3[] PROGMEM = "Cancel";
prog_char TipEN_4[] PROGMEM = "?OK?";

PGM_P TipEN[] PROGMEM = {
        TipEN_0,
        TipEN_1,
        TipEN_2,
        TipEN_3,
        TipEN_4,
};

prog_char TipCN_0[] PROGMEM = "菜单";
prog_char TipCN_1[] PROGMEM = "选择";
prog_char TipCN_2[] PROGMEM = "确认";
prog_char TipCN_3[] PROGMEM = "取消";
prog_char TipCN_4[] PROGMEM = "?确认?";

PGM_P TipCN[] PROGMEM = {
        TipCN_0,
        TipCN_1,
        TipCN_2,
        TipCN_3,
        TipCN_4,
};

#define MenuWhat(n) {(const char **)n,(sizeof(n)/sizeof(unsigned char *)),0}

//Tip
struct Menu Tip[] PROGMEM =
{
        MenuWhat(TipCN),
        MenuWhat(TipEN),
};


void GUI_DispStringAtBar(const char *s,unsigned char x0, unsigned char y0, unsigned char x1,unsigned char Mode)
{
    unsigned char ENCount;//英文统计
    unsigned char CNCount;//中文统计
    unsigned char XLen;
    unsigned char X;
    unsigned char Y;
    unsigned char i;
    const char *ss;
    CNCount = 0;
    ENCount = 0;
    XLen = 0;

    ss = s;

    while(i = pgm_read_byte(ss))
    {//统计中英文个数
        if (i > 0x80)
        {
            CNCount ++;
            ss++;
        }
        else
        {
           ENCount++;
        }
        ss++;
    }

    GUI_SetEnFont(En_8x16);

    XLen = ENCount*8 + CNCount*16;

    if (XLen > 127)
    {//我们只能显示一行
        XLen = 127;
    }
        //识别对其方式属性
    switch (Mode & 0x30)
    {//只有这两个Bit是这个属性
        case GUI_TA_LEFT: //左对齐
            XLen = 0;
            break;
        case GUI_TA_HCENTER:  //居中
            XLen  = ((x1-x0)-XLen)/2;
            break;
        case GUI_TA_RIGHT:   //右对齐
            XLen  = (x1-x0)-XLen;
            break;
        default:
            break;
    }
//--------------------------------------
//得到喀什显示的起点坐标
    X = x0+XLen;
    Y = y0;

//---------------------
//清除字符前面的空白部分
    if(Mode&GUI_JUST_TEXT)
    {
    }
    else
    {
        x0 = X;
        if (GUITextMode == GUI_TEXTMODE_REVERSE)
        {
            for(i = 0; i < x0; i++)
            {
                Display_Locate(0xFF, i,y0);
                Display_Locate(0xFF, i,y0 + 1);
            }
        }
        else
        {
            for(i = 0; i <x0; i++)
            {
                Display_Locate(0x00, i,y0);
                Display_Locate(0x00, i,y0 + 1);
            }
        }
    }

    ss = s;
    while(i = pgm_read_byte(ss))
    {
        if (i < 0x80)
        {//是ASCII
            switch (GUITextMode)
            {
                case GUI_TEXTMODE_NORMAL :
                     Display_ASCII(i, X, Y);
                     break;
                case GUI_TEXTMODE_REVERSE :
                     Display_InvASCII(i, X, Y);
                     break;
                case GUI_TEXTMODE_UNDERLINE :
                     Display_ASCII_UnderLine(i, X, Y);
                     break;
                default :
                     break;
            }
            X += 8;
        }
        else
        {//是中文
            Display_Chinese((unsigned int)i * 256 + pgm_read_byte(ss + 1),X,Y);//中文
            X += 16;
            ss++;
       }
        ss++;
    }
//清除字符后面的空白部分
    if(Mode&GUI_JUST_TEXT)
    {
        GUI_SetEnFont(En_5x8);
        return;
    }
    else
    {
        x0 = X;
        if (GUITextMode == GUI_TEXTMODE_REVERSE)
        {
            for(i = 0; i <x1-x0; i++)
            {
                Display_Locate(0xFF, x0+i,y0);
                Display_Locate(0xFF, x0+i,y0+1);
            }
        }
        else
        {
            for(i = 0; i <x1-x0; i++)
            {
                Display_Locate(0x00, x0+i,y0);
                Display_Locate(0x00, x0+i,y0+1);
            }
        }
        GUI_SetEnFont(En_5x8);
        return;
    }
}







回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

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