我收到一条包含原始传感器数据数组的UART消息。我正在程序的主循环中读取消息。我需要PIC处理不同值的两件事。在液晶显示屏上显示它(有点耗时),并且至少在其中一个值之间,根据值更改连接到PORTD的LED条(相当简单)。
在主循环中,这是我目前的工作方式:
使用以下代码在LCD-bar上显示RPM值:
if (RPM < 99)
{
PORTD = 0;
}
if (RPM > 100)
{
PORTD = 0x01;
}
if (RPM > 2400)
{
PORTD = 0x03;
}
if (RPM > 3700)
{
PORTD = 0x07;
}
if (RPM > 4900)
{
PORTD = 0x0F;
}
if (RPM > 6200)
{
PORTD = 0x1F;
}
if (RPM > 7400)
{
PORTD = 0x3F;
}
if (RPM > 8700)
{
PORTD = 0x7F;
}
if (RPM > 10000)
{
PORTD = 0xFF;
}
最后在LCD上显示多个值。因此,删除旧值,绘制标签,设置新值,再次绘制标签。
最后一个任务减慢了整个循环,这使得LED-bar功能变得“滞后”。 我建议在重新绘制标签之前检查值是否已更改,以避免不必要的绘图。但是所有的值都是相当快速变化的值,如RPM等。
欢迎任何建议!!
答案 0 :(得分:2)
进入显示器的数据不需要比观察者能够感知的更快地改变。如果您的更改大于阈值(40到100 Hz),则仅使用上一期间发生的最后一次更改。
int UpdateValue;
int UpdateNeeded = 0;
void TimerServiceRountine() { // called at N (60) Hz.
if (UpdateNeeded) {
UpdateNeeded = 0;
UpdateLCD(UpdateValue);
}
// ...
}
// Call this with each RPM
void UpdateDisplay(int Value) {
UpdateValue = Value;
UpdateNeeded = 1;
}
进一步细化:如果x与之前不同,则只调用UpdateLCD(x)
。
答案 1 :(得分:0)
解决方案理念#1
我的猜测是LCD部件的缓慢是因为您需要等待LCD处理发送给它的命令(与某些字母数字LCD一样)。
否则你的主循环可能会每秒做几千个循环。
如果是这种情况,那么您应该在主循环中为LCD输出实现状态机。只有当LCD准备好接受新命令时,该状态机才会向LCD输出必要的命令,以便逐个更新显示,每次运行主循环一次。
这样你的主循环可以无需等待LCD,而LCD也可以足够快地更新(取决于没有LCD任务的主循环的周转时间是否足够低:最佳低于典型值LCD的“忙”时间。)
解决方案构思#2
如果液晶显示过程由于某种原因(在图形液晶显示屏上按像素工作?)而计算量很大,这会更复杂并适用。
即使是这种情况, Solution#1 的类似方法也可以正常工作。如果您可以将LCD任务拆分为具有大致相似处理时间要求的较小块,则可以加快主循环(仅通过一次处理这些块)。
如果您更喜欢更准确的主要任务时间,那么主要任务需要放入一个中断(假设您从传感器请求数据,您需要一个计时器IT来计时这些请求)。然后主循环只适用于LCD。
常用元素
在所有情况下,您可以进行更多采样,而单个碎片LCD则显示数据构建过程。这需要一些数据管理:在开始构建显示之前,您必须“采样”(主要是复制,在最后一个解决方案中禁用中断)数据进入LCD。
我提出的所有解决方案都是“理想的”,从这个意义上说,他们可以使用所有可用的周期“自动”从硬件“拉出”(在显示更新频率方面)。您只需为您的情况选择合适的方法。