上周考试,没时间把我的那篇“在LCD上倾角变化的显示界面”
https://bbs.eeworld.com.cn/viewthread.php?tid=330464 的学习心得写出来,现在补上!
我觉得我这个程序使用最多的就是Ti图形库的画布控件(Canvas)和图形按钮控件(Image Button),
我利用循环,添加了显示框和三个表盘以及指针
for (i = 0; i < 5; i++)
{
WidgetAdd(WIDGET_ROOT, g_tWidgetadc);
}
CanvasImageOff(&g_sadc3);//这里是暂时关闭单个表盘
CanvasAppDrawnOff(&g_sadc4);//这里是暂时关闭单个表盘指针
其实我把需要显示的背景和表针都显示在LCD上,只不过通过以上两个函数将它们暂时关闭,待到相应的功能按钮按下时,我在将它们打开,这样就有了切换显示的效果啦!!
这就是我添加的画布控件:
tWidget * g_tWidgetadc[5] =
{
(tWidget *)&g_sadc0,(tWidget *)&g_sadc1,(tWidget *)&g_sadc2,
(tWidget *)&g_sadc3,(tWidget *)&g_sadc4
};
具体如下:
Canvas(g_sadc0, WIDGET_ROOT, 0, 0,
&g_sLcdDisplay, 0, 164,320 , 30,
(CANVAS_STYLE_FILL | CANVAS_STYLE_OUTLINE | CANVAS_STYLE_TEXT | CANVAS_STYLE_TEXT_LEFT),
ClrWhite, ClrYellowGreen, ClrBlack, &TXT_FONT, "Angle:", 0, 0);
//添加三个表盘
Canvas(g_sadc1, WIDGET_ROOT, 0, 0,
&g_sLcdDisplay, 0, 0,320 ,163,
CANVAS_STYLE_IMG,
0, 0, 0, 0, 0,xyz,0);
//添加三个表盘指针
Canvas(g_sadc2, WIDGET_ROOT, 0, 0,
&g_sLcdDisplay, 0, 0, 320,163,
(CANVAS_STYLE_APP_DRAWN),
0, 0, 0, 0, 0,0,pfnOnPaint1);
//添加单个表盘
Canvas(g_sadc3, WIDGET_ROOT, 0, 0,
&g_sLcdDisplay, 0, 0,320 ,163,
CANVAS_STYLE_IMG,
0, 0, 0, 0, 0,kong,0);
//添加单个表盘指针
Canvas(g_sadc4, WIDGET_ROOT, 0, 0,
&g_sLcdDisplay, 0, 0, 320,163,
(CANVAS_STYLE_APP_DRAWN),
0, 0, 0, 0, 0,0,pfnOnPaint0);
其中的单个表盘指针和三个表盘指针的处理,我是利用的画布控件的WIDGET_MSG_PAINT事件处理凼数,
具体的pfnOnPaint0和pfnOnPaint1如下:
//处理单个表盘
void pfnOnPaint0(tWidget *pWidget, tContext *pContext)
{
int x,y;
x=(int)(160*sin(2*(3.1415926)*Angle/360));
y=(int)(160*cos(2*(3.1415926)*Angle/360));
GrContextForegroundSet(&g_sContext, ClrBlack);
GrLineDraw(&g_sContext,160,160,160+x,160-y);
GrLineDraw(&g_sContext,159,160,159+x,160-y);
GrFlush(&g_sContext);
}
//处理三个表盘
void pfnOnPaint1(tWidget *pWidget, tContext *pContext)
{
int Xx,Xy,Yx,Yy,Zx,Zy;
Xx=(int)(81*sin(2*(3.1415926)*XAngle/360));
Xy=(int)(81*cos(2*(3.1415926)*XAngle/360));
Yx=(int)(81*sin(2*(3.1415926)*YAngle/360));
Yy=(int)(81*cos(2*(3.1415926)*YAngle/360));
Zx=(int)(81*sin(2*(3.1415926)*ZAngle/360));
Zy=(int)(81*cos(2*(3.1415926)*ZAngle/360));
GrContextForegroundSet(&g_sContext, ClrBlack);
//画表盘指针
GrLineDraw(&g_sContext,80,81,80+Xx,81-Xy);
GrLineDraw(&g_sContext,240,81,240+Yx,81-Yy);
GrLineDraw(&g_sContext,160,162,160+Zx,159-Zy);
GrFlush(&g_sContext);
}
其实道理很简单,既然我的表盘是半圆,那么我就可以根据角度来计算出画直线(表针)的起始坐标和终止坐标,而且它是随着角度变换的,这就解决了表针的显示问题!!而角度的输入则是由ADC采样再加上标度变换来得到的!
接下来同样的道理,我再添加图形按钮控件:
for (i = 0; i < 4; i++)
{
WidgetAdd(WIDGET_ROOT, g_tWidgetBnt);
}
这就是我添加的
图形按钮控件 :
//定义功能按键
tWidget * g_tWidgetBnt[4] =
{
(tWidget *)&g_sBnt0,(tWidget *)&g_sBnt1,(tWidget *)&g_sBnt2,(tWidget *)&g_sBnt3
};
具体如下:
//定义功能按键
//X按键
ImageButton(g_sBnt0, WIDGET_ROOT,0,0,
&g_sLcdDisplay,
175,195,
BNT_WIDTH, BNT_HIGHTH,
(IB_STYLE_TEXT),
ClrWhite, ClrYellowGreen, ClrBlack,
&BNT_FONT,"X",
g_pucBlueBntUp_45x45,g_pucBlueBntUp_45x45,g_pucBlueBntUp_45x45,
0,0,
0,0,
X_click);
//Y按键
ImageButton(g_sBnt1, WIDGET_ROOT,0,0,
&g_sLcdDisplay,
225, 195,
BNT_WIDTH, BNT_HIGHTH,
(IB_STYLE_TEXT),
ClrWhite, ClrYellowGreen, ClrBlack,
&BNT_FONT,"Y",
g_pucGreenBntUp_45x45,g_pucGreenBntUp_45x45,g_pucGreenBntUp_45x45,
0,0,
0,0,
Y_click);
//Z按键
ImageButton(g_sBnt2, WIDGET_ROOT,0,0,
&g_sLcdDisplay,
275, 195,
BNT_WIDTH, BNT_HIGHTH,
(IB_STYLE_TEXT),
ClrWhite, ClrYellowGreen, ClrBlack,
&BNT_FONT,"Z",
g_pucRedBntUp_45x45,g_pucRedBntUp_45x45,g_pucRedBntUp_45x45,
0,0,
0,0,
Z_click);
//返回按键
ImageButton(g_sBnt3, WIDGET_ROOT,0,0,
&g_sLcdDisplay,
0,195,
170, 20,
(IB_STYLE_TEXT),
ClrWhite, ClrYellowGreen, ClrBlack,
&BNT_FONT,"Back",
back,back,back,
0,0,
0,0,
B_click);
不难看出,他和画布控件函数很相似,同样我利用了它的 点击事件处理凼数:
具体如下:
//定义切换按键
//X按键处理函数
void X_click(tWidget *pWidget)
{
unsigned char i;
Xsingle=1;
for (i = 3; i < 5; i++)
{
WidgetAdd(WIDGET_ROOT, g_tWidgetadc);
}
CanvasImageOff(&g_sadc1);//注意用法
CanvasAppDrawnOff(&g_sadc2);
CanvasImageOn(&g_sadc3);//注意用法
CanvasAppDrawnOn(&g_sadc4);
WidgetPaint(WIDGET_ROOT);
WidgetMessageQueueProcess();
GUI_Reflush();
}
//Y按键处理函数
void Y_click(tWidget *pWidget)
{
unsigned char i;
Ysingle=1;
for (i = 3; i < 5; i++)
{
WidgetAdd(WIDGET_ROOT, g_tWidgetadc);
}
CanvasImageOff(&g_sadc1);//注意用法
CanvasAppDrawnOff(&g_sadc2);
CanvasImageOn(&g_sadc3);//注意用法
CanvasAppDrawnOn(&g_sadc4);
WidgetPaint(WIDGET_ROOT);
WidgetMessageQueueProcess();
GUI_Reflush();
}
//Z按键处理函数
void Z_click(tWidget *pWidget)
{
unsigned char i;
Zsingle=1;
for (i = 3; i < 5; i++)
{
WidgetAdd(WIDGET_ROOT, g_tWidgetadc);
}
//注意用法(要把Canvas每一个属性修改函数看懂)
CanvasImageOff(&g_sadc1);//注意用法(关闭图片)
CanvasAppDrawnOff(&g_sadc2);//注意用法(关闭调用函数)
CanvasImageOn(&g_sadc3);//注意用法(开启调用函数)
CanvasAppDrawnOn(&g_sadc4);//注意用法(开启图片)
WidgetPaint(WIDGET_ROOT);
WidgetMessageQueueProcess();
}
//返回按键处理函数
void B_click(tWidget *pWidget)
{
Xsingle=0;
Ysingle=0;
Zsingle=0;
CanvasImageOff(&g_sadc3);//注意用法
CanvasAppDrawnOff(&g_sadc4);
CanvasImageOn(&g_sadc1);//注意用法
CanvasAppDrawnOn(&g_sadc2);
WidgetPaint(WIDGET_ROOT);
WidgetMessageQueueProcess();
GUI_Reflush();
}
可以看到,每个功能按键的操作都是对画布背景的开关进行处理,从而实现相应的功能!!
接下来是一系列的初始化操作:
WidgetPaint(WIDGET_ROOT);//绘制控件树中的所有控件。
WidgetMessageQueueProcess();//处理所有控件事件。
GUI_Bcaklight_On();
GUI_Reflush();
Touch_Init();//触摸初始化
Touch_Callback_Set(WidgetPointerMessage);//设置回调函数
IntMasterEnable();// 开启中断.
Acc_ADC1_int();//初始化ADC1
然后就可以在while循环里进行相应的判断:
首先是ADC的采样和数据的标度转换部分:
我都放在了ACC.c文件中了,其实道理很简单,参考手册后,可以知道加速度传感器的三轴在静止的时候和加速度一直是1g,那么当z轴为1g的时候,加速度传感器处于水平状态,X和Y与水平夹角都为0,而当有倾角的时候,各个方向的值都产生变化,这时候他们的值和1g可以动过三角函数计算,得到相应的倾角,所需要的值是通过ADC采样在加上标度变换得到的,加速度传感器手册里讲的很清楚,我就不细讲了!
得到了倾角了,我定义了三个变量:
if(Xsingle==1||Ysingle==1||Zsingle==1)
来判断是否为单个表盘
如不是则执行整体表盘的显示,同时得到数值的ASCII码用于在画布上显示!
若是其中的一块表盘则执行相应的程序,具体和整体表盘的程序相差不大!
这个例程让我对M4/M3的Ti图形库有了深刻的了解,同时锻炼了我的编程能力!
整体:
单个: