Какой самый быстрый способ сделать деление в C для 8-битных MCU? - PullRequest
0 голосов
/ 30 апреля 2010

Я работаю над прошивкой для устройства, которое использует 8bit mcu (архитектура 8051). Я использую SDCC (Small Device C Compiler). У меня есть функция, которую я использую, чтобы установить скорость шагового двигателя, который ведет моя цепь. Скорость устанавливается путем загрузки нужного значения в регистр перезагрузки для таймера. У меня есть переменная MotorSpeed, которая находится в диапазоне от 0 до 1200, которая представляет импульсы в секунду для двигателя. Моя функция для преобразования MotorSpeed ​​в правильное значение перезагрузки 16 бит показана ниже. Я знаю, что операции с плавающей точкой довольно медленные, и мне интересно, есть ли более быстрый способ сделать это ...

void SetSpeed()
{
    float t = MotorSpeed;
    unsigned int j = 0;
    t = 1/t ;
    t = t / 0.000001;
    j = MaxInt - t;
    TMR3RL = j;      // Set reload register for desired freq
    return;
}

Ответы [ 3 ]

2 голосов
/ 01 мая 2010

Если я правильно понимаю, что происходит, Вы хотите вычислить выражение

MaxInt - 1000000/MotorSpeed

где MotorSpeed ​​- это число от 0 до 1200, представляющее количество импульсов в секунду.

Если ваш компилятор поддерживает арифметику с плавающей запятой, он должен поддерживать целочисленное деление. Почему бы тебе не попробовать это. Если скорость> 15 Нет проблем, но для скоростей в диапазоне от 0 до 15 результат отрицательный. Это означает, что просто невозможно генерировать импульсы с частотой ниже 16 Гц, если счетчик имеет ширину 16 бит и увеличивается на 1 МГц Есть ли у вас дополнительный прескалер, позволяющий уменьшить частоту приращений? (Я не знаю 8051).

1 голос
/ 30 апреля 2010

Классический способ - использовать фиксированную точку, увеличивая масштаб перед делением, и делая все это как целое число.

j = (MotorSpeed * 65536) / 1200;

Это все еще требует фактического деления (на 1200), но, по крайней мере, оно является целочисленным. Масштабирование должно быть очень быстрым, поскольку это можно реализовать с помощью сдвига.

0 голосов
/ 01 мая 2010

Разматывание верно относительно фиксированной точки.

Я написал фиксированную библиотеку для SDCC на 8051, которая использует 32-битные числа. Просто определите, какую точность вы хотите получить в своих дробях, и примените соответствующий сдвиг к значениям.

Например, моя библиотека с фиксированной точкой использует 2 байта для дробного пространства.

Таким образом, каждое число x представляется как x * 65535. Вы можете использовать обычное подписанное длинное сложение и вычитание.

Для умножения и деления вам необходимо скорректировать смещение. Простое умножение даст (x * 65535) * (y * 65535). Просто разбейте и вычтите смещение для каждой части чисел и сложите их все.

Просто разбейте номер с фиксированной точкой на байты или 16-битные и работайте с ними по частям.

Взгляните на эту статью на embedded.com .

...