
写真1 AD9833 DDS MSOP 0.5ピッチ 変換基板に乗せる
それはさておき、
このチップは10ピンのMSOPで、写真にようにピンセットの先ほどの大きさです。
変換基板に取り付けましたが、ピンのピッチは0.5なので、半田付けにはちょっと技術が必要です。
まずチップをゲルタイプの瞬間接着剤で正確な位置に仮止めしておきます。
フラックスをほんのわずか塗って、すべてのピンにわざとまたがるくらい半田を盛ります。
半田吸い取り線で、余分な半田を吸い取って、出来上がり。
慣れれば簡単ですが、最初は数個パーにする覚悟がいります(笑)。
このDDSは、マスタクロック(MCLK)周波数は最高25MHzで、その場合最高発振周波数(ナイキスト周波数)は12.5MHzとなり、分解能は0.1Hzです。
今回は手持ち部品の関係で、20MHzのクリスタルを使用したので、10MHzまでのプログラマブルオシレータとして、実験してみました。この場合の分解能は約0.075Hzです。
STM32 Nucleoで制御するTPSA4700プログラマブル電源
投稿日 2014/09/25
TIのTPS7A4700を使用した超ローノイズ・プログラマブル電源モジュールが秋月電子から出ています。
出力電圧 1.4Vから20.5V可変で、DIPスイッチによって100mV単位で設定できるようになっています。最大出力電流は1Aです。超ローノイズ、高精度がうたい文句です。
このモジュールは、小さなDIPスイッチで電圧を切り替えるようになっていますが、これをロータリーエンコーダを使用したツマミの回転で切り替えられるようにしてみました。マイコン制御にするので、ついでにキャラクタLCDに設定電圧値も表示してみました。使用目的は特にありませんが、ちょっと便利に使える高精度電圧源にしておこうという動機です。

STM32 Nucleo + TPS7A4700 プログラマブル電源
ロータリエンコーダで1.40から20.5Vまで0.1Vステップで選べる
マイコン制御の場合、制御信号線を引き出す必要がありますが、秋月電子のこのボードの場合、引き出せるようにはなっていません。(他のお店から販売されているものは引出しが考慮されています) 仕方がないのでDIPスイッチの端子に直接リードをはんだ付けして引き出すことにしました。
マイコンにはSTM32 Nucleoを使用し、mbedでプログラムを作ってみました。
Nucleoには数種類ありますが、今回はSTM32L152 Nucleoを使用しました。
32bit MCU搭載のNucleoを使う理由は何もありませんが、mbedの開発環境を確認しておくのによい機会となりました。
計算で求めた設定電圧値をキャラクタLCDに表示するようにしました。
(ADコンバータで読み込んだ実際の出力電圧ではありません)
表示用のキャラクタLCDはI2C制御のAQM0802Aを使用しました。
I2Cの制御信号は、D14(SDA), D15(SCL)につなぎ、
4.7KΩでプルアップしておきます。
出力電圧の設定は、ロータリエンコーダで行うようにしました。
ロータリエンコーダを回すと1ステップで100mV増減します。
ロータリエンコーダのA端子はPC_0、B端子はPC_1につなぎました。
これらは10KΩでプルアップしておき、C端子はGNDに落とします。
電源のオン/オフができるようにスライドスイッチを設けました。
基板はArduino互換の汎用基板を使用し、電源モジュールやロータリエンコーダを接着剤で固定しました。放熱の考慮はしていないので、あまり電流は流せません。
入力側の電源は外付けを別途用意しました。出力電圧より1V高い電源を用意する必要があります。今回は15Vまでの電源で動作確認しましたので、14V程度までしか出力を確認していません。(最大は20.5V出るはず)

CMOSアナログスイッチ 4066を2個使用して
NucleoのGPIO D0-D7でスイッチをON/OFFする
EN端子にはスライドスイッチ(SW)を取り付けた
(秋月電子の資料より抜粋)
TPS7A4700の制御
TPS7A4700の出力電圧は8本のGPIOで制御します。
0 100mV
1 200mV
2 400mV
3 800mV
4 1.6V
5 3.2V
6 6.4V
7 6.4V
の各電圧を受け持つピン計8本です。
電圧はこれらの組み合わせで決まります。
ALL 0で1.4Vが出ます。
ALL 1では、1.4 + 6.4 + 6.4 + 3.2 + 1.6 + 0.8 + 0.4 + 0.2 + 0.1 = 20.5Vとなります。
0番から6番までの7本のピンはその数値のビットパターンがそのまま電圧に対応しますが、7番が12.8Vではなく6番と同じ6.4Vなので、少し工夫が必要です。
7 6 5 4 3 2 1 0
0 0 0 0 0 0 0 0 0 1.4V
...
0 1 1 1 1 1 1 1 127 14.1V
1 1 0 0 0 0 0 0 192(128 + 64) 14.2V
...
1 1 1 1 1 1 1 1 255(128 + 127) 20.5V
14.1Vと14.2Vの境目で7番を1にして0から6番は64で始めなければなりません。
このため14.1Vまでは0から127まで順にインクリメントすればよいのですが、
14.2Vからは192から始めることになります。
制御用の数値が用意できたら、あとはこの値をGPIOのビットに対応させ出力します。
0から7番のGPIOピンはCN9 Arduinoソケットに出ているD0からD7を使いました。
注意点としては、D0, D1の出ているピンはUARTと共有しており、デフォルトではUARTにつながっている点です。D0, D1として使う場合は、基板裏面のSB62とSB63をショートし、SB13とSB14の0Ωショートバーを取り除いてオープンにしておく必要があります。
TPS7A4700の電圧制御ピンは、GNDに落とすと有効となり、そのピンの担当する電圧が加わります。一方でOPENにすると無効となります。注意する点は無効にするときはOPENであって、電圧を印加してはいけない点で,この仕様がやっかいです。
つまり普通のGPIOのHIGHレベルにはできません。(HIGHで3.3Vが加わってしまう)このため今回は手持ちの4066 4bitのCMOSアナログスイッチを2個使用して制御することにしました。回路が複雑になりますが、仕方ありません。D0からD7を4066のゲートにつなぎON/OFFを制御します。
EN端子は、ディセーブル(電圧出力OFF)にする場合GNDレベルに落としますが、イネーブルにする場合はOPENにして回路にあるR1でハイサイドに引き上げます。このため、スライドスイッチを外付けして出力電圧をON/OFFできるようにしました。
今回はArduinoのシールド用基板に組んでNucleoの上に載せました。せっかくの超ローノイズLDOですのであまり好ましいことではありません。今回はGNDラインにフェライトビーズを入れて妥協しています。
これで、実験等でちょっと精度のよい電圧がほしい場合に便利な電源ができました。マイコン制御にしたメリットはロータリエンコーダで切り替えられる程度の割には回路が複雑になってしまいましたし、この程度の制御にNucleoを使うべきではありません。^-^;
ソースコード
#include <mbed.h>
#include <AQM0802A.h>
AQM0802A lcd(D14, D15); // D14(SDA), D15(SCL)
Ticker ticker;
BusInOut cont_val(D0, D1, D2, D3, D4, D5, D6, D7);
DigitalIn CH_A(PC_1);
DigitalIn CH_B(PC_0);
int counter = -1;
int int_cnt = 0;
int now = 0;
int prev = 0;
int change = 0;
char string[10];
float vol;
void tick()
{
if(int_cnt == 3) { //make 3ms
int_cnt = 0;
now = (CH_A << 1) + CH_B;
if(prev != now) {
if (((prev << 1) + now) & 0x02) {
if(now == 0x03) { //right, lock position
counter++;
if(counter == 128){
counter = 192; //128 + 64
}
if(counter > 255) counter = 255; //128 + 127
change = 1;
}
} else {
if(now == 0x03) { //left, lock position
counter--;
if(counter < 0) counter = 0;
if(counter == 191) {
counter = 127;
}
change = -1;
}
}
prev = now;
}
} else
int_cnt++;
}
int main()
{
ticker.attach(&tick, 0.001);
lcd.cls();
lcd.printf("%s", "TPS7A47");
cont_val.output();
while(1) {
vol = 1.4;
if(counter & 0x0001) vol += 0.1;
if(counter & 0x0002) vol += 0.2;
if(counter & 0x0004) vol += 0.4;
if(counter & 0x0008) vol += 0.8;
if(counter & 0x0010) vol += 1.6;
if(counter & 0x0020) vol += 3.2;
if(counter & 0x0040) vol += 6.4;
if(counter & 0x0080) vol += 6.4;
lcd.setCursor(0, 1);
lcd.printf("Set:%2.4f", vol);
cont_val.write(counter);
wait_ms(100);
}
}
謝辞: I2C LCD AQM0802Aの制御は、Tetsuya Hoshino氏のAkizuki I2C 8x2 Character LCD AQM0802A driver class Libraryを使用させていただきました。
(JF1VRR)