dsPIC33AKシリーズ㉒ CBGモジュールの使い方

CBGモジュールの使い方

概要

今回は、dsPIC33AKシリーズのCBGモジュールの動作を確認します。

CBGとは

CBGとは「Current Bias Generator」の頭文字をとった用語で、定電流を出力します。なお従来のdsPIC33Cシリーズに搭載されていた電流シンク機能は削除され電流ソースのみとなりました。ただし従来は10μAか50μAのどちらかの選択でありましたが、10μAか30,50,100,120,150,200μAと選択肢は増えています。

関連記事

記事リンク
第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 (electricpico.com)
第11回WDTモジュールの使い方dsPIC33AKシリーズ⑪WDTモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第12回DMTモジュールの使い方dsPIC33AKシリーズ⑫DMTモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第13回I/Oインテグリティモニタモジュールの使い方dsPIC33AKシリーズ⑬I/Oインテグリティモニターモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第14回QEIモジュールの使い方dsPIC33AKシリーズ⑭QEIモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第15回UARTモジュールの使い方dsPIC33AKシリーズ⑮UARTモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第16回DSPの使い方1 (デジタルフィルタ)dsPIC33AKシリーズ⑯ DSPの使い方1(デジタルフィルタ) – ぴくおの電子工作的な何かWP (electricpico.com)
第17回DSPの使い方2 (FFT)dsPIC33AKシリーズ⑰ DSPの使い方2(FFT) – ぴくおの電子工作的な何かWP (electricpico.com)
第18回DSPの使い方3 (自己相関アルゴリズム)dsPIC33AKシリーズ⑱ DSPの使い方3(自己相関アルゴリズム) – ぴくおの電子工作的な何かWP (electricpico.com)
第19回DSPの使い方4(LMSアルゴリズム)dsPIC33AKシリーズ⑲ DSPの使い方4(LMSアルゴリズム) – ぴくおの電子工作的な何かWP (electricpico.com)
第20回SPIモジュールの使い方dsPIC33AKシリーズ⑳ SPIモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
第21回高速コンパレータモジュールの使い方1dsPIC33AKシリーズ㉑ 高速コンパレータモジュールの使い方1 – ぴくおの電子工作的な何かWP (electricpico.com)
第22回(本記事)CBGモジュールの使い方dsPIC33AKシリーズ㉒ CBGモジュールの使い方 – ぴくおの電子工作的な何かWP (electricpico.com)
(fig.1-1)dsPIC33Aシリーズ各関連記事リンク

開発環境

開発環境を以下に示します。
今回はCPUボード(EV02G02A)で動作確認を行います。

項目リンク
ベースボードdsPIC33A CURIOSITY PLATFORM
DEVELOPMENT BOARD
dsPIC33A Curiosity Platform Development Board User’s Guide (microchip.com)
CPUボード(EV68M17A)EV68M17A – dsPIC33AK128MC106 Motor Control DIMdsPIC33AK128MC106 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.20MPLAB® X IDE | Microchip Technology
コンパイラMPLAB XC DSC v3.10MPLAB® XC DSC Compiler | Microchip Technology
(fig.2-1)本記事の動作確認環境
(fig.2-2)動作環境

CBGモジュールについて

ブロック図

No Image

レジスタ

CBGレジスタとその説明を以下に示します。

レジスタ名機能説明
IBIASCONバイアス電流ジェネレータ設定レジスタ電流ソースの設定を行う
(fig.3-1)CBGレジスタ

定電流ソースの使い道

定電流ソースは以下のような使い道が考えられます。

1.固定電圧の生成、抵抗値の推定

定電流ソースの先が抵抗を介してGNDに接続されている場合、点Vの電圧は電流Iと抵抗値Rの積、つまり I × R となります。これにより、電流または抵抗、もしくはその両方の値を調整することで、Vの値を任意に設定することが可能です。ただし、生成できる電圧は電源電圧までに制限されます。

(fig.3-2)固定電圧の生成、抵抗値の推定

またRTDのような温度によって抵抗値が変わるセンサの場合、R=V/Iで求めることが可能です。

2.定電流充電

定電流ソースの先がコンデンサを介してGNDに接続されている場合、点Vの電圧は電流Iと充電時間tの積をコンデンサの容量で割った時間、つまり I × t / Cとなります。
例えばCの値が未知で、これを検出する場合に充電開始後の電圧V、充電電流I、充電時間よりCの容量を求めることができます。ただし、上限電圧は電源電圧までに制限されます。

(fig.3-3)定電流充電

3.電圧シフト

DC オフセットのある AC 信号をADCなどで検出したい場合、ADCのレンジ内に収める必要があります。抵抗分圧等で電圧シフトを行うと、振幅の変化量も小さくなってしまうためS/N比が悪化します。そのような場合に、オフセット電圧が定電流モジュールによって生成できます。例えば下記の「シミュレーションのように-24±1.5Vの信号(緑)を、ADCのレンジ内に収める場合、定電流値(I_OUT)を50μA、信号と定電流源の間に511kΩを挿入すると、定電流出力側(青)の電圧は1.5V±1.5Vとなります。

この外部抵抗値 RShift = (VinDC – VinAC /2 ) / IOUT となります。

(fig.3-4)電圧シフト

従来のdsPIC33Cシリーズは電流ソースだけでなく電流シンク機能も持っていたため、シフト電圧をマイナスする事も可能でしたが、dsPIC33Aシリーズはその機能が削られてしまったのが残念です。

動作説明

ブロック図

今回のブロック図を以下に示します。
定電流出力ピン(IBAIS3)は基板上のタッチパッドT1と接続されています。基板上で形成される静電容量に加え、指を近づけることで静電容量が変化し、それに伴い充放電の時間も変わります。この変化を明確に捉えるため、ジャンパワイヤを使用してコンパレータ1に接続し、電圧の比較を行います。

ソースコード

コンフィグレーションファイル

コンフィグレーションファイル、クロック設定ファイルは以下のファイルをインクルードしてください。

■コンフィグレーションファイル 

■クロック設定ソースファイル

■クロックヘッダーファイル

ソースコード全体

#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include "config.h"
#include "clock_driver.h"

/*----------------------------------------------------------------------------*/
/* 定数定義*/
/*----------------------------------------------------------------------------*/
#define DACH 0xF00
#define DACL 0x80
/*----------------------------------------------------------------------------*/
/*変数定義*/
/*----------------------------------------------------------------------------*/
volatile uint32_t adVal;


int main() 
{
    /*-----------------------------------------------------------------------*/
    /*初期化*/
    /*-----------------------------------------------------------------------*/
        vdg_Clock_Set_Register();
		
	ANSELAbits.ANSELA4 = 1U;		//PortA4をアナログに設定
	ANSELAbits.ANSELA8 = 1U;		//PortA8をアナログに設定

	RPOR9bits.RP40R = 32;	//CMP1
	TRISCbits.TRISC3 = 0u;
		
    /*-----------------------------------------------------------------------*/
    /* DACCTRL1レジスタ */
    /*-----------------------------------------------------------------------*/
	DACCTRL1 = 0x00000000u;
	DACCTRL1bits.ON = 0u;
	DACCTRL1bits.FCLKDIV = 0u;
	DACCTRL1bits.DNLADJ = 0u;
	DACCTRL1bits.SIDL = 0u;
	DACCTRL1bits.NEGINLADJ = 0x7Fu;
	DACCTRL1bits.POSINLADJ = 0x3Fu;
	ACCTRL1bits.RREN = 0u;
    /*-----------------------------------------------------------------------*/
    /* DACCTRL2レジスタ */
    /*-----------------------------------------------------------------------*/
	DACCTRL2 = 0x00000000u;
	DACCTRL2bits.TMODTIME = 0x01u;
	DACCTRL2bits.SSTIME = 0x8Au;

    /*-----------------------------------------------------------------------*/
    /* DAC1CONレジスタ */
    /*-----------------------------------------------------------------------*/
	DAC1CON = 0x00000000u;

	DAC1CONbits.HYSSEL = 0u;
	DAC1CONbits.HYSPOL = 0u;
	DAC1CONbits.INSEL = 1u;  //CMP1B
	DAC1CONbits.CMPPOL = 0u;
	DAC1CONbits.CMPSTAT = 0u;
	DAC1CONbits.FLTREN = 1u;  //デジタルフィルタの有効か
	DAC1CONbits.DACOEN = 0u;
	DAC1CONbits.CBE = 0u;
	DAC1CONbits.UPDTMDIS = 0u;
	DAC1CONbits.EXTUPD = 0u;
	DAC1CONbits.IRQM = 0u;
	DAC1CONbits.DACEN = 0u;
	DAC1CONbits.TMCB = 0u;

    /*-----------------------------------------------------------------------*/
    /* DAC1DATレジスタ */
    /*-----------------------------------------------------------------------*/
	DAC1DAT = 0x00000000u;
	DAC1DATbits.DACLOW = 0x100u;
	DAC1DATbits.DACDAT = DACH;

    /*-----------------------------------------------------------------------*/
    /* DAC1SLPCONレジスタ */
    /*-----------------------------------------------------------------------*/
	DAC1SLPCON = 0x00000000u;
    /*-----------------------------------------------------------------------*/
    /* SLP1CONレジスタ */
    /*-----------------------------------------------------------------------*/
	SLP1CON = 0x00000000u;
    /*-----------------------------------------------------------------------*/
    /* SLP1DATレジスタ */
    /*-----------------------------------------------------------------------*/
	SLP1DAT = 0x00000000u;

	DAC1CONbits.DACEN = 1u;
	DACCTRL1bits.ON = 1u;
		
	IBIASCONbits.I10EN3 = 1u;
    /*-----------------------------------------------------------------------*/
    /*メインルーチン*/
    /*-----------------------------------------------------------------------*/
        while(1)
        {
		if ((DAC1DATbits.DACDAT == DACH) && (DAC1CONbits.CMPSTAT == 1))
		{
			DAC1DATbits.DACDAT = DACL;
			IBIASCONbits.I10EN3 = 0u;
			LATCbits.LATC3 = 0;
		}
		else if  ((DAC1DATbits.DACDAT == DACL) && (DAC1CONbits.CMPSTAT == 0))
		{
			DAC1DATbits.DACDAT = DACH;
			IBIASCONbits.I10EN3 = 1u;
			LATCbits.LATC3 = 1;
		}
	}
}

結果

指のタッチが無い時は約40usecで充電しているのに対し、指をタッチすると約58μsecで充電している事が確認できました。ただし、タッチ無の場合は安定的な発振になるのに対し、タッチありの場合は充放電の時間が安定しない事も確認できました。

タッチ無し

タッチあり

記事についての注意点

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

コメント

タイトルとURLをコピーしました