AT SAMの部屋(14) XiaoでもGo!machine.TCC1使用、PWM出力

Joseph Halfmoon

Go言語でMCUのコードを生成できるTinyGoでATSAMD21マイコンの周辺回路を勉強しております。前回までunsafeなポインタを使って直接アクセスする不作法をしてました。今回は machine モジュールを使ってTCC1からPWM波形を出力してみます。制御は簡単なのですが、データシートを読むのがメンドイ。

ATSAMD21マイコンのタイマ・カウンタ

Arm Cortex-M0+コア搭載、MicroChip社のATSAMD21は32ビットマイコンとしてはローエンド品種だと思いますが、モダーンなマイコンの通例に漏れずタイマ・カウンタ類は充実しています。TCC(TIMER / COUNTER FOR CONTROL )と表記される入出力機能が充実したゴージャスなタイマ・カウンタを3本。TC(TIMER/COUNTER)と表記される、主に基本的なタイマ/カウンタとして使うけれども入出力もできるものが5本あります。それらには連番が振られています。

    • TCC0~TCC2
    • TC3~TC7

TCCは24ビットのカウンタ1本に対して、4チャネルのコンペア・キャプチャ(CC)を持っています。各チャネルは所定の外部出力端子に接続できるので、TCCを全てPWMに使うとすると4チャネルx3本で最大12端子まで可能です。

一方、TCは基本16ビットのカウンタで、半分の8ビット使いも可能。また2本を組み合わせて32ビットとしても使えるようになっています。各TCには、TCCのものより機能は落ちますがコンペア・キャプチャ(CC)2チャネルがあるので入出力も可能です。こちらを数えれば2x5で10チャネルとな。

出力についてはTCCもTCもチャネルと外部端子の対応関係はハードで決まっています(ただし多対多の関係。)

入力機能はATSAMD21のもつ近代的な制御ハードEVSYS経由でイベントと結び付けられるので出力のようなキメウチでもないようです。また後でEVSYSも動かしてみます。

Seeduino Xiaoボード上で出力に使えるタイマ・チャネル

上記のように充実したATSAMD21のタイマ・カウンタ機能なのですが、出力に限ると実際に使えるタイマは限られます。まずXiaoボードに搭載されているATSAMD21G18は48ピンの比較的小ピンの品種です。出ていない端子があります。さらに超小型のXiaoボードです。使用できるデジタルピンの数はたかだか11端子のみ。

そこでXiaoボードの端子名とATSAMD21マイコンのPIN名、そしてそれらピンに出力可能なカウンタ/タイマとそのチャネル名を以下にまとめました。例えば

TCC0/WO[0]

とかかれていたら、TCC0 のチャネル0の出力をその端子に出力できるという意味です。Func E と Func Fと2つの列がありますが、これは前回も出て来たPMUXレジスタの行き先選択で使える選択肢です。TinyGoの「定数」とは以下のような関係となります。

  • Func E、PinMode=4 あるいは PinTimer または PinTCC
  • Func F、PinMode=5 あるいは PinTimerAlt または PinTCCAlt
Xiao端子名 ATSAMD21G18 pin名 Func E Func F
D0 PA02
D1 PA04 TCC0/WO[0]
D2 PA10 TCC1/WO[0] TCC0/WO[2]
D3 PA11 TCC1/WO[1] TCC0/WO[3]
D4 PA08 TCC0/WO[0] TCC1/WO[2]
D5 PA09 TCC0/WO[1] TCC1/WO[3]
D6 PB08 TC4/WO[0]
D7 PB09 TC4/WO[1]
D8 PA07 TCC1/WO[1]
D9 PA05 TCC0/WO[1]
D10 PA06 TCC1/WO[0]
今回実験のソースコード

以下のような設定でPWM信号を出力してみます。

    • 外部出力端子 D3
    • 使用するタイマ・カウンタは TCC1、チャネルは1番
    • 周波数 100kHz
    • デューティ 25%

ソースコードが以下に。

package main

import (
    "fmt"
    "machine"
    "time"
)

func main() {
    counter := 0
    pwmOut := machine.D3
    pwmOut.Configure(machine.PinConfig{Mode: machine.PinTimer})
    machine.TCC1.Configure(machine.PWMConfig{Period: 10000})
    ch, _ := machine.TCC1.Channel(machine.D3)
    machine.TCC1.Set(ch, (machine.TCC1.Top() / 4))
    for {
        counter++
        fmt.Println(ch, counter)
        time.Sleep(1000 * time.Millisecond)
    }
}
実機動作確認

D3端子に出力された波形を観察したものが以下に。ほぼ100kHz、25%デューティとなってます。

PWM_WAVEFORM

今回はunsafeなポインタ使わなかった。よかった?また次回は分かりませぬが。

AT SAMの部屋(13) XiaoでもGo!XOSC32K、32Kクリスタルの発振ON へ戻る

AT SAMの部屋(15) XiaoでもGo!TinyGoのRTC設定状況と周波数補正 へ進む