是基于本站网友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;
}
} |
|
|
|