製作手順


※上記の広告は60日以上更新のないWIKIに表示されています。更新することで広告が下部へ移動します。

4.製作手順
4.1構成
全体の構成は、図8-4-1のようになっています。大元の電源供給は15V、1A程度のものが必要になりますが、今回はスイッチング方式のACアダプタを使いました。このACアダプタの供給能力は最大15V1.6Aとなっています。
この15V電源をトランジスタ2SA1714でスイッチングして負荷に供給し、120μHのチョークコイルとC1のコンデンサでリップル成分を取り除いた直流にして負荷に供給しています。D1はトランジスタがOFFの間に負荷に電流を供給するフライホイールダイオードです。このダイオードにも負荷と同じ電流が流れていますので、電圧降下の小さいショットキダイオードか、ファーストリカバリダイオードを使って発熱を小さくする必要があります。トランジスタのスイッチング制御は、PICのPWMによる制御で行いますが、そのフィードバックを出力電圧と出力電流の測定値で行います。PWMのパルスは、PICのクロック20MHzで9ビット分解能として、役40kHzの周期としています。
出力フィードバック制御の基準となる電圧と電流は、外部から可変抵抗で設定することができるようにします。
負荷電流の測定は、R1での電圧降下を利用して行いますが、R1の抵抗値は発熱の問題で大きくできません。このため電圧降下も小さな電圧となりますので、オペアンプで増幅して測定します。
PIC電源は、大元の電源から3端子レギュレータで5Vを作って供給しています。

4.2回路設計
この全体構成をベースにして制作した回路図が図8-4-2です。スイッチング動作そのものは、トランジスタ2SA1741で行いますが、このトランジスタのベース電圧は15Vと高いですから、PICでは直接ドライブできません。そこで、もう1つトランジスタを追加してドライブしています。このドライブ用トランジスタをPICのPWMで制御しています。約40kHzのPWM周期になりますから、トランジスタの周波数特性などは特に問題なく通常のトランジスタで十分です。最大負荷のときに少し発熱しますので、小型の放熱器をつけています。
スイッチングのフライホイールダイオードには、ファーストリカバリダイオードを使います。ここにも負荷と同じだけの電流が流れますので、ダイオードの許容電流値は大き目のものを選択しておきましょう。
チョークコイルには120μH、2Aのものを使いましたが、ちょっと大きめなので、1Aクラスで良いかと思います。平滑用のコンデンサには、チップタイプの大容量セラミックコンデンサと大容量の電解コンデンサを組み合わせて、周波数の高いリップルができるだけ出力に現れないようにしています。

PWMパルスのデューティを制御することで、電圧と電流を一定に保つように制御するのですが、そのフィードバック用として負荷電流の計測値を使って制御しています。
まず負荷電流は、電流計測用の0.5Ωの抵抗での電圧降下値をオペアンプで増幅しています。負荷電流が1Aのときにオペアンプの出力電圧が2.5Vとなるようにしますので、オペアンプの増幅率は2.5V÷0.5Vで5倍ということになります。このオペアンプの出力を、PICのA/D変換入力のチャンネル0としています。
次に出力電圧値は、出力電圧を直接抵抗で分圧して10V出力のときに2.5Vとなるように可変抵抗で調節して、PICのA/D変換入力のチャンネル1としています。
A/D変換用のリファレンス電圧は、精度を良くするため電圧標準ICを使いました。これで正確な2.5Vを得ることができますので、これをそのままリファレンス電圧としてPICに入力しています。
電圧と電流の設定値のPICへの入力も、この2.5Vを可変抵抗で分圧して、それぞれPICのA/D変換入力のチャンネル2、3として入力します。これを最大10Vと最大1Aの設定値として使います。

PICとオペアンプ用の+5V電源は、大元の15Vから3端子レギュレータで制作しています。
液晶表示器との接続は、4ビットのデータとE(STB)とRSの制御信号のみとしています。出力だけしか使いませんので、RW端子はGNDに直接接続しています。輝度調整用の可変抵抗は、液晶表示器本体側に直接取り付けるようにしました。

4.3プログラム作成
この定電圧定電流電源の制御プログラムは、PIC16F819を使って、C言語で作成しています。
実験で使用するプログラムは以下の通りです。
void main()
{
set_tris_a(0xFF);

setup_adc_ports(ANALOG_NOT_RE1_RE2_REF_RA3);

setup_adc(ADC_CLOCK_DIV_32);

setup_ccp1(CCP_PWM);
set_pwm1_duty(0);
setup_timer_2(T2_DIV_BY_1,0x7F,1);

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_8);

settimer0(0x4B);
sec=288usec

duty = 0;
volt = 0;
current = 0;
set_curnt = 0;
set_volt = 0;

lcd_init();
lcd_clear();
printf(lcd_data,” Start!!” );

enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);


while(1)
{
float data;

lcd_cmd(0x80);
printf(lcd_data, “Set “);
data = ((float)set_volt * 10.0) / 1024;
printf(lcd_data, “%02.2fV “,data);
data = ((float)set_curnt * 1000.0) / 1024;
printf(lcd_data, “%03.0fmA” , data);

lcd_cmd(0xc0);
printf(lcd_data, “Now “);
data = ((float)volt * 10.0) / 1024;
printf(lcd_data, “%02.2fV “,data);
data = ((float)current * 1000.0) / 1024;
printf(lcd_data, “03.0fmA” , data);
delay_ms(50);
}
}


#INT_TIMER0
void isr_t0(void)
{
set_timer0(0x4B);

set_adc_channel(2);
delay_us(20);
set_volt = read_adc();
set_adc_channel(4);
delay_us(20);
set_curnt = read_adc();
set_adc_channel(0);
delay_us(20);
current = read_adc();
set_adc_channel(1);
delay_us(20);
volt = read_adc();
volt = volt ? (currenr / 20);

if(current > set_curnt)
{
output_high(RedLED);
if(duty > 0)
	duty --;
else
	duty = 0;
}
else
{
output_low(RedLED);
if(volt > set_volt)
{
if(duty > 0)
	duty --;
else
	duty = 0;
}
if(volt < set_volt)
{
if(duty < 511)
	duty ++;
else
	duty = 511;
}
}
set_pwm1_duty(duty);
}