概要
今回は、dsPIC33AKシリーズのCBGモジュールの動作を確認します。
CBGとは「Current Bias Generator」の頭文字をとった用語で、定電流を出力します。なお従来のdsPIC33Cシリーズに搭載されていた電流シンク機能は削除され電流ソースのみとなりました。ただし従来は10μAか50μAのどちらかの選択でありましたが、10μAか30,50,100,120,150,200μAと選択肢は増えています。
関連記事
開発環境
開発環境を以下に示します。
今回はCPUボード(EV02G02A)で動作確認を行います。
| 項目 | 値 | リンク |
| ベースボード | 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 |

CBGモジュールについて
ブロック図
No Image
レジスタ
CBGレジスタとその説明を以下に示します。
| レジスタ名 | 機能 | 説明 |
| IBIASCON | バイアス電流ジェネレータ設定レジスタ | 電流ソースの設定を行う |
定電流ソースの使い道
定電流ソースは以下のような使い道が考えられます。
1.固定電圧の生成、抵抗値の推定
定電流ソースの先が抵抗を介してGNDに接続されている場合、点Vの電圧は電流Iと抵抗値Rの積、つまり I × R となります。これにより、電流または抵抗、もしくはその両方の値を調整することで、Vの値を任意に設定することが可能です。ただし、生成できる電圧は電源電圧までに制限されます。

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

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 となります。

従来の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で充電している事が確認できました。ただし、タッチ無の場合は安定的な発振になるのに対し、タッチありの場合は充放電の時間が安定しない事も確認できました。
タッチ無し


タッチあり


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

コメント