こんにちは。通りすがりです。
今日、たまたま同じようなことをしていました。
mega168pで、$crystal = 8000000、$baud = 115200 とすると、 UCSR0A.U2X = 1 UBRR = 8 と設定され、誤差が-3.5%となりました。これはコンパイルリザルトから確認できます。 3.5%なので、条件によっては受信できなくなるでしょう。実際、通信できませんでした。 データデータシートによると8N1、U2X=1のとき、推奨誤差は+/-1.5%だそうです。
しかし、3.5%しかないと考えれば、OSCCALを調整すればよいのではと思い、 OSCCAL = OSCCAL + n として、CLKOを有効にして周波数カウンタで確認しながら調整するとおよそ1%以内に 簡単に入りました。nが1あたり数十kHz程度可変できました。データシートにosccalの値と 周波数の関係グラフが載っています。 (なお、内蔵RC-OSCはスペクトル拡散のためかジッタがかなりあります。)
その後、$crystal = 8294400(およその実際の周波数)としておけば、その他のwaitなど クロックに影響するものの誤差も少なくなるでしょう。あくまでも、内蔵RC-OSCなので、 電圧や温度などから影響を受けますので安定性について留意が必要ですが、今日使った限り (非業務用途)では問題ありませんでした。
ご賢察のとおり、本来は適切な周波数の水晶発振を使用すべきですね。
ご参考になりましたら
[No.17] 2026/10/17(Sat) 19:01:31 |