将“错误”值写入寄存器的函数-PIC18F

时间:2019-03-23 22:43:26

标签: c embedded pic pic18

我编写了一个函数,您应该可以在其中输入数字,然后该函数计算要写入寄存器的值。但是,看起来它正在将“错误的”值写入寄存器。我使用了计算器和wolframalpha来确认我没有弄乱操作顺序。该功能如下:

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

当我尝试将Frequency设置为20kHz(20,000Hz)时,我需要将PR4寄存器设置为32。理论上,如果我将20000插入函数中,则应该吐出,但会吐出179由于某种原因。任何猜测为什么?

MCU:PIC18F67J60 IDE:MP LAB X

1 个答案:

答案 0 :(得分:6)

由于在PIC18中,int类型仅为16 bits,所以C语言中有些神秘的implicit conversion rules会导致表达式的中间结果被截断。令您惊讶的是,您的编译器没有对文字41667000发出警告,因为在任何情况下,该警告显然都不适合PIC18 int类型。

通过使用显式文字类型后缀来更改表达式的整体类型,可以轻松解决该问题:

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

或者如果所需的频率分辨率以KHz为单位,则可以缩放表达式:

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

但是应该注意,在这两种情况下, real 值41667000 /(64 x 20x10 3 ))-1为〜31.55,因此PR4中的值将是31而不是32,并会导致 actual (实际)频率为20345Hz。

舍入为 real 表达式的 nearest 整数值:

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

这将导致PR4 = 32和19729Hz的频率。

让该函数返回实际达到的频率可能会有用:

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

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