概要
今回は、強化されたDMAモジュールの使い方をご紹介します。
DMAとはDirect Memory Accessの略でCPUのリソースを使用せずに、RAMやペリフェラル間のデータ転送を実行するモジュールです。
以前の記事( DACとDMAモジュールの使い方(任意波形出力編) – ぴくおの電子工作的な何かWP (electricpico.com) )で紹介したように、従来のdsPICシリーズにもDMAモジュールは搭載されていました。しかし、dsPIC33AKシリーズでは、さらに強化されたDMA機能が搭載されています。
以下にその特徴を示します。
・6つの独立したチャンネル
・CPUとの同時動作(DMAによる待機状態なし)
・固定優先順位とラウンドロビン方式によるDMAバス調停
・4つのアドレスモード
・4つの転送モード
・ピンポン・モード(各ブロック転送完了後に2つのチャネルを自動切り替え)
・データ転送のための8ビット、16ビットまたは32ビットワード・サポート
・各チャンネルに24ビットの送信元および宛先アドレス・レジスタを搭載。
・32ビット・トランザクション・カウント・レジスタ。
・上下限アドレス・レジスタ
・カウンタ・ハーフ/フル・レベル割り込み
・ソフトウェア・トリガー転送
・対称バッファ・オペレーションのためのヌル・ライト・モード
・各チャネルのDMAリクエストは、サポートされた割り込みソースから選択可能
・チャネル・チェイニングと呼ばれるチャネルのデイジー・チェイニングのサポート
・セット/クリア/反転ビット操作機能
・パターン・マッチ
・バス・リード/ライト・エラー障害表示
今回は基本的な使い方から実践的な使い方まで紹介します。
記事変更履歴
| 公開/ 変更日 | 特記 |
| 24/08/11 | 初版公開。 |
| 25/11/15 | Ping-Pongモードについて注記追加 |
関連記事
| 記事 | リンク | |
| 第1回 | dsPIC33AKシリーズについて | dsPIC33Aシリーズに関して – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第2回 | 開発ボード、コンフィグレーション設定、クロック設定について | dsPIC33AKシリーズ②開発ボード,コンフィグレーション設定,クロック設定について – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第3回 | CPU性能について | dsPIC33AKシリーズ③CPU性能について – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第4回 | FPU性能について | dsPIC33AKシリーズ④FPU性能について – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第5回 | DSPについて | dsPIC33AKシリーズ⑤DSPについて – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第6回 | タイマー1割り込みの使い方 | dsPIC33AKシリーズ⑥Timer1割り込みの使い方 – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第7回 | PMUの使い方 | dsPIC33AKシリーズ⑦PMUの使い方 – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第8回 | 高速ADCの使い方 | dsPIC33AKシリーズ⑧高速ADCの使い方 – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第9回 | 高速OPAMPの使い方 | dsPIC33AKシリーズ⑨高速OPAMPの使い方 – ぴくおの電子工作的な何かWP (electricpico.com) |
| 第10回(本記事) | DMAモジュールの使い方 | dsPIC33AKシリーズ⑩DMAモジュールの使い方 – ぴくおの電子工作的な何かWP |
開発環境
開発環境を以下に示します。
今回はどちらのCPUボードでも動作いたします。
| 項目 | 値 | リンク |
| ベースボード | dsPIC33A CURIOSITY PLATFORM DEVELOPMENT BOARD | dsPIC33A Curiosity Platform Development Board User’s Guide (microchip.com) |
| CPUボード(EV68M17A) | EV68M17A – dsPIC33AK128MC106 Motor Control DIM | dsPIC33AK128MC106 Motor Control Dual In-Line Module (DIM) Information Sheet (microchip.com) |
| CPUボード(EV02G02A) | dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM) | dsPIC33AK128MC106 General Purpose Dual In-Line Module (DIM) | Microchip Technology |
| 統合開発環境 | MPLAB X IDE v6.20 | MPLAB® X IDE | Microchip Technology |
| コンパイラ | MPLAB XC DSC v3.10 | MPLAB® XC DSC Compiler | Microchip Technology |

DMAレジスタ
以下にDMAレジスタとその説明を示します。
| レジスタ名(xは1~6) | 機能 | 説明 |
| DMACON | DMAモジュール制御レジスタ | DMAモジュール全体の設定を行う |
| DMABUF | DMAデータバッファレジスタ | DMA転送時の一時バッファ |
| DMALOW | DMAアドレス低リミットレジスタ | DMA転送のためのアドレスリミットを設定する |
| DMAHIGH | DMAアドレス高リミットレジスタ | DMA転送のためのアドレスリミットを設定する |
| DMAxCH | DMAチャンネルx制御レジスタ | DMAチャンネルxの各種設定を行う |
| DMAxSEL | DMAチャンネルxトリガレジスタ | DMAチャンネルxの転送トリガを設定する |
| DMAxSTAT | DMAチャンネルxステータスレジスタ | DMAチャンネルxの動作ステータスを取得する |
| DMAxSRC | DMAチャンネルx転送元レジスタ | DMAチャンネルxの転送元アドレスを設定する |
| DMAxDST | DMAチャンネルx転送先レジスタ | DMAチャンネルxの転送先アドレスを設定する |
| DMAxCNT | DMAチャンネルxカウントレジスタ | DMAチャンネルxの転送回数を設定する |
| DMAxCLR | DMAチャンネルxクリアレジスタ | DMABUF レジスタの対応ビットをクリアする |
| DMAxSET | DMAチャンネルxセットレジスタ | DMABUF レジスタの対応ビットをセットする |
| DMAxINV | DMAチャンネルx反転レジスタ | DMABUF レジスタの対応ビットを反転する |
| DMAxMSK | DMAチャンネルxマスクレジスタ | パターンマッチ用マスクビットを設定する |
| DMAxPAT | DMAチャンネルxパターンマッチレジスタ | パターンマッチ用データ |
DMA基本動作
転送タイプ
DMAの転送は、Peripheralアドレス(SFR Area)とRAMアドレス(Data Space)間で自由にデータを転送できます。

転送モード
転送モードは以下の4つを備えています。
| モード | 転送バイト | 転送終了後 |
| ワンショット | DMAxCHbits.SIZE | モジュール停止 |
| 繰り返しワンショット | DMAxCHbits.SIZE | リロードとリピート |
| 連続 | DMAxCHbits.SIZE × DMAxCNT | モジュール停止 |
| 繰り返し連続 | DMAxCHbits.SIZE × DMAxCNT | リロードとリピート |
ワンショット転送モード (RAM → RAM)
動作説明
ワンショット転送モードは1回の転送トリガに対し1回の転送を行います。
DMAxCNTで設定した回数の転送トリガを受信するとチャンネルの動作が無効になります。

ソースコード
インクルードファイル
コンフィグレーションファイル、クロック設定ファイルは以下のファイルをインクルードしてください。
■コンフィグレーションファイル (config.h)
■クロック設定ソースファイル(Clock_Driver.c)
■クロックヘッダーファイル(clock_driver.h)
ソースコード全体
下記のコードは1回の転送トリガしか発生させていないため、u4g_SrcData[0]のみがu4g_DstData[0]に転送されます。
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "config.h"
#include "clock_driver.h"
uint32_t u4g_SrcData[8];
uint32_t u4g_DstData[8];
int main()
{
/*-----------------------------------------------------------------------*/
/*初期化*/
/*-----------------------------------------------------------------------*/
vdg_Clock_Set_Register();
for (int i=0 ; i< 8 ;i++)
{
u4g_SrcData[i] =i * 10 + 20;
u4g_DstData[i] = 0x00000000U;
}
/*-----------------------------------------------------------------------*/
/* DMA設定 */
/*-----------------------------------------------------------------------*/
DMACONbits.ON = 1U; //DMA有効
DMACONbits.PRIORITY = 0U; //Fixed
DMACONbits.SIDL = 0UL;
DMABUF = 0x00000000u;
DMALOW = 0x4000U;
DMAHIGH = 0x7FFFU;
DMA0CH = 0x00000000U;
DMA0CHbits.SIZE = 2U; //32Bit
DMA0CHbits.TRMODE = 0U; //One-Shot
DMA0CHbits.DAMODE = 1U; //Increment
DMA0CHbits.SAMODE = 1U; //Increment
DMA0SEL = 0x00000000U;
DMA0STAT = 0x00000000U;
DMA0SRC = (unsigned int)& u4g_SrcData; //転送元
DMA0DST = (unsigned int)& u4g_DstData; //転送先
DMA0CNT = 8u; //転送回数
DMA0CLR = 0x00000000U;
DMA0SET = 0x00000000U;
DMA0INV = 0x00000000U;
DMA0MSK = 0x00000000U;
DMA0PAT = 0x00000000U;
DMA0CHbits.CHEN = 1U; //DMA0チャネル有効化
DMA0CHbits.CHREQ = 1U; //DMA0ソフトウェア転送開始
while(DMA0CHbits.CHREQ){;} //DMA0ソフトウェア転送完了確認
while(1)
{
;
}
}
もし全部の転送を行う場合は、下記のコードを8回繰り返す必要が有ります。
DMA0CHbits.CHREQ = 1U; //DMA0ソフトウェア転送開始
while(DMA0CHbits.CHREQ){;} //DMA0ソフトウェア転送完了確認
連続転送モード (RAM → RAM)
動作説明
連続転送モードは1回の転送トリガに対し複数回の転送を行います。回数はDMA0CNTで設定します。
転送トリガを受信し8回の転送が完了するとチャンネルの動作が無効になります。

ソースコード
ワンショット転送モードとの違い
ワンショット転送モードとの違いは以下の行のみです。
DMA0CHbits.TRMODE = 2U; //連続転送
ソースコード全体
下記のコードを実行すると、u4g_SrcData[0]~[7]の値がu4g_DstData[0]~[7]に転送されます。
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "config.h"
#include "clock_driver.h"
#include <dsp.h>
uint32_t u4g_SrcData[8];
uint32_t u4g_DstData[8];
int main()
{
/*-----------------------------------------------------------------------*/
/*初期化*/
/*-----------------------------------------------------------------------*/
vdg_Clock_Set_Register();
for (int i=0 ; i< 8 ;i++)
{
u4g_SrcData[i] =i * 10 + 20;
u4g_DstData[i] = 0x00000000U;
}
/*-----------------------------------------------------------------------*/
/* DMA設定 */
/*-----------------------------------------------------------------------*/
DMACONbits.ON = 1U; //DMA有効
DMACONbits.PRIORITY = 0U; //Fixed
DMACONbits.SIDL = 0UL;
DMABUF = 0x00000000u;
DMALOW = 0x4000U;
DMAHIGH = 0x7FFFU;
DMA0CH = 0x00000000U;
DMA0CHbits.SIZE = 2U; //32Bit
DMA0CHbits.TRMODE = 2U; //連続転送
DMA0CHbits.DAMODE = 1U; //Increment
DMA0CHbits.SAMODE = 1U; //Increment
DMA0SEL = 0x00000000U;
DMA0STAT = 0x00000000U;
DMA0SRC = (unsigned int)& u4g_SrcData; //転送元
DMA0DST = (unsigned int)& u4g_DstData; //転送先
DMA0CNT = 8u; //転送回数
DMA0CLR = 0x00000000U;
DMA0SET = 0x00000000U;
DMA0INV = 0x00000000U;
DMA0MSK = 0x00000000U;
DMA0PAT = 0x00000000U;
DMA0CHbits.CHEN = 1U; //DMA0チャネル有効化
DMA0CHbits.CHREQ = 1U; //DMA0ソフトウェア転送開始
while(DMA0CHbits.CHREQ){;} //DMA0ソフトウェア転送完了確認
while(1)
{
;
}
}
ワンショットリピートモード(RAM → RAM)
動作説明
ワンショットリピートモードは1回の転送トリガに対し1回の転送を行います。
DMAxCNTで設定した回数の転送トリガを受信してもチャンネルの動作が無効になりません。
ここで重要なのが、以下のリロード設定を有効にすることです。これを転送元、転送先の両方に設定しておくことで、アドレスがリロードされます。
DMA0CHbits.DAMODE = 1U; //リロード
DMA0CHbits.SAMODE = 1U; //リロード

ソースコード
ソースコード全体
以下を実行するとwhileループでトリガを発生させていますので、データ転送が永遠と実行されます。
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "config.h"
#include "clcok_driver.h"
#include <dsp.h>
uint32_t u4g_SrcData[8];
uint32_t u4g_DstData[8];
int main()
{
/*-----------------------------------------------------------------------*/
/*初期化*/
/*-----------------------------------------------------------------------*/
vdg_Clock_Set_Register();
for (int i=0 ; i< 8 ;i++)
{
u4g_SrcData[i] =i * 10 + 20;
u4g_DstData[i] = 0x00000000U;
}
/*-----------------------------------------------------------------------*/
/* DMA設定 */
/*-----------------------------------------------------------------------*/
DMACONbits.ON = 1U; //DMA有効
DMACONbits.PRIORITY = 0U; //Fixed
DMACONbits.SIDL = 0UL;
DMABUF = 0x00000000u;
DMALOW = 0x4000U;
DMAHIGH = 0x7FFFU;
DMA0CH = 0x00000000U;
DMA0CHbits.SIZE = 2U; //32Bit
DMA0CHbits.TRMODE = 1U; //ワンショットリピート
DMA0CHbits.DAMODE = 1U; //Increment
DMA0CHbits.SAMODE = 1U; //Increment
DMA0CHbits.DAMODE = 1U; //リロード
DMA0CHbits.SAMODE = 1U; //リロード
DMA0SEL = 0x00000000U;
DMA0STAT = 0x00000000U;
DMA0SRC = (unsigned int)& u4g_SrcData; //転送元
DMA0DST = (unsigned int)& u4g_DstData; //転送先
DMA0CNT = 8u; //転送回数
DMA0CLR = 0x00000000U;
DMA0SET = 0x00000000U;
DMA0INV = 0x00000000U;
DMA0MSK = 0x00000000U;
DMA0PAT = 0x00000000U;
DMA0CHbits.CHEN = 1U; //DMA0チャネル有効化
while(1)
{
DMA0CHbits.CHREQ = 1U;
while(DMA0CHbits.CHREQ){;}
}
}
ワンショット転送モード(Peripheral → RAM)
動作説明
dsPIC33AKになって、大きく進化した点にADCの変換速度が最大40Mspsと非常に高速になった点が挙げられます。ただこの速度でADC変換したデータを取得することは困難です。
そこで今回は例として50kHzの信号を5MHzでサンプリングするという仕様を検討します。
下記のブロック図のようにSCCP0のトリガ(5MHz)によってサンプリングを行い、そのAD変換完了によってDMA転送トリガを発動し、DMAによりで256回データを転送したあとに、チャネルを無効化するものとします。

ソースコード
ソースコード全体
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "config.h"
#include "clock_driver.h"
#include <dsp.h>
uint32_t u4g_AdcData[256];
int main()
{
/*-----------------------------------------------------------------------*/
/*初期化*/
/*-----------------------------------------------------------------------*/
vdg_Clock_Set_Register();
/*-----------------------------------------------------------------------*/
/*ADC設定*/
/*-----------------------------------------------------------------------*/
ANSELAbits.ANSELA11 = 1u; //PortA11をアナログ入力に設定
AD1CH0CONbits.TRG1SRC = 0x0Cu; //SCCP1 Trig
AD1CH0CONbits.PINSEL = 10u; //AD1CH0+入力はAD1AN10
AD1CH0CONbits.MODE = 0u; //シングル変換モード
AD1CON = 0x00000000U;
AD1CONbits.ON = 1U;
while(AD1CONbits.ADRDY == 0U)
{
;
}
/*-----------------------------------------------------------------------*/
/* DMAレジスタ */
/*-----------------------------------------------------------------------*/
DMACONbits.ON = 1u;
DMACONbits.PRIORITY = 0U; //Fixed
DMACONbits.SIDL = 0UL;
DMABUF = 0x00000000u;
DMALOW = 0x4000U;
DMAHIGH = 0x7FFFU;
DMA0CH = 0x00000000U;
DMA0CHbits.CHEN = 0U;
DMA0CHbits.HALFEN = 0U;
DMA0CHbits.MATEN = 0U;
DMA0CHbits.INTOEN = 0U;
DMA0CHbits.CHREQ = 0U;
DMA0CHbits.SIZE = 2U; //32Bit
DMA0CHbits.FLWCON = 0U;
DMA0CHbits.TRMODE = 0U; //One-Shot
DMA0CHbits.DAMODE = 1U; //インクリメント
DMA0CHbits.SAMODE = 0U; //変更無
DMA0CHbits.RETEN = 0U;
DMA0CHbits.RELOADS = 0U;
DMA0CHbits.RELOADD = 0U;
DMA0CHbits.RELOADC = 0U;
DMA0CHbits.PCHAEN = 0U;
DMA0CHbits.PPEN = 0U;
DMA0SEL = 0x2Bu;
DMA0STAT = 0x00000000U;
DMA0SRC = (unsigned int)& AD1CH0DATA;
DMA0DST = (unsigned int)& u4g_AdcData;
DMA0CNT = 256u;
DMA0CLR = 0x00000000U;
DMA0SET = 0x00000000U;
DMA0INV = 0x00000000U;
DMA0MSK = 0x00000000U;
DMA0PAT = 0x00000000U;
DMA0CHbits.CHEN = 1U;
/*-----------------------------------------------------------------------*/
/* CCP1レジスタ*/
/*-----------------------------------------------------------------------*/
CCP1CON1 = 0x00000000u;
CCP1CON2 = 0x00000000u;
CCP1CON3 = 0x00000000u;
CCP1PR = 19U; //100MHz / 5MHz -1 = 19
CCP1RA = 0x00000000u;
CCP1RB = 0x00000000u;
CCP1CON1bits.ON = 1u;
while(1)
{
}
}
結果
以下に測定結果を示します。50kHzの信号を5MHzでサンプリングした結果、計算通りに2.5周期分のデータがサンプリングされていることが確認できました。
ちなみに入力信号を500kHz、サンプリング周波数を20MHzにした時も、計算通りデータが取得できています。

Ping-Pongモードについて
動作説明
DMAによるPing-Pongモードは、データ転送を途切れなく行うための高度なテクニックです。このモードは、2つのバッファ(通常はバッファAとバッファB)を交互に使用してデータを転送します。これにより、1つのバッファがデータを受け取っている間に、もう1つのバッファが次のデータを処理できる状態になります。
DMAによるPing-Pongモードの動作フロー:
- バッファAへのデータ転送: DMAがまずバッファAにデータを転送します。
- バッファBの準備: バッファAへの転送が行われている間、バッファBが次のデータを受け取る準備をします。
- バッファBへのデータ転送: バッファAが満杯になったら、DMAは自動的にバッファBにデータを転送し始めます。
- バッファAの準備: バッファBがデータを受け取っている間、バッファAが次の転送に備えてクリアされます。
このプロセスは連続的に行われるため、データの転送と処理がスムーズに進行し、遅延を最小限に抑えることができます。Ping-Pongモードは、リアルタイム処理や高頻度でデータが転送されるシステムで特に有効です。たとえば、音声データやセンサーデータの処理でよく使われます。

DMAに関するシリコンエラッタが何点か報告されています。
dsPIC33AK128MC106 Family Silicon Errata and Data Sheet Clarification (microchip.com)
A2リビジョンではPing-Pongモードが完全に動作せず、1回のペア転送が完了した時に動作が停止してしまう事が報告されています。
なお2nd Generation であるdsPIC33AK512MPS512系ではこの問題は解消されている模様です
今回は、AD変換データをBufferA(DMACH0)からBufferB(DMACH1)へ連続して保存するプロセスを確認します。
ソースコード
ソースコード全体
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "peripheral_init.h"
#include "BoardSupportPackage.h"
#include <dsp.h>
uint32_t u4g_AdcDataA[256];
uint32_t u4g_AdcDataB[256];
int main()
{
/*-----------------------------------------------------------------------*/
/*初期化*/
/*-----------------------------------------------------------------------*/
vdg_Clock_Set_Register();
/*-----------------------------------------------------------------------*/
/*ADC設定*/
/*-----------------------------------------------------------------------*/
ANSELAbits.ANSELA11 = 1u; //PortA11をアナログ入力に設定
AD1CH0CONbits.TRG1SRC = 0x0Cu; //SCCP1 Trig
AD1CH0CONbits.PINSEL = 10u; //AD1CH0+入力はAD1AN10
AD1CH0CONbits.MODE = 0u; //シングル変換モード
AD1CON = 0x00000000U;
AD1CONbits.ON = 1U;
while(AD1CONbits.ADRDY == 0U)
{
;
}
/*-----------------------------------------------------------------------*/
/* DMAレジスタ */
/*-----------------------------------------------------------------------*/
DMACONbits.ON = 1u;
DMACONbits.PRIORITY = 0U; //Fixed
DMACONbits.SIDL = 0UL;
DMABUF = 0x00000000u;
DMALOW = 0x4000U;
DMAHIGH = 0x7FFFU;
DMA0CH = 0x00000000U;
DMA0CHbits.CHEN = 0U;
DMA0CHbits.HALFEN = 0U;
DMA0CHbits.MATEN = 0U;
DMA0CHbits.INTOEN = 1U; //
DMA0CHbits.CHREQ = 0U;
DMA0CHbits.SIZE = 2U; //32Bit
DMA0CHbits.FLWCON = 0U;
DMA0CHbits.TRMODE = 1U; //One-Shotリピート
DMA0CHbits.DAMODE = 1U; //インクリメント
DMA0CHbits.SAMODE = 0U; //変更無
DMA0CHbits.RETEN = 0U;
DMA0CHbits.RELOADS = 1U; //リロード有効
DMA0CHbits.RELOADD = 1U; //リロード有効
DMA0CHbits.RELOADC = 0U;
DMA0CHbits.PCHAEN = 1U;
DMA0CHbits.PPEN = 1U; //Ping-Pong 有効化
DMA0SEL = 0x2Bu;
DMA0STAT = 0x00000000U;
DMA0SRC = (unsigned int)& AD1CH0DATA;
DMA0DST = (unsigned int)& u4g_AdcDataA;
DMA0CNT = 256u;
DMA0CHbits.CHEN = 1U;
DMA1CH = 0x00000000U;
DMA1CHbits.CHEN = 0U;
DMA1CHbits.HALFEN = 0U;
DMA1CHbits.MATEN = 0U;
DMA1CHbits.INTOEN = 1U;
DMA1CHbits.CHREQ = 0U;
DMA1CHbits.SIZE = 2U; //32Bit
DMA1CHbits.FLWCON = 0U;
DMA1CHbits.TRMODE = 1U; //One-Shotリピート
DMA1CHbits.DAMODE = 1U; //インクリメント
DMA1CHbits.SAMODE = 0U; //変更無
DMA1CHbits.RETEN = 0U;
DMA1CHbits.RELOADS = 1U; //リロード有効
DMA1CHbits.RELOADD = 1U; //リロード有効
DMA1CHbits.RELOADC = 0U;
DMA1CHbits.PCHAEN = 0U;
DMA1CHbits.PPEN = 1U; //Ping-Pong 有効化
DMA1SEL = 0x2Bu;
DMA1STAT = 0x00000000U;
DMA1SRC = (unsigned int)& AD1CH0DATA;
DMA1DST = (unsigned int)& u4g_AdcDataB;
DMA1CNT = 256u;
DMA1CHbits.CHEN = 1U;
/*-----------------------------------------------------------------------*/
/* CCP1CON1初期化*/
/*-----------------------------------------------------------------------*/
CCP1CON1 = 0x00000000u;
CCP1CON2 = 0x00000000u;
CCP1CON3 = 0x00000000u;
CCP1STAT = 0x00000000u;
CCP1TMR = 0x00000000u;
CCP1PR = 19U; //100MHz / 5MHz -1 = 19
CCP1RA = 0x00000000u;
CCP1RB = 0x00000000u;
CCP1BUF = 0x00000000u;
CCP1CON1bits.ON = 1u;
while(1)
{
}
}
結果
CH0(青)が256回サンプリングを終了した後に連続してCH1(赤)が256回データを取得している事が確認できました。

記事についての注意点
本記事は慎重に内容を検討し正確さに努めておりますが、内容に誤りがあったとしても、この記事を参考にして生じた損害等については一切の責任を負いません。

コメント