メディア
ハウツー
» 2018年07月30日 11時00分 公開

Design Ideas 信号源とパルス処理:PLDを使ったPWM信号発生器

任意の分解能のPWM(Pulse Width Modulation)信号を発生させるPLD(Programmable Logic Device)コードを紹介する。

[Clive Bolton(Bolton Engineering),EDN Japan]

任意の分解能のPWM信号を発生させるPLDコード

 リスト1に示したPLD(Programmable Logic Device)コードは、任意の分解能のPWM(Pulse Width Modulation)信号を発生させるものだ。PWM信号発生器は、マイクロプロセッサを使ったシステムにおいて、帯域幅が狭いD-A変換器として利用できる。

 PWM信号は、簡単なRC低域通過フィルターを通すと、PWM信号のデューティー比と電源電圧との積にほぼ等しい電圧値に変換できるからだ。ただし実際のシステムでは、駆動用のハードウェアが不完全であるため、最小値はゼロにならず、最大値も電源電圧に等しくならない。

INCLUDE "LPM_COUNTER.INC";
INCLUDE "LPM_COMPARE.INC";
INCLUDE "LPM_FF.INC";
PARAMETERS
(
	PWM_WIDTH = 6, -- Bits (set to 6 for testing)
	AVALUE = B"100000" -- Async reset value
);
SUBDESIGN pwm
(
	clock : INPUT;
	aclr : INPUT;
	enable : INPUT = VCC; -- zeros PWM output
	write : INPUT; -- writes into holding register
	data[PWM_WIDTH-1..0] : INPUT;
	q : OUTPUT;
--	period_pulse : OUTPUT; -- for debug and ext sync
--	cout : OUTPUT;
)
VARIABLE
	pwm : LPM_COUNTER WITH (LPM_WIDTH = PWM_WIDTH, LPM_DIRECTION = "DOWN");
	cntr LPM_COUNTER WITH (LPM_WIDTH = PWM_WIDTH, LPM_DIRECTION = "DOWN");
	pwm_ff SRFF;
	pwm_reg LPM_FF WITH (LPM_WIDTH = PWM_WIDTH, LPM_AVALUE = AVALUE);
	pwm_preout : NODE;
	period_pulse : NODE; -- for debug and ext sync
	cout : NODE;
BEGIN
	ASSERT
		REPORT "PWM_WIDTH: %" PWM_WIDTH
		SEVERITY INFO;
	% PWM Holding Register %
	pwm_reg.clock = clock;
	pwm_reg.aset = aclr;
	pwm_reg.enable = write;
	pwm_reg.data[] = data[];
	% PWM Counter %
	cntr.clock = clock;
	cntr.aclr = aclr;
	cntr.cnt_en = enable;
	period_pulse = DFF(cntr.cout, clock, !aclr, VCC);
	% PWM Counter %
	pwm.clock = clock;
	pwm.aclr = aclr;
	pwm.sload = cntr.cout;
	pwm.data[] = pwm_reg.q[];
	pwm.cnt_en = enable;
	cout = pwm.cout;
	% PWM Output F/F %
	pwm_ff.clk = clock;
	pwm_ff.clrn = !aclr;
	pwm_ff.s = !cout AND period_pulse; -- turn FF on at beginning of interval
	pwm_ff.r = cout OR !enable; -- turn off at carry overflow.
	pwm_preout = pwm_ff.q;
	q = DFF(enable AND pwm_preout, clock, !aclr, VCC);
END;
リスト1:PWM信号発生器のPLDコード

 リスト1のプログラムは、PWM_WIDTHとAVALUEという2つのコンパイルタイムパラメーターを使って、所望のハードウェアを自動的に生成するものだ。PWM_WIDTHは、PWM信号のデューティー比のステップ数を設定する。例えば6ビットと設定するとステップ数は26、すなわち64になる。AVALUEは電源投入時、もしくはリセット時のPWMの初期値を設定する。リスト1では、半分のスケールに設定している。

 このプログラムは、2つの主要なセクションから構成されている。1つは、PWM値を格納するホールディングレジスター、もう1つはPWM波形を生成するカウンターである。ホールディングレジスターはPWMカウンターとは独立に更新できる。PWMカウンターがオーバーフローしたときは、ホールディングレジスターの値が自動的にPWMカウンターに転送される。

 このプログラムには、CLOCKとACLR、ENABLE、DATA[PWM_WIDTH-1..0]などの入力がある。CLOCKはマスターのシステムクロックである。ACLR以外の信号は全て、このクロックの立ち上がりエッジに同期する。ACLRは電源投入時にハードウェアを初期化し、AVALUEの値をホールディングレジスターに格納する役割を果たす。

 ENABLE=0のときは、PWM出力は0(オフ)になる。ENABLE=1になると、PWM波形をQ出力に発生させる。WRITEのアサートが1クロックサイクル続いたことを確認すると、DATA[PWM_WIDTH-1..0]に入力されたデータをホールディングレジスターに転送する。

 PLDコードはAlteraのハードウェア記述言語「AHDL」で記述した。このコードは、同社のPLDであれば直接コンパイルできる。PLDとして「EPIK10TC100-3」を使えば、最大139MHzで動作する(パラメーターはリスト1に記述したものを使用)。このプログラムはVHDLやVerilog HDLに簡単に変換できる。

Design Ideas〜回路設計アイデア集

【アナログ機能回路】:フィルター回路や発振回路、センサー回路など

【パワー関連と電源】:ノイズの低減手法、保護回路など

【ディスプレイとドライバー】:LEDの制御、活用法など

【計測とテスト】:簡易テスターの設計例、旧式の計測装置の有効な活用法など

【信号源とパルス処理】:その他のユニークな回路



※本記事は、2008年7月29日にEDN Japan臨時増刊として発刊した「珠玉の電気回路200選」に掲載されたものです。著者の所属や社名、部品の品番などは掲載当時の情報ですので、あらかじめご了承ください。
「珠玉の電気回路200選」:EDN Japanの回路アイデア寄稿コラム「Design Ideas」を1冊にまとめたもの。2001〜2008年に掲載された記事から200本を厳選し、5つのカテゴリーに分けて収録した。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSフィード

公式SNS

EDN 海外ネットワーク

All material on this site Copyright © ITmedia, Inc. All Rights Reserved.
This site contains articles under license from AspenCore LLC.