PR

ATtiny402、TCBを使った高速PWM

ATtiny402のPWM周波数(megaTinyCore)

ATtiny402をArdino IDE(+megaTinyCore)の環境でクロック20MHzとして使った場合、PWM(analogWrite())の周波数は約1.25kHzのようだ(上の写真で抵抗器は抵抗としては無関係。単にオシロのプローブで掴む端子として使っている)。おそらく、クロックを64分周して使用しているのだろう。20MHz÷64÷256=1220.70Hz。256はPWMの分解能。なので、公称値としては約1.2kHzというところか?

PWM出力ピン

TCA0

megaTinyCoreのATtiny402ではPWMは四つ出せることになっている。1(PA7)、2(PA1)、3(PA2)、4(PA3)。

これらは四つともTCA0による出力(WO0~3)。

TCB0で高速PWM

上の表には、TCB0にもWOがある。対応するピンはPA6。

より高速なPWMを出してみようと思うが、TCA0はおそらくmegaTinyCore内部で使っているだろうから、TCA0は触らないほうが無難。ということで、TCB0を使ってやってみる。

こう書くと順序だってやったみたいけど、実際はこんなにはスマートじゃない。PWM出力は1(PA7)、2(PA1)、3(PA2)、4(PA3)のいずれかだと思っていたのに、TCB0のPWMはPA6に出力されて悩んだ。なぜPA6に出力されるのか、また、他のピンに出すにはどうすればよいのかと、TCBによる出力のピンの割り当て方法をデータシート等で調べたがわからない。あちこち見て、ようやくTCB0による信号出力がPA6に固定されていることを上の表で見つけた。つまり、TCB0を使ったPWM出力はmegaTinyCoreの預かり知らぬことで、当然、この出力にはanalogWrite()は使えない。

約79kHz。計算上は、20MHz÷256=78.125kHz。

以下がコード。

void setup() {
  TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm; // TCB0 enabled, CLK_PER/1
  TCB0.CTRLB = TCB_CCMPEN_bm | TCB_CNTMODE_PWM8_gc; // Single slope PWM, CCMPEN enabled
  TCB0.CCMPL = 255; // Set TOP value
  TCB0.CCMPH = 127; // Set duty cycle CCMPH/CCMPL
  PORTA.DIR |= PIN6_bm; // TCBによる信号出力はPA6(pin 2)に固定されている(書かなくても出力された)

  pinMode(PIN_PA1, OUTPUT);	// pin 4、これは比較用の通常PWM出力
  analogWrite(PIN_PA1, 127);
}

void loop() {
}

anlogWrite()は使えないので、レジスタを直接いじる。コードはBing AIとチャットしながら書いた(書いてもらった)。間違いも非常に多い(analogWriteFrequency()を使えと言ってきたり。そんな便利なものはmegaTinyCoreにはない)ので、動くまでにはかなり苦労した。「出来は良いとは言えないが、従順なアシスタント」という感じ。


こういうちょっとした確認にはDSO-TC3が手軽で便利。


コメント