Функция, записывающая «неправильное» значение для регистрации - PIC18F - PullRequest
1 голос
/ 24 марта 2019

Я написал функцию, в которой вы должны иметь возможность вводить число, а затем функция вычисляет значение для записи в регистр.Однако похоже, что он записывает «неправильное» значение в регистр.Я использовал калькулятор и wolframalpha, чтобы подтвердить, что я не испорчу порядок операций.Функция перечислена ниже:

void SetFrequency_Hz(int Freq) {
    PR4 = ((41667000 / (4 * 16 * Freq)) - 1);
}

Когда я пытаюсь установить частоту на 20 кГц (20000 Гц), мне нужно установить регистр PR4 на 32. Что в теории, если я добавлю значение 20000в функцию надо выплюнуть, НО по каким-то причинам выплевывает 179.Есть догадки почему?

MCU: PIC18F67J60 IDE: MP LAB X

1 Ответ

6 голосов
/ 24 марта 2019

Поскольку в PIC18 тип int будет иметь только 16 бит , несколько непонятные правила неявного преобразования в C приведут к усечению промежуточных результатов в вашем выражении. Я удивлен, что ваш компилятор не выдал предупреждение для литерала 41667000, так как это явно не будет соответствовать типу PIC18 int в любом случае.

Эту проблему легко решить, используя явные суффиксы литерального типа для изменения общего типа выражения:

PR4 = 41667000ul / (64ul * Freq) - 1u ;

или, если требуемое разрешение по частоте в кГц, вы можете масштабировать выражение:

PR4 = 41667u / (64u * (Freq/1000)) - 1u ;

Следует отметить, однако, что в обоих этих случаях действительное значение 41667000 / (64 x 20x10 3 )) - 1 равно ~ 31,55, поэтому значение в PR4 будет 31, а не 32, и приведет к фактической частоте 20345 Гц.

Чтобы округлить до ближайшего целочисленного значения выражения real :

PR4 = (41667000ul / (32ul * Freq) - 1u) / 2 ;

Это приведет к PR4 = 32 и частоте 19729 Гц.

Может быть полезно, чтобы функция возвращала фактическую достигнутую частоту:

unsigned SetFrequency_Hz( unsigned ideal_freq ) 
{
    PR4 = (41667000ul / (32ul * ideal_freq ) - 1u) / 2u ;

    // Return actual achievable frequency
    return 41667000ul / ((PR4 + 1ul) * 64ul)
}
...