Посвящаю эту тему вопросам оптимизации существующего алгоритма обработки датчика положения коленвала (ДПКВ). Смотреть файл ckps.c
Первая часть алгоритма, которая требует оптимизации это 32-х битное деление, добавляющее к времени обработки прерывания 25...40мкс.
Тут viewtopic.php?f=52&t=1238&start=50 участник по имени teuer предложил замену:
- OCR1A = GetICR() + ((uint32_t)diff * (ckps.period_curr)) / ANGLE_MAGNITUDE(CKPS_DEGREES_PER_COG);
+ OCR1A = GetICR() + (((((uint32_t)diff * (ckps.period_curr))>>8) * 0x15556)>>16);
Чтобы проверить его версию, я написал специальную программку на С. Ее я компилировал и запускал на настольном компьютере. Программка перебирает все возможные комбинации входных параметров и строит гистограмму ошибок.
Предложенный вариант непригоден к использованию, так как дает очень много ошибок.
Код программы:
Code: Select all
#include <stdio.h>
#include <stdint.h>
#include <string.h>
int main(void)
{
uint16_t value_1;
uint16_t value_2;
uint16_t ICR = 1024;
uint16_t p_c = 5076;
uint16_t diff = 8234;
#define ERR_MAX 256
uint32_t errors[ERR_MAX+2];
memset(errors, 0, sizeof(int)*(ERR_MAX+2));
int i,j;
uint32_t max_error = 0;
//collect statistics
for(i = 0; i < 65536; ++i)
{
for(j = 0; j < 65536; ++j)
{
diff = i, p_c = j;
//-------------------------------------------------------------------
value_1 = ICR + ((uint32_t)diff * p_c) / (32*6);
value_2 = ICR + (((((uint32_t)diff * p_c)>>8) * 0x15556)>>16);
//-------------------------------------------------------------------
if (value_1 != value_2)
{
uint32_t error = abs((int32_t)value_1 - (int32_t)value_2);
if (error > max_error)
max_error = error;
// printf("%u ", (int)error);
if (error > ERR_MAX)
error = ERR_MAX;
errors[error]++;
}
}
}
//print statistics
printf("\nerrors flow:\n");
for(i = 1; i < ERR_MAX+1; ++i)
printf("%u ", (int)errors[i]);
printf("\n");
printf("max. detected error = %u\n", max_error);
}