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.

[参考译文] EK-TM4C123GXL:小工具绘制无限循环

Guru**** 2330840 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/595196/ek-tm4c123gxl-widget-paint-infinite-loop

器件型号:EK-TM4C123GXL

我正在尝试制作一个标题 widgetStructt、它将显示多个读数、如基准、反馈、运行/停止、本地/远程控制。  我仍在详细介绍所有细节、但现在我正在尝试用一种好方法替换停止/运行的内容(如果检测到更改、请先打印黑色矩形、然后打印新状态)、然后我运行到无限循环中。  以下是我的相关代码(或我认为至少相关的代码...):

主程序


tContext sContext;
bool StartStop=true;
bool StartStop_Last=true;
bool LocalRemote_true;
bool LocalRemote_Last=true;

extern void sample (void);


int main (void)
{

FPUEnable();
FPULazyStackingEnable();

//将系统时钟初始化为80MHz
SysCtlClockSet (SYSCTL_SYSDIV_2|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHz|SYSCTL_OSC_MAIN);

Kentec320x240x16_SSD2119Init(); //屏幕初始化
initialize();
//
//初始化触摸屏驱动程序并将其消息路由到
//小工具树。
//
TouchScreenInit();
TouchScreenCallbackSet (WidgetPointerMessage);

//
//将标题块以及上一个和下一个按钮添加到控件中
//树。
//
WidgetAdd (widget_root、(tWidget *)&g_sPrevious);
WidgetAdd (widget_root、(tWidget *)&g_sNext);

//
//将第一个面板添加到小部件树中。
//
G_ulPanel = 0;
WidgetAdd (widget_root、(tWidget *) g_psPanel);
WidgetAdd (widget_root、(tWidget *) g_psHeader);

//
//向小工具发出初始喷漆请求。
//
WidgetPaint (widget_root);

//启用所有中断
IntMasterEnable();

//开始表演的时间!
// TimerEnable (TIMER2_base、timer_both); //启用 Timer2以更新屏幕
// TimerEnable (Timer1_base、timer_both); //启用 Timer1以获取样本读数

//
//循环永久处理小工具消息。
//
while (1)
{
//
//处理小组件消息队列中的任何消息。
//
WidgetMessageQueueProcedess();
}
} 

标题不同部分的画布定义:

//
//
//标题信息的帆布
画布//
//********


画布(g_sStatus、g_psHeader、0、0、&g_sKentec320x240x16_SSD2119、 120、
2、200、22、canva_style_app_elved_、0、 0、
0、0、0、0、状态);
画布(g_SFB、g_psHeader、&g_sStatus、0、&g_sKentec320x240x16_SSD2119、 80、
2、75、22、canva_style_text|canva_style_text_left、0、 0、
ClrRed、&g_sFontCmss16b、"FB:"、0、0);
画布(g_sRef、g_psHeader、&g_SFB、0、&g_sKentec320x240x16_SSD2119、 2、
2、75、22、canva_style_text|canva_style_text_left、0、 0、
ClrRed、&g_sFontCmss16b、"Ref:"、0、0); 

用于收割台画布结构的 tCanvasWidget:


//
//标题的画布小工具数组。
////
*********


tCanWidget vasg_psHeader[]=
{
CanvasStruct(0)、&g_SFB、&g_sRef、&g_sKentec320x240x16_SSD2119、0、 0、
320、24、canva_style_fill | canva_style_outline、ClrBlack、ClrRed、 0、0、0、0)、

}; 

用于显示和更新标题栏的"状态"功能:


空状态(tWidget * pWidget、tContext * pContext){
tRectangle sRect_CLR;
GrContextFontSet (pContext、&g_sFontCms14b);

环境 ForegroundSet (pContext、ClrRed);
GrStringDraw (pContext、"Stopped"、-1、
185、5、0);

环境 ForegroundSet (pContext、ClrLawnGreen);
GrStringDraw (pContext、"local"、-1、
270、5、0);
if (StartStop_Last!= StartStop){
sRect_CLR.i16XMin = 180;
sRect_CLR.i16YMin = 2;
sRect_CLR.i16XMax = 250;
sRect_CLR.i16YMax = 20;

if (StartStop){
环境 ForegroundSet (pContext、ClrBlack);
GrRectFill (pContext、&sRect_CLR);
环境 ForegroundSet (pContext、ClrLawnGreen);
GrStringDraw (pContext、"正在运行"、-1、
185、5、0);

}

if (!StartStop){
环境 ForegroundSet (pContext、ClrBlack);
GrRectFill (pContext、&sRect_CLR);
环境 ForegroundSet (pContext、ClrRed);
GrStringDraw (pContext、"Stopped"、-1、
185、5、0);
}
StartStop_Last=StartStop;
};
if (LocalRemote_last!= LocalRemote){

if (LocalRemote){
环境 ForegroundSet (pContext、ClrLawnGreen);
GrStringDraw (pContext、"local"、-1、
270、5、0);
}

if (!LocalRemote){
环境 ForegroundSet (pContext、ClrYellow);
GrStringDraw (pContext、"remote"、-1、
270、5、0);
}
};
} 

我发现、如果我将标题的'WidgetAdd'语句移动到第一个面板/屏幕的'WidgetAdd'语句上方、那么我不会遇到这个无限循环问题。  我尝试单步执行反汇编以查看调用'Status'函数的内容、但我无法找到它。  如果切换'WidgetAdd'语句的顺序可以解决问题、那么我倾向于认为 Stellaris 图形库的某些部分默认为无限循环。  

我确认切换顺序(标题和面板)时面板1屏幕不是无限循环、因为我可以获得上升沿检测中断和 LED 点亮。  我检查了矢量表、以确保没有调用'Status'函数的中断。  我不会、我认为无论如何从中断表中调用 widget 函数是不可行的。

如果我切换'WidgetAdd'的顺序、这样我就不会得到一个无限循环、那么调用'Status'函数时遇到问题。  有人能给我一些关于最好的方法的建议吗?  我尝试让计时器中断触发一个 void ScreenUpdate (void)函数、该函数随后将调用"Status"函数、但我在该路由中没有遇到任何幸运。

我未显示的其余代码完全基于 Lab10代码、我一直在缓慢构建和测试自己的小工具和面板。

谢谢