
写真1 AD9833 DDS MSOP 0.5ピッチ 変換基板に乗せる
それはさておき、
このチップは10ピンのMSOPで、写真にようにピンセットの先ほどの大きさです。
変換基板に取り付けましたが、ピンのピッチは0.5なので、半田付けにはちょっと技術が必要です。
まずチップをゲルタイプの瞬間接着剤で正確な位置に仮止めしておきます。
フラックスをほんのわずか塗って、すべてのピンにわざとまたがるくらい半田を盛ります。
半田吸い取り線で、余分な半田を吸い取って、出来上がり。
慣れれば簡単ですが、最初は数個パーにする覚悟がいります(笑)。
このDDSは、マスタクロック(MCLK)周波数は最高25MHzで、その場合最高発振周波数(ナイキスト周波数)は12.5MHzとなり、分解能は0.1Hzです。
今回は手持ち部品の関係で、20MHzのクリスタルを使用したので、10MHzまでのプログラマブルオシレータとして、実験してみました。この場合の分解能は約0.075Hzです。
FM3 PWMを試す
投稿日 2012/05/10
インターフェース6月号に付属のFM3評価ボードで遊んでいます。
今後いろいろな応用で役立つように、基本機能を試しています。
今回はPWMです。LEDの明るさをPWMで変えてホタル点灯してみます。
同じようなことはインターフェース誌6月号でも紹介されています。

写真1 PWMでLEDの明るさをダイナミックに変える
PWMはPulse Width Modulationの略で、その名の通り、パルス幅変調です。
パルスのデューティー比(オンとオフの割合)を可変することができます。
例えば、デューティー100%のフル点灯から0%の消灯まで、ダイナミックに明るさを変えることができます。
FM3にはいくつかのPWMが利用可能です。
GPIOを使うだけなら気にしなくてよいのですが、PWMを使う場合はリロケートを行わなければなりません。
FM3のほとんどのピンにはGPIO(汎用入出力)が割り当てられていますが、同じピンに他のペリフェラルも割り当てられています。そのペリフェラル(今回はPWM)を使用する場合は、GPIOのピンをPWMで使う旨設定しなければなりません。この標準で当てられている機能を別の機能に切り替えることをリロケートと言います。
リロケートはEPFRレジスタで行いますが、EPFRレジスタは16個もあるので、そのうちのどこをどう設定する必要があるかを知る必要があります。
まず、使用するピンに割り当てられてるGPIOのポート名と、そのピンに割り当てられている外部出力信号名(TIOAxx_n)をデータシートで調べておきます。
たとえば、CPUピン43のGPIO P3F(GPIO ポート3のF番)には、外部出力TIOA05_1が割り当てられています。(他のピンにTIOA05_0というのもありますが、_nは同じ出力をそのピンにもリロケートできるということです)
つぎにTIOA05_1が、どのEPFRレジスタにあるかをペリフェラルマニュアルで調べておきます。ペリフェラルマニュアルによると5番目のEPFRレジスタEPFR05であることがわかり、TIOA5Eを10にすればTIOA05_1が外部出力信号に選ばれることが分かります。
ここで、外部出力信号とはベースタイマーの出力信号です。TIOA5_1の5はベースタイマーch.5の出力であることを示しています。
設定手順は以下のようになります。
①P3FをGPIOからペリフェラルに切り替える。
FM3_GPIO->PFR3_f.PF = 1 (0=GPIO 1=ペリフェラル)
②TIOA05_1をベースタイマ(ch.5)の出力としてリロケートする
FM3_GPIO->EPFR05_f.TIOA5E1 = 1
FM3_GPIO->EPFR05_f.TIOA5E0 = 0
以上の設定(リロケート)を行ったら、次にベースタイマ(BT)を16ビットPWMタイマに変身させます。
ベースタイマーはch.5ですから、BT5のPWMの構造体の各パラメータを設定します。そのうちFMDがPWMタイマにする設定です。
FM3_BT5_PWM->TMCR_f.FMD = 1 これでPWMタイマになります。
PWMタイマの場合は、このほかにデューティーやワンショット、アンダーフロー割り込みなど、他にいろいろ設定しておく必要があります。
それらを設定した後、カウント動作を開始させ、トリガをかければ動き出します。
データシートを調べてみると、P3Fのほかに、タイマー出力が割り当てられているピンがたくさんあります。そのすべてがFM3評価ボードでも使えるわけではありませんが、いくつか使用できます。
たとえば、FM3評価ボードでは、今回のP3Fの他に、
P3C ベースタイマー2 TIOA02_1
P3E ベースタイマー4 TIOA04_1
などがあります。
ソースコード(LED表示関連は省略)
#include "mcu.h"
#define PWM_CYCLE_CNT (6000) // PWM 周期16bit
void Init_Port(void);
void delay_ms(__IO uint32_t nTime);
void Init_LCD(void);
void Init_PWM(void);
void lcd_write(uint8_t x, uint8_t y, uint8_t *str);
uint16_t read_val;
int32_t main(void)
{
SysTick_Config(SystemCoreClock / 1000);
Init_Port();
Init_PWM();
Init_LCD();
lcd_write(1, 1, "FM3 PWM Test ^o^" );
while(1);
}
static void Init_Port(void)
{
//P3F TIOA05_1
FM3_GPIO->PFR3_f.PF = 1; //GPIO P3Fをペリフェラルに設定する
FM3_GPIO->PZR3_f.PF = 1; //set to open drain mode
FM3_GPIO->EPFR05_f.TIOA5E1 = 1; //0b10:TIOA5 is TIOA05_1
FM3_GPIO->EPFR05_f.TIOA5E0 = 0;
}
void Init_PWM(void){
/* BT5 PWMinit */
FM3_BT5_PWM->TMCR2_f.CKS3 = 0; // 0b0000: Φ/1
FM3_BT5_PWM->TMCR_f.CKS2 = 0;
FM3_BT5_PWM->TMCR_f.CKS1 = 0;
FM3_BT5_PWM->TMCR_f.CKS0 = 0;
FM3_BT5_PWM->TMCR_f.RTGEN = 0; // 再起動禁止
FM3_BT5_PWM->TMCR_f.PMSK = 0; // 通常出力(maskしない)
FM3_BT5_PWM->TMCR_f.EGS1 = 0; // 0b00:トリガ入力無効
FM3_BT5_PWM->TMCR_f.EGS0 = 0;
FM3_BT5_PWM->TMCR_f.FMD = 1; //0b001:PWM 機能選択
FM3_BT5_PWM->TMCR_f.OSEL = 1; //リセット後 "H"出力
FM3_BT5_PWM->TMCR_f.MDSE = 1; //ワンショット動作
FM3_BT5_PWM->TMCR_f.CTEN = 0; //カウント動作停止
FM3_BT5_PWM->TMCR_f.STRG = 0; //ソフトウェアトリガ無効
FM3_BT5_PWM->STC_f.TGIE = 0; //トリガ割込み禁止
FM3_BT5_PWM->STC_f.DTIE = 0; //デューティ一致割込み禁止
FM3_BT5_PWM->STC_f.UDIE = 0; //アンダフロー割込み禁止
FM3_BT5_PWM->STC_f.TGIR = 0; //トリガ割込みクリア
FM3_BT5_PWM->STC_f.DTIR = 0; //デューティ一致割込みクリア
FM3_BT5_PWM->STC_f.UDIR = 0; //アンダフロー割込みクリア
FM3_BT5_PWM->PCSR = PWM_CYCLE_CNT; // PWM 周期
FM3_BT5_PWM->PDUT = 0; // PWM デューティ
/* 動作開始 */
FM3_BT5_PWM->STC_f.UDIR = 0; //アンダフロー割込みクリア
FM3_BT5_PWM->STC_f.UDIE = 1; //アンダフロー割込み許可
NVIC_EnableIRQ(BTIM0_7_IRQn);
FM3_BT5_PWM->TMCR_f.CTEN = 1; //カウント動作許可
FM3_BT5_PWM->TMCR_f.STRG = 1; //ソフトウェアによる起動開始
}
void BT0_7_IRQHandler(void)
{
static uint8_t dec_fg = 0;
static uint16_t cnt = 0;
//BT5 PWM
FM3_BT5_PWM->STC_f.UDIR = 0; //アンダフロー割込みクリア
read_val = FM3_BT5_PWM->PDUT; //PWM デューティ
if (dec_fg == 0) {
read_val++;
if (read_val >= PWM_CYCLE_CNT) {
dec_fg = 1;
}
} else if (dec_fg == 1) {
read_val--;
if (read_val == 0) {
FM3_BT5_PWM->TMCR_f.PMSK = 1; // maskする
dec_fg = 2;
cnt = 0;
}
} else {
cnt++;
if (cnt >= PWM_CYCLE_CNT) {
FM3_BT5_PWM->TMCR_f.PMSK = 0; // 通常出力(maskしない)
dec_fg = 0;
}
}
FM3_BT5_PWM->PDUT = read_val; //PWM デューティ
FM3_BT5_PWM->TMCR_f.STRG = 1; //ソフトウェアによる起動開始
}
関連記事:
インターフェース6月号 p95 CQ出版社
FM3 LCDをつなぐ->LCDに文字列を表示する
(JF1VRR)