余白 Copyright © 2018-2021 てきーらサンドム


■■■ SAMマイコンの道標(応用編) ■■■


●回路例、注意点

SAMC21-can実験ボード(5版) 2021/12/16 更新
 昨年製作したCAN 2chの実験ボードです(PDF回路図D2CADデータPDF基板図CADLUSX圧縮データ) 。SAMC21J18Aは去年は300円未満で買えたのですが、500円台と値上がりしています。しかも在庫なし。SAMシリーズで在庫があるのはSAME70/V7xという高い品種か古いSAMG55のAバージョンなど。早く供給を正常化して欲しいですね。
 なおこのボードをマイコン技研で販売しています(「紹介ページ」)。
miconhyst027s.jpg miconhyst030ss.jpg
 写真左側:右についている白い基板は、 マイクロチップのデバッガ(Snap)です。PICkit4も同様に直結できます。上側のLCDは秋月で購入したSG12864ASLB-GB(128X64ドット)にL型20pinソケットを付けたものです。
 写真右側:LCDは秋月で購入したAE-AQM1248(128x48ドット)に7pinソケットを付けたものです。ちっちゃいけど何とか漢字が読めます。5Vto3.3V変換基板資料(PDF回路図D2CADデータ)。
 
SAMC20/C21ベース回路(64pin) 2020/7/15 更新
 SAMCのデータシートには、有り難い事に「回路チェックリスト」の章がついています。ここを読めば電源、発振回路、デバッガなど、基本的な回路が分かります。ただしデータシートC版にはPICkit4との接続はまだ載っていませんので、下記回路図はデバッガのマニュアルを参照して描いています。
■SAMC20/C21評価ボード回路図(PDF回路図D2CADデータ 2019/7/28 RS485信号線にPU,PD追加)。基板図(2層115x85mm, PDF基板図CADLUSX圧縮データ 2019/7/28 RS485信号線にPU,PD追加)。CN3から給電し(DCジャック未確認)、PICkit4およびSNAPによるプログラム書き込みできました。UART(460kbps)通信、RS485(460kbps)通信、AD変換、ブザー(任意周波数の方形波出力、メロディ演奏)、スイッチ入力、LED点滅も確認できています(2019/7/28時点)。RS485信号線に追加したプルアップ/ダウン抵抗は相手側についていれば省略可能ですが、本基板同士で通信する場合は必須です。CAN通信もクラシックCANの500kbpsでch0とch1の相互通信を確認してあります。
■上記回路の32.768kHzにはコンデンサと直列抵抗が入っていますが、秋月で売っているVT-200-F 32.768kHz(負荷容量:12.5pF,直列抵抗:50kΩmax)であれば両方ともカタログ上は省略可能なはずです。実際試したところ直列抵抗が必要でした(スタートアップ時間不足が原因かもしれませんので後日レジスタ設定を確認してみます→時間を長くしてもダメでした)。470kΩと15pFのコンデンサx2で良いでしょう(常温で3台実測して+12〜+22ppm、32k発振子は常温で温度偏差ピーク(+側)になるのでちょうどよい感じです)。ただし励振レベルや発振余裕度は未確認なので、量産時は水晶メーカに評価を依頼してください。なお8bit,16bitMCUに比べると発振回路消費電力がやや大きいです。
■上記回路には水晶が2個入っていますが、DPLL(逓倍)のリファレンスとして、32.768kHz, MHz帯のどちらも選択可能なので、一般的には2個付ける必要は無いです。またMHz帯からDPLLを使用する場合は、発振回路の消費電流を下げるために4MHzとか8MHzあたりにしておいた方が良いと思われます(DPLLの入力は2MHz max)。MHz帯発振回路を使う場合、消費電流を下げるためにAGC機能をオンにした方が良いでしょう(最大の32MHz発振で消費電流を比較するとオン/オフで2倍も違う)。
■上記回路では、アナログ電源のフィルタとしてデータシート記載の10μHを載せています。リファレンスボード回路(SAMC21_Xplained_Pro_design_documentation_release_rev5.pdf)ではフェライトビーズが入っており、やはりそちらの方が一般的と思います。
■グラフィックLCD拡張基板の回路図(PDF回路図D2CADデータ)。RL78版で使っていた128x64ドットLCDを上記のコネクタにさせるようにしました。XC32用の漢字フォント生成ユーティリティもベクターに掲載済みです。

■端子割り当て検討用の回路図(旧データ) C21用(PDF回路図D2CADデータ)、C20用(注:データシートB版のピン機能のまま)(PDF回路図D2CADデータ
 
デジタル電源に配置されたアナログ入力端子に注意 2018/12/16 追加
 落とし穴としか言いようが無いのですが、デジタル電源(VDDIO)系ポートなのにアナログ入力に割当て可能な端子があります。64pinの場合はPA8〜PA11が該当します。
■これらのポートはデジタル電源からのノイズの回りこみがありますので、高精度なアナログ入力としては適していません。
 (ノイズフィルタ経由でVDDIOに電源供給することで外来ノイズは防げますが、VDDIO系デジタルポートのスイッチングノイズは防げません)
■SAMC2xを2電源で使用する場合は、これらのアナログ入力範囲をVDDIO電源電圧以内に制限する必要があります。
 

 


●プログラム例: SAMC20/21用

プログラム基本構成 2019/7/22 追加
 何も考えずにmain()に初期化から全部書くこともできますが、せっかくユーザ初期化関数名が用意されているので、これを使うことにします。
 
リセット
スタートアップ・ルーチン(自動組み込み)
startup_atsamc20j18a.c

ユーザー初期化関数
void _on_bootstrap(void)
main関数

 スタートアップの項でも説明しましたが、_on_bootstrap()はC言語初期化後に呼び出される関数名ですので、通常のC言語記述が可能です。
 発振クロック設定、キャリブレーション設定、などの初期設定のほか、共通的に使用するクロックジェネレータ設定、スリープモード設定、ウオッチドッグ設定なども入れられます。
 さらにはmain関数の先頭でいきなりprintf("Start\n");などと標準入出力関数が記述できるようにドライバを組込んでおくこともできます。
 
初期化、共通設定 2019/12/23 赤字部分追記
 リセット後のCPUクロックは4MHzなので大概は変更します。ただしクロックを上げる前にウエイト数を先に変更します。
 さらに必要に応じて外部発振やPLLの設定を行います。以下はレジスタ設定例です(#include <../include/xc.h>の場合)。
 
CPU、バス用クロック(内蔵高速発振)設定
(1)ウエイト数(デフォルト0)変更
 >38MHz時 NVMCTRL->CTRLB.bit.RWS = 2;
 >19MHz時 NVMCTRL->CTRLB.bit.RWS = 1;
(2)GCLK0の分周比(デフォルト1)変更
 GCLK->GENCTRL[0].bit.DIV =
   内蔵高速発振出力周波数 / CPU周波数;
 ただしクロックソース変更時は後で設定。
(3)内蔵高速発振(デフォルト4MHz)変更
 OSCCTRL->OSC48MDIV.bit.DIV =
        48MHz / 出力周波数 − 1;
  必要に応じてGCLK1〜8設定
GCLK->GENCTRL[1〜8].bit.SRC = ソース;
GCLK->GENCTRL[1〜8].bit.DIV = 分周比;
GCLK->GENCTRL[1〜8].bit.OE = 1;
GCLK->GENCTRL[1〜8].bit.GENEN = 1;
ADCキャリブレーション(注参照)
ADC0,ADC1のバスクロックを有効にすること
ADC0->CALIB.bit.BIASCOMP = wk & 0x7;
ADC0->CALIB.bit.BIASREFBUF=(wk>>3)&0x7;
ADC1->CALIB.bit.BIASCOMP =(wk>>6)&0x7;
ADC1->CALIB.bit.BIASREFBUF=(wk>>9)&0x7;
内部32K発振設定
OSC32KCTRL->OSC32K.bit.CALIB =
         (wk >> 12) & 0x7F; //注参照
OSC32KCTRL->OSC32K.bit.ENABLE = 1;
OSC32KCTRL->OSC32K.bit.EN32K = 1;
ウオッチドッグ開始
WDT->CONFIG.bit.PER = 7; //約1秒.
WDT->CTRLA.reg = WDT_CTRLA_ENABLE;
外部32K発振設定
OSC32KCTRL->XOSC32K.bit.XTALEN = 1;
OSC32KCTRL->XOSC32K.bit.ENABLE = 1;
OSC32KCTRL->XOSC32K.bit.EN32K = 1;
スリープ設定(IDLEに設定。CPU,バスのみ停止)
PM->SLEEPCFG.bit.SLEEPMODE = 0x02;
PLL設定(VCO=48MHz設定、外部32K基準)
OSCCTRL->DPLLRATIO.bit.LDR = 1463;
OSCCTRL->DPLLRATIO.bit.LDRFRAC = 14
OSCCTRL->DPLLPRESC.bit.PRESC =
  VCO周波数 / 出力周波数 − 1;
空きピンの出力設定
 空きピンを出力にする場合など、他に適当な
 設定ソースが無い場合は、ここで設定します。
 (「ポートの設定」参照)
 注:キャリブレーションデータは、あらかじめ変数wkに格納してあるものとします。
    wk = *(unsigned long*) 0x806020; //チップがリビジョンDでない場合(内部32KとADCのみ対象)。
    wk = *(unsigned long long*) 0x806020; //チップリビジョンD。内蔵高速発振も対象。

なおウオッチドッグをリセットするには以下のように記述します。
  WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;
またスリープするには、以下のように__haltマクロを定義しておくと分かりやすいでしょう。
  #define __halt() asm("WFI")
 
ポートの設定 2019/7/22 追加
 ピンごとにIOの設定を行います。ピン名称PA00〜31,PB00〜31に対してピン定義名はPIN_A00〜31, PIN_B00〜31となっており、値としては連番で0〜63が定義されています。またPORT_A00〜31, PORT_B00〜31には1 << (PIN_xxx & 0x1f)が定義されています。
 ポートとして使う各ピン(PIN_xxx)は以下の3行で設定できます。
   PORT->Group[PIN_xxx >> 5].OUTyyy.reg = PORT_xxx;
   PORT->Group[PIN_xxx >> 5].DIRzzz.reg = PORT_xxx;
   PORT->Group[PIN_xxx >> 5].PINCFG[PIN_xxx & 0x1f].reg = d;
 ここで、yyy,zzz,dは下表のようになります。 
項目 出力設定
(初期値0)
出力設定
(初期値1)
入出力設定
(初期値0)
入出力設定
(初期値0)
入力設定
(Hi-z)
入力設定
(プルダウン)
入力設定
(プルアップ)
yyy CLR SET CLR SET 不要 CLR SET
zzz SET SET SET SET CLR CLR CLR
d 0 0 2 2 2 6 6
注:*印はリセット後のデフォルト状態から変更してなければ設定不要。

 以降、設定したポートへ出力するには、以下のように記述します(実際にはマクロ定義して記述を短縮する方が良いでしょう)。
   PORT->Group[PIN_xxx >> 5].OUTCLR.reg = PORT_xxx; //0を出力
   PORT->Group[PIN_xxx >> 5].OUTSET.reg = PORT_xxx; //1を出力
 また入力は、32bit単位ならPORT->Group[PIN_xxx >> 5].IN.reg で良いのですが、ビット判定もしくはビット取出しする場合は以下の記述になります。
   PORT->Group[PIN_xxx >> 5].IN.reg & PORT_xxx          //ビット判定用。対象ビットが0なら0, 1なら非0。
   (PORT->Group[PIN_xxx >> 5].IN.reg >> (PIN_xxx & 0x1f) ) & 1 //ビット取出し
 
各周辺の設定手順概要 2019/7/22 追加
 以下の順に設定します。
(1)クロックジェネレータの設定
  クロック供給が必要な周辺機能を使う場合、GCLK0〜8のどれかを選択します。初期化のところで設定してないGCLKを使う場合は、まずそれを設定します(設定方法は初期化参照)。
(2)クロックジェネレータの指定
  「クロック生成(GCLK)」項のクロック供給先一覧から周辺ch番号を探し、以下の設定を行います。
   GCLK->PCHCTRL[周辺ch番号].bit.GEN = 使用するクロックジェネレータ番号;
   GCLK->PCHCTRL[周辺ch番号].bit.ENABLE = 1;
(3)バスクロックの供給
  周辺機能を制御するレジスタをアクセスするには、上記のクロックではなくバスクロックを供給する必要があります。
  「クロック生成(GCLK)」項のバス・クロック供給の表から対象を選択し、以下の設定を行います。
   MCLK->xxxMASK.bit.yyy = 1;
  ここで、xxxは表のbit欄の.より前、yyyは後ろ側を記載します。なお、表の対象欄に*印がある周辺機能はデフォルトで1になっているので設定不要です。
(4)周辺機能のレジスタ設定
  各周辺に固有の設定を行います。
(5)ポートの設定
  周辺機能の入出力信号をピンに結びつけるには、以下の設定をします。
   PORT->GroupPIN_xxx >> 5].PMUX[(PIN_xxx & 0x1f)>>1].bit.PMUXE = map; //偶数ピンの場合
   PORT->Group[PIN_xxx >> 5].PMUX[(PIN_xxx & 0x1f)>>1].bit.PMUXO = map; //奇数ピンの場合
   PORT->Group[PIN_xxx >> 5].PINCFG[PIN_xxx & 0x1f].bit.PMUXEN = 1;
  ここで、mapはデータシートのIO Multiplexingの表のA列〜I列に対応する0〜8の数字になります。
  また、周辺によってはIOポート設定も必要になる場合があります(例えばGCLKの入力、出力のどちらを結びつけるかをIOポート設定で選択)。
(6)多重割込み(NVIC)設定
  周辺機能からの割込みを許可する場合、「多重割込制御(NVIC)」の項の割込みソース対応表から番号を読取り、以下の設定を行います。
    NVIC->IP[割込ソース番号 >> 2] |= 優先度 << ((割込ソース番号 & 0x3) * 8); //優先度は8bit(Cortex-M0+は 0,64,128,192のみ)を設定
    NVIC->ISER[割込ソース番号 >> 5] = 1 << (割込ソース番号 & 0x1f);      //割込み許可(割込数が32を超えるMCUと記述共通化)
 
SAMC21_can4テストプログラム 2020/2/29 更新
 ベクターに掲載中です。Harmony(v3)は使っていません。とりあえずSAMC21_can4評価ボードの動作確認用という位置付けになります。以下は、プログラムの説明書に記載してない補足説明になります。
(1)不具合事項
  CAN通信とシリアル通信を同時に行うと、シリアル通信側にたまに文字化けが出ます。CAN0-CAN1間のコンフリクト頻度が下がると文字化けの頻度も下がるので、CANコントローラから共用資源であるRAMへのアクセスがぶつかって影響が出るのかもしれません。
(2)搭載漢字フォント
  ROMが余っているので5362文字分(157KB)のフォントを載せています。減らしたい場合は、漢字フォント生成ユーティリティ(公開済み)を使ってFont.incを差し替えてください。
(3)XC32 v2.40対応
  特に問題なくビルドできます。オブジェクト・サイズが17Kバイト減少しました。RAM使用量は2Kバイト減少しています。さらにスタックの使用量も150バイトぐらい減っているようです。いずれもC言語ライブラリの改良によるものだと考えられます。
 
割込フラグの立ち方 2019/6/9 追加
 RL78とか使っている人が落ちやすい(と思われる)のが、割込フラグの立ち方です。
 多重割込制御(NVIC)側は、割込要求フラグの名前が”ペンディング”になっているので名前がしっくりきませんが、機能としてはRL78と大差ありません。
 違いがあるのは周辺回路側で、SAMの周辺回路は割込許可されてないと要求フラグが立ちません。
 つまり割り込みされたくない、ポーリングで監視したいって場合は、周辺回路側の割込イネーブルは許可にし、NVIC側を不許可にするしかありません。
 じゃ、割込みさせたいフラグとポーリングしたいフラグが同居している場合はどうするかというと、結局両方割込処理するしかありません。ポーリングの方は割込処理中にポーリング用のフラグを立てるようにします。