Sam*_*m W 1 c embedded pic pic18
我编写了一个函数,您应该可以在其中输入数字,然后该函数计算要写入寄存器的值。但是,看起来它正在将“错误的”值写入寄存器。我已经使用了计算器和wolframalpha来确认我没有弄乱操作顺序。该功能如下:
void SetFrequency_Hz(int Freq) {
PR4 = ((41667000 / (4 * 16 * Freq)) - 1);
}
Run Code Online (Sandbox Code Playgroud)
当我尝试将Frequency设置为20kHz(20,000Hz)时,我需要将PR4寄存器设置为32。理论上,如果我将20000插入函数中,则应该吐出,但是它会吐出179原因。任何猜测为什么?
MCU:PIC18F67J60 IDE:MP实验室X
由于在PIC18中int类型只有16位,因此C语言中有些晦涩难懂的隐式转换规则将导致表达式的中间结果被截断。令您惊讶的是,您的编译器没有对文字41667000发出警告,因为int在任何情况下,该警告显然都不适合PIC18 类型。
通过使用显式文字类型后缀更改表达式的整体类型,可以轻松解决此问题:
PR4 = 41667000ul / (64ul * Freq) - 1u ;
Run Code Online (Sandbox Code Playgroud)
或者,如果所需的频率分辨率以KHz为单位,则可以缩放表达式:
PR4 = 41667u / (64u * (Freq/1000)) - 1u ;
Run Code Online (Sandbox Code Playgroud)
但是,应注意的是,在这两种情况下,实际值41667000 /(64 x 20x10 3))-1为〜31.55,因此PR4中的值为31而不是32,将导致实际频率为20345Hz。
舍入到最接近实数表达式的整数值:
PR4 = (41667000ul / (32ul * Freq) - 1u) / 2 ;
Run Code Online (Sandbox Code Playgroud)
这将导致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)
}
Run Code Online (Sandbox Code Playgroud)