【发布时间】:2015-08-15 19:43:07
【问题描述】:
我正在 Nordic Micro 中创建一个项目,该项目从模拟输入终端读取值并将其输出到 UART。我现在正在尝试使用 GE Proficy Historian Compression 压缩数据,以便在 UART 中仅输出更改的数据。但是我的代码不起作用。输出的数据有时仍然是多余的。 该程序的想法是每隔一定时间产生一个中断,读取 adc 值,如果它与之前的值不同,则将其输出到 UART 端口。 该算法在这里解释 http://www.evsystems.net/files/GE_Historian_Compression_Overview.ppt 处理中断的主要部分代码如下所示
void ADC_IRQHandler(void)
{
/* Clear dataready event */
NRF_ADC->EVENTS_END = 0;
// write ADC value to UART port
// Compression Algorithm should occur here
uint8_t current_Val= NRF_ADC->RESULT;
//simple_uart_put(current_evaluation);
// Construct error bands around the held point
float U_tolerance = current_Val + error_tolerance;
float L_tolerance = current_Val - error_tolerance; // integer type is selected since lower tolerance could be negative
if( first_Run == false)
{
float slope = ((current_Val - Archived_Val) / (held_Time - Archived_Time)) ;
if (slope > U_Slope || slope > L_Slope)
{
Archived_Val = current_Val; // update the archived value
held_Time = 1; // reset held time
simple_uart_put(current_Val);
first_Run = true;
Archived_Val = current_Val;
}
else
{
float Upper_Slope = (U_tolerance - Archived_Val) /( held_Time - Archived_Time);
float Lower_Slope = (L_tolerance - Archived_Val)/(held_Time- Archived_Time);
if(Upper_Slope < U_Slope) // lowest upper slope is always taken as a blanket boundry
{
U_Slope = Upper_Slope;
}
if(Lower_Slope < L_Slope)
{
L_Slope = Lower_Slope;
}
held_Time += time_increment;
}
}
if (first_Run == true) // first held point always outputted
{
// calculate the slopes of the two lines
float Upper_Slope = (U_tolerance - Start_Up_Val) /( held_Time - Archived_Time);
float Lower_Slope = (L_tolerance - Start_Up_Val)/(held_Time- Archived_Time);
// Update Max and Min slopes
if(Upper_Slope < U_Slope) // lowest upper slope is always taken as a blanket boundry
{
U_Slope = Upper_Slope;
}
if(Lower_Slope < L_Slope)
{
L_Slope = Lower_Slope;
}
held_Time += time_increment;
first_Run = false;
Archived_Val = current_Val;
}
}
veriables 定义如下
> uint32_t error_tolerance = 50; // error tolerance value for swining door algorithm
uint8_t Start_Up_Val = 100;
float held_Time = 1;
int Archived_Time = 0;
float U_Slope = 2500;
float L_Slope = 0;
//float slope;
uint8_t Archived_Val;
bool GE_Comp(uint8_t, uint8_t, uint8_t, int);
bool first_Run = true;
float time_increment = 0.1;
【问题讨论】:
-
你展示的代码有什么问题?它不会建立吗?它会崩溃吗?它会给出错误的结果吗?请详细说明。也请read about how to ask good questions,并学习如何创建Minimal, Complete, and Verifiable Example。
-
您的中断处理程序试图实现太多功能。它的执行时间是多少?在嵌入式环境的中断中实现
float计算通常是完全不可以的。 -
在设置float变量时,设置值也应该是float。 IE。每个文字浮点值都应包含一个小数点“。”和一个尾随的“f”,例如:float U_Slope = 2500.f;浮动 L_Slope = 0.f;和浮动时间增量 = 0.1f;
-
中断处理程序中的代码似乎太多了。建议:使用互斥锁。在中断处理程序中,如果时间戳不明确,则标记数据溢出错误。否则,在某个全局变量中设置新值并设置时间戳。在主函数中,查看时间戳。当时间戳改变时,检索全局变量和时间戳。然后清除时间戳。然后执行所需的处理。
-
@Raiyans 这不是解决问题的方法。中断将在中断开始时被禁用。如果还有其他具有相同或更低优先级的中断,则在您的中断完成之前不会为它们提供服务。正如其他人评论的那样,解决这个问题的方法是从 IRQ 处理程序中删除大部分权重。然后,它会将原始 ADC 输入值简单地发布到
main(),其中循环将检测更改并重新计算 ADC 计数器值对用户的意义。
标签: c embedded compression nrf51