HOME > natural science メンバー > 佐瀬 一弥 > 佐瀬日記

C言語とgnuplotで負荷線を引いてトランジスタの静特性を調べる

文責:佐瀬 一弥 (2011年8月19日) カテゴリ:佐瀬日記(33)

トランジスタのIC-VCE特性がわかればダイオードの時と同様にして、上の回路のIcとVCEを得られる。
Vcc=5[V]、R=1k,2k,4k,6k[ohm]として負荷線を引いてみた。左はIf=20mA、右はIf=15mAのとき。トランジスタのIC-VCE特性はRPR-220のフォトトランジスタのものを用いた。


If=20mA                      If=15mA
トランジスタの静特性と負荷線(R=1k, Vcc=5V)


If=20mA                      If=15mA
トランジスタの静特性と負荷線(R=2k, Vcc=5V)


If=20mA                      If=15mA
トランジスタの静特性と負荷線(R=4k, Vcc=5V)


If=20mA                      If=15mA
トランジスタの静特性と負荷線(R=6k, Vcc=5V)

わかること

・R一定でIfが小さくなるとVceは大きくなる
・Rが大きいほどIc、Vceが小さくなる
・Rが小さいほどIfの変化に対するVceの変化が大きくなる

C言語のソース

/*
ivload.c
コマンドラインで
ivload (引数1:R[ohm]) (引数2:Vcc[ohm]) (iv特性の入ったファイル名)
のようにして実行

I-V特性の入ったファイルを同ディレクトリに入れる
中身は 各行 V[V](半角スペース)I[mA] とする
負荷線を書いたグラフをpngで出力

新しいI-V特性をインポートするときはグラフの設定を変える
・xrange,yrange
・log
など

環境:コンパイラcygwin gcc, gnuplotインストール&パス必要
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[])
{
	FILE *fin;
	FILE *gp;
	double R,Vcc;
	double *Vf,*If;
	int i;
	int size; //ファイルサイズ
	char ss[256];
	double err=1e10; //err = Vcc-Vf-If*R
	int tmp;
	char ivfname[30];
	char graphfname[30];
	
	/* 引数の数をチェック */
	if(argc != 4){
		puts("引数の数が違います\n");
		exit(1);
	}
	
	R=atof(argv[1]);
	Vcc=atof(argv[2]);
	
	/* iv特性ファイルの名前 */
	strcpy(ivfname,argv[3]);
	
	/* グラフの名前 */
	strtok(argv[3],".");//拡張子を削除
	strcpy(graphfname,argv[3]);
	strcat(graphfname,"R");
	strcat(graphfname,argv[1]);
	strcat(graphfname,"Vcc");
	strcat(graphfname,argv[2]);
	strcat(graphfname,".png");
	
	/* ファイルサイズを数える */
	size=0;
	printf(ivfname);
	
	if((fin=fopen(ivfname,"r"))==NULL){
		printf("input file err1!\n");
		exit(1);
	}
	while(fgets(ss,256,fin)!=NULL){
		size++;
	}
	
	fclose(fin);
	
	/* 数えたファイルサイズをもとにメモリ確保 */
	Vf=(double*)calloc(size,sizeof(double));
	if(Vf==NULL){
		printf("calloc err!\n");
		exit(1);
	}
	If=(double*)calloc(size,sizeof(double));
	if(If==NULL){
		printf("calloc err!\n");
		exit(1);
	}
	
	/* ファイルの値を配列にコピー */
	if((fin=fopen(ivfname,"r"))==NULL){
		printf("input file err2\n");
		exit(1);
	}
	for(i=0;i<size;i++){
		fscanf(fin,"%lf %lf\n",Vf+i,If+i);
	}
		
	/* err = Vcc-Vf-If*R がいちばん小さくなるiを探す*/
	for(i=0;i<size;i++){
		if(fabs(err) > fabs(Vcc-Vf[i]-If[i]*R/1000)){
			err = Vcc-Vf[i]-If[i]*R/1000;
			tmp = i;
		}
	}
	
	printf("Vf=%f If=%f\n",Vf[tmp],If[tmp]);
	
	fclose(fin);
	free(Vf);
	free(If);
	
	
	/* グラフ描画 */
	gp = popen("gnuplot -persist","w");
	fprintf(gp,"R=%f\n",R);
	fprintf(gp,"Vcc=%f\n",Vcc);
	fprintf(gp,"set term png enhanced\n");
	fprintf(gp,"set size square\n");
	fprintf(gp,"set grid xtics mxtics ytics mytics\n");
	fprintf(gp,"set xtics 5\n");
	fprintf(gp,"set mxtics 1\n");
	fprintf(gp,"set ytics 0.2\n");
	fprintf(gp,"set mytics 0.1\n");
	fprintf(gp,"set xrange [0:25]\n");
	fprintf(gp,"set yrange [0:2.5]\n");
	fprintf(gp,"set xlabel 'COLLECTOR-EMITTER : V_{CE} (V)'\n");
	fprintf(gp,"set ylabel 'COLLECTOR CURRENT : I_C (mA)'\n");
	fprintf(gp,"set label 1 'V_{CE}=%4.3f   I_C=%4.2f' at graph 0.5,graph 0.05\n",Vf[tmp],If[tmp]);
	fprintf(gp,"set output '%s'\n",graphfname);
	fprintf(gp,"plot '%s' using 1:2 w l lw 2 notitle,(Vcc-x)/R*1000 w l lw 2 title 'load line R=%3.0f Vcc=%3.2f'\n",ivfname,R,Vcc);
	fprintf(gp,"unset output\n");
	pclose(gp);
	
	printf("get a graph in '%s'!\n",graphfname);
	
	return 0;
}



▲このページのトップNPO法人 natural science トップ

▲このページのトップNPO法人 natural science トップ