• 沒有找到結果。

第五章 電路實作

5.6 實驗改善方向

本論文末將針對實作的誤差,提出幾點本實驗可以改善的方向:

1. 本論文實驗提出的無電流感測控制,僅靠二個 A/D 轉換電路感測輸入電壓及輸 出電壓,故此 A/D 轉換電路的可靠度顯得相當的重要,無論是感測出的大小或 是頻寬不足造成時間的誤差,將影響控制的效果。

2. 所提出的控制法中,補償開關及二極體不理想特性的壓降,是假設一定值,但 其壓降的大小會隨著溫度而有所改變,其補償的大小應有所不同,故實驗時半 導體元件散熱也會影響實驗的結果。

第六章 結論

總結以上實驗歸納,若是採用本系統有以下優點:

1. 本電路結構簡單,相較於傳統之電流控制迴路減少了一個控制迴圈,因此可降 低電路複雜造成的誤差。

2. 因取消了電流的控制迴路,減少了電流感測器,因此可以有相較於電流控制迴 路控制更便宜的電路費用。

3. 在本控制推導的方法,亦可用在頻率較高的範圍,且仍保持為理想弦波,使應 用範圍廣泛。

亦有缺點存在:

由於無感測輸入電流,因此我們必須得知電感的感值以及內阻值來加以補 償,其精確程度將與 PFC 效果呈正比。

參考文獻

[1] H. C. Chen,“Duty phase control for single-phase boost-type SMR,”IEEE Trans.

on Power Electron, vol. 23, no. 4,pp. 1927-1934, Jul. 2008.

[2] H. C. Chen,“Single-Loop Current Sensorless Control for Single-Phase Boost-Type SMR,”IEEE Trans. on Power Electron, vol. 24, no. 1, Jan. 2009.

[3] David M. Van de Sype; Koen De Gussemé; Alex P. M. Van den Bossche; Jan A.

Melkebeek, “Duty-Ratio Feedforward for Digitally Controlled Boost PFC Converters,” IEEE Trans on Industrial Electron, vol. 52, no. 1, pp 108-115, Feb.

2005.

[4] PSIM WEBSITE---http://www.powersimtech.com [5] Xilnx, Spartan-3 FPGA Family Data Sheet, 2008.

[6] Laszlo Huber; Yungtaek Jang; Milan M. Jovanovic, “Performance evaluation of bridgeless PFC boost rectifier,” IEEE Trans on Power Electron, vol 23, no. 3,May 2008.

[7] Yungtaek Jang; Milan M. Jovanovic, “A bridgeless PFC boost rectifier with optimized magnetic utilization,” IEEE Trans on Power Electron,vol. 24,no. 1,Jan 2009.

[8]“IEEE Recommended Practices and Requirements for Harmonic Control in Electrical Power Systems,” IEEE Std 519-1992

[9] Jian Sun; Min Chen; Kamiar J. Karimi, “Aircraft Power System Harmonics Involving Single-Phase PFC Converters,” IEEE Trans on Aerospace and Electron, vol. 44, no. 1, pp 217-226, Jan 2008.

[10] Jian Sun, “Analysis and Design of Single-Phase PFC Converters for Airborne Systems,” IEEE, 2003

[11] J. Rajagopalan, F. C. Lee, and P. Nora, “A general technique for derivation of

average current mode control laws for single-phase power-factor correction circuits without input voltage sensing,” IEEE Trans. on Power Electron., vol. 14,no. 4, pp.

663-672, Jul. 1999.

[12] K. Rustom, and I. Batarseh, “Recent Advances in Single-Stage Power Factor Correction,” IEEE International Conference 2003, pp. 1089-1095, vol. 12.

附錄一、程式控制方塊圖

ADC Ad_dip

vs_adin vs_ad ABS

sin_2 s2_final

+ +

vo_ref

ADC Ad_dip2

vo_adin vo_ad

+

-PI error_vo pi_out

<<1

module pfc(clk_40MHz,

da_clk_1,la_1,out_1,out_2,out_3,out_4, //for DA ad_clk_1,sfrm_1,convst_1,sdata_1,sdata_2,dipsw7, //for AD dipsw2,dipsw3,dipsw4, //for KI

dipsw5,dipsw6, //for KP

dipsw1, //for PI

//clk_40k_1,t, //Test Freq

duty,an,bn,startsw); //for tosw

input startsw;

input clk_40MHz;

//output clk_40k_1;

wire [15:0] divider_10M,divider_4M,divider_20k,divider_20M,divider_40k;

wire clk_10MHz,clk_4MHz,clk_4kHz,clk_40kHz;

output duty;

//assign clk_40k_1=clk_40kHz;

//output t;

//除頻器,因為是正緣觸發,本身就除頻為 20MH,再除以(divider+1) assign divider_10M=16'd1;

assign divider_4M=16'd4;

assign divider_20k=16'd999;

assign divider_20M=16'd0;

assign divider_40k=16'd499;

//4 組 DA,硬體電路上的 clk 和 la 腳位共用,故 la_2,la_3,la_4 都設為 la_1,clk 亦同 output da_clk_1,la_1,out_1,out_2,out_3,out_4;

wire la_2,la_3,la_4; //配合程式 DA Module 使用 wire da_clk_2,da_clk_3,da_clk_4; //配合程式 DA Module 使用

wire [15:0] in_1,in_2,in_3,in_4;

assign la_2=la_1;

assign la_3=la_1;

assign la_4=la_1;

assign da_clk_2=da_clk_1;

assign da_clk_3=da_clk_1;

assign da_clk_4=da_clk_1;

assign da_clk_1=clk_10MHz;

//2 組 AD,硬體電路上 sfrm,convst 和 clk 腳位共用

wire adsw; //模組內有設一個開關當 ad 的 switch

assign adsw=1'b0; //adsw=0 時,AD 程式才作用

input sfrm_1,sdata_1,sdata_2;

output ad_clk_1,convst_1;

wire [15:0] vo_adin,vs_adin; //原始 AD 硬體轉換出來的值 wire sfrm_2,ad_clk_2,convst_2; //因 sfrm,convst,adclk 硬體共用

wire [15:0] vo_ad,vs_ad; //修正後的值

assign sfrm_2=sfrm_1;

assign convst_2=convst_1;

assign ad_clk_2=ad_clk_1;

assign ad_clk_1=clk_4MHz;

//assign vo_ad=vo_adin+16'd1224; //補償 MAX121 的 offset,輸入 0V 時,AD 值 FB38=1224 //assign vs_ad=vs_adin+16'd788; //補償 MAX121 的 offset,輸入 0V 時,AD 值 FCEC=788 //誤差放大器

wire [15:0] vo_ref;

wire [15:0] error_vo;

assign vo_ref=16'd13474; //Vo=200V 時,vo_ref=200/92/5*32767=14247,

//Vo=200V 時,60Hz 設 13900 輸出會變低,但 THD 會變好 //Vo=200V 時,400Hz 200W 設 13774,400W 設 13474 波型較佳,600W 設 13574 //PI

input dipsw1; //為 PI 控制器的開關

input dipsw2,dipsw3,dipsw4; //用指撥開關的 3bit module 可以調 KI,KP 或 AD 值 input dipsw5,dipsw6,dipsw7; //同上

wire [15:0] kp;

wire [15:0] ki;

wire [15:0] pi_out;

assign kp=16'd50; //待調整 assign ki=16'd50; //待調整 //zcp

wire vs_plus; //當 Vin 為正時,vs_plus=0 wire [8:0] sin_counter;

//sin_table

wire [15:0] sin,cos,sin_2,cos_2;

wire [15:0] s2_final;

wire [15:0] s2_final2; //s2_final=s2*rL/WL

wire [15:0] s1s2_sum;

wire [15:0] s2_ratio;

wire [2:0] shift_bit1,shift_bit2;

assign s2_ratio=16'd1862; //s2_ratio=rL/WL=0.5/(2*pi*60*4.6*e-3)*32767=9447 //for 1L 60Hz

//s2_ratio=0.3/(2*pi*60*2.6*e-3)*32767=10028 for 2L 60Hz //s2_ratio=0.3/(2*pi*60*2.1*e-3)*32767=12417 for 2L 60Hz //s2_ratio=0.3/(2*pi*400*2.6*e-3)*32767=1504 for 2L 400Hz //s2_ratio=0.3/(2*pi*400*2.1*e-3)*32767=1862 for 2L 400Hz //s2_ratio=0.3/(2*pi*400*0.28*.e-3)*32767=13968 for 2L 400Hz //s2_ratio=0.3/(2*pi*400*0.88*e-3)*32767=4444 for 2L 400Hz assign s2_final2=~s2_final+16'd1; //配合減法器當加法器使用

assign shift_bit1=3'd1; //本查表為最大值 32767 當實際值 1,但 s1+s2>>1 出現, //故先又移 1 位除以 2

assign shift_bit2=3'd1; //同上 //vcont 查表,用查表當 Vcont

//wire [15:0] vcont_200v,vcont_40v,vcont_200v_dis,vcont_40v_dis;

//乘法器

wire [15:0] pi_vlhead,pi_vlhead_2;

wire [15:0] vs_abs_48,vs_abs_92;

wire [15:0] ratio_48_92;

wire [15:0] vf_out;

wire [15:0] v_cont_bef,v_cont_bef2,v_cont,v_cont2;

wire [15:0] vf_comp1,vf_comp2;

wire [2:0] shift_bit3,shift_bit4;

wire [15:0] vo_ratio;

wire duty;

assign vf_comp1=duty?16'd228:16'd199; //導通時壓降為 1.8+1.4,截止時壓降為 //1.4+1.4,vf=壓降/92/5*32767=202(截止) assign vf_comp2=~vf_comp1+16'd1; //配合減法器當加法器使用

assign ratio_48_92=16'd17096; //48/92*32767=17096 assign shift_bit3=3'd1;

assign shift_bit4=3'd2;

assign vo_ratio=16'd18841; //vo_ratio=2.3/4*32737=18841,2.3=92*5/200,需左移 2bit //若輸出為 40V,vo_ratio=92*5/40=11.5,則需左移 4bit,再乘上 11.5/16*32767=23551 //wire [8:0] sin_counter2;

//assign sin_counter2=sin_counter+9'd20;

//將 ZCP 偵測出的零交越點 shift 個值 wire [8:0] triangle_1,triangle_2,vcont;

//tosw

output an,bn;

clk_conversion clk_10M (clk_40MHz,divider_10M,clk_10MHz); //20MHz/(divider+1) clk_conversion clk_4M (clk_40MHz,divider_4M,clk_4MHz);

clk_conversion clk_20k (clk_40MHz,divider_20k,clk_20kHz);

clk_conversion clk_20M (clk_40MHz,divider_20M,clk_20MHz);

clk_conversion clk_40k (clk_40MHz,divider_40k,clk_40kHz);

ad ad_1(ad_clk_1,sdata_1,vo_adin,any1,convst_1,sfrm_1,adsw,t1);

//輸出 vo_ad 為 16bit 值,此 AD 硬體輸入,經取樣轉成 14bit 的值,

//但輸出傳回成 16bit,後面會用到

ad ad_2(ad_clk_2,sdata_2,vs_adin,any2,convst_2,sfrm_2,adsw,t2);

//輸出 vo_ad 為 16bit 值,此 AD 硬體輸入,經取樣轉成 14bit 的值,

//但輸出傳回成 16bit,後面會用到

ad_dip ad_regulator(clk_40kHz,vs_adin,vs_ad,dipsw7,dipsw6,dipsw5,vs_plus);

//判斷輸入電壓 vs 正負,為正時 vs_plus=0,利用指撥開關 5~7 補償一定的數值,調整後為 vs_ad ad_dip2 ad_regulator2(clk_40kHz,vo_adin,vo_ad,dipsw4,dipsw3,dipsw2);

//利用指撥開關 2~4 調整 vo_adin,調整後為 vo_ad

da da_1(la_1,clk_10MHz,out_1,in_1); //DA 出來只有正負 3V,再經過硬體電路放大 3.3 倍 da da_2(la_2,clk_10MHz,out_2,in_2);

da da_3(la_3,clk_10MHz,out_3,in_3);

da da_4(la_4,clk_10MHz,out_4,in_4);

subtraction voltage(vo_ref,vo_ad,error_vo);

//減法器為 vo_ref-vo_adin(或 vo_ad),同 16bit

pi voltage_controller(error_vo,pi_out,kp,ki,clk_40kHz,dipsw1);

//pi_out=VL_head,dipsw1 為 PI 的開關

zcp vin_zcp(clk_40kHz,vs_plus,vs_ad,sin_counter);

//零交越點偵測電路,為了要查表用,輸入為 vs_adin(或 vs_ad)

Hz_sin_table sin_list(sin,cos,sin_counter); //可得到 sin 和 cos 查表值 //60Hz 使用 sin_table,400Hz 使用 Hz_sin_table

shift_R s1(clk_40kHz,shift_bit1,cos,cos_2); //左 shift_bit1 數,最多移 4 位 shift_R s2(clk_40kHz,shift_bit2,sin,sin_2);

multiplication s2_multi(sin_2,s2_ratio,s2_final); //s2_final=sin_2*s2_ratio //1/60 sec 用 40kHz 取樣的話,會有 666 點

//s2_final=s2*rL/WL 值,s2_ratio 為 rL/WL=0.5/(2*pi*60*4.6*e-3)*32767 subtraction s1s2_sum_module(cos_2,s2_final2,s1s2_sum);

//s2_final2 為 s2_final 取負值,配合減法器取代加法器 //因此 s1s2_sum=cos_2+s2_final1

multiplication pi_compensate(pi_out,s1s2_sum,pi_vlhead);

//pi_vlhead=pi_out*s1s2_sum

shift_L pi_vlhead_shift(clk_40kHz,shift_bit3,pi_vlhead,pi_vlhead_2);

//pi_vlhead_2 為 pi_vlhead 左移(shift_bit3)位數

subtraction vf_compensate(pi_vlhead_2,vf_comp2,vf_out);

//vf_out 為 pi_vlhead_2+vf_comp1,vf+comp1 為導通或截止的補償值 absolute vs_voltage(clk_40kHz,vs_ad,vs_abs_48);

//vs_abs_48 為 vs 電壓降為 1/48 之 AD 值

multiplication vs_voltage_multi(vs_abs_48,ratio_48_92,vs_abs_92);

//vs_abs_92 為 vs 電壓轉為 1/92

//cont_table control(vcont_200v,vcont_40v,sin_counter);

//用查表當 vcont

subtraction v_cont_before(vs_abs_92,vf_out,v_cont_bef);

//v_cont_bef=vs_abs_92-vf_out

multiplication v_cont_multi(v_cont_bef,vo_ratio,v_cont_bef2);

//v_cont_bef2=v_cont_bef*vo_ratio

shift_L v_cont_shift(clk_40kHz,shift_bit4,v_cont_bef2,v_cont);

//v_cont=v_cont_bef2 左移(shift_bit4)位數 latch latch_1(v_cont,v_cont2,clk_40kHz);

triangle tr(v_cont2,duty,duty2,clk_40MHz,startsw,triangle_1,triangle_2,vcont);

// clk/1000 為三角波的頻率,vcont=v_cont 取 9bit tosw tosw1(duty,vs_plus,an,bn,startsw);

//startsw=0 時,開關訊號才會送出

//ki_dip ki_ki(clk_40kHz,ki,dipsw4,dipsw3,dipsw2);

//kp_dip kp_kp(clk_40kHz,kp,dipsw4,dipsw3,dipsw2);

//DA 要顯示的 assign in_1=vs_ad;

assign in_2=cos;

assign in_3=sin;

assign in_4=pi_vlhead;

endmodule

減法器(subtraction.v):

module subtraction(minuend,subtrahend,error);

input [15:0] minuend,subtrahend;

output reg [15:0] error;

reg [1:0] sign_bit;

always @(minuend,subtrahend) begin

sign_bit[1]=minuend[15];

sign_bit[0]=subtrahend[15];

case(sign_bit) 2'b00:

error=minuend-subtrahend;

2'b10:

begin

error=minuend-subtrahend;

if(error[15]==0)

error=16'b1000_0000_0000_0000;

end 2'b11:

error=minuend-subtrahend;

2'b01:

begin

error=minuend-subtrahend;

if(error[15]==1)

error=16'b0111_1111_1111_1111;

end endcase

end endmodule

乘法器(multiplication.v):

module multiplication (multiplicand,multiplier,answer);

input [15:0] multiplicand,multiplier;

output reg [15:0] answer;

reg [15:0] multiplicand_p,multiplier_p;

reg [31:0] answer_temp;

reg [1:0] sign_bit;

always @(multiplicand,multiplier) begin

if(multiplicand[15]) begin

if(multiplicand==16'b1000_0000_0000_0000) multiplicand_p=16'b0111_1111_1111_1111;

else

multiplicand_p=~multiplicand+16'd1;

end else

multiplicand_p=multiplicand;

if(multiplier[15]) begin

if(multiplier==16'b1000_0000_0000_0000) multiplier_p=16'b0111_1111_1111_1111;

else

multiplier_p=~multiplier+16'd1;

end else

multiplier_p=multiplier;

sign_bit[0] = multiplicand[15];

sign_bit[1] = multiplier[15];

answer_temp=(multiplicand_p*multiplier_p)<<1;

case (sign_bit) 2'b00:

answer=(answer_temp)>>16;

2'b01:

answer=(~answer_temp+1)>>16;

2'b10:

answer=(~answer_temp+1)>>16;

2'b11:

answer=(answer_temp)>>16;

endcase end

endmodule

PI 控制器(PI.v):

module pi(error,PI_out,kp,ki,clk,start);

input start,clk;

input [15:0] error,kp,ki;

output [15:0] PI_out;

reg [15:0] y;

reg [2:0] contr_win;

reg [15:0] kp_c;

reg [15:0] ki_c;

reg [31:0] multi_temp_kp;

reg [31:0] multi_temp_ki;

reg [31:0] sum_temp_kp;

reg [31:0] sum_temp_ki;

reg [15:0] Duty_PI;

reg buffer;

wire [15:0] PI_out;

always @(negedge clk) begin

if(!start) begin

if(!error[15]) y=error;

else begin

if(error==16'b1000_0000_0000_0000) y=16'b0111_1111_1111_1111;

else

y=~error+16'd1;

end if(ki[15]==1)

begin

if(ki==16'b1000_0000_0000_0000) ki_c=16'b0111_1111_1111_1111;

else

ki_c=~ki+16'd1;

end else

ki_c=ki;

if(kp[15]==1) begin

if(kp==16'b1000_0000_0000_0000) kp_c=16'b0111_1111_1111_1111;

else

kp_c=~kp+16'd1;

end else

kp_c=kp;

contr_win[0] = error[15];

contr_win[1] = ki[15];

contr_win[2] = kp[15];

multi_temp_kp=kp_c*y;

multi_temp_ki=ki_c*y;

multi_temp_kp=multi_temp_kp<<1;

multi_temp_ki=multi_temp_ki<<1;

case (contr_win)

3'b001:

begin

multi_temp_kp=~multi_temp_kp+1;

multi_temp_ki=~multi_temp_ki+1;

end 3'b011:

begin

multi_temp_kp=~multi_temp_kp+1;

multi_temp_ki=multi_temp_ki;

end 3'b010:

begin

multi_temp_kp=multi_temp_kp;

multi_temp_ki=~multi_temp_ki+1;

end 3'b000:

begin

multi_temp_kp=multi_temp_kp;

multi_temp_ki=multi_temp_ki;

end 3'b100:

begin

multi_temp_kp=~multi_temp_kp+1;

multi_temp_ki=multi_temp_ki;

end 3'b101:

begin

multi_temp_kp=multi_temp_kp;

multi_temp_ki=~multi_temp_ki+1;

end 3'b110:

begin

multi_temp_kp=~multi_temp_kp+1;

multi_temp_ki=~multi_temp_ki+1;

end 3'b111:

begin

multi_temp_kp=multi_temp_kp;

multi_temp_ki=multi_temp_ki;

end endcase

buffer=sum_temp_ki[31];

sum_temp_ki=sum_temp_ki+multi_temp_ki;

if((multi_temp_ki[31]==0) & (buffer==0)) begin

if (sum_temp_ki[31]==1)

sum_temp_ki=32'h7FFF_FFFF;

end

if ((multi_temp_ki[31]==1) & (buffer==1)) begin

if (sum_temp_ki[31]==0)

sum_temp_ki=32'h8000_0000;

end

sum_temp_kp=sum_temp_ki+multi_temp_kp;

if((sum_temp_ki[31]==0) & (multi_temp_kp[31]==0)) begin

if (sum_temp_kp[31]==1) sum_temp_kp=32'h7FFF_FFFF;

end

if ((sum_temp_ki[31]==1 )& (multi_temp_kp[31]==1)) begin

if (sum_temp_kp[31]==0) sum_temp_kp=32'h8000_0000;

end

Duty_PI[15:0]=sum_temp_kp[31:16];

end else

begin

Duty_PI=16'd0;

y=16'd0;

contr_win=3'd0;

kp_c=16'd0;

ki_c=16'd0;

multi_temp_kp=32'd0;

multi_temp_ki=32'd0;

sum_temp_kp=32'd0;

sum_temp_ki=32'd0;

buffer=1'd0;

end end

assign PI_out=Duty_PI;

endmodule

左移(shift_L.v)

module shift_L(clk,shift_bit,vin,vin_shift);

input clk;

input [15:0] vin;

input [2:0] shift_bit;

reg vin_sign=1'b0;

reg [15:0] vin_temp;

output reg [15:0] vin_shift=16'd0;

always@(posedge clk) begin

if(vin[15]==1'b0) begin

vin_temp=vin;

case(shift_bit) 3'd1:begin

if((vin_temp[14]==1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end 3'd2:begin

if((vin_temp[14]==1)||(vin_temp[13]==1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end

3'd3:begin

if((vin_temp[14]==1)||(vin_temp[13]==1)||(vin_temp[12]==1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end 3'd4:begin

if((vin_temp[14]==1)||(vin_temp[13]==1)||(vin_temp[12]==1)||(vin_temp[11]==

1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end

default: vin_temp=vin_temp;

endcase

vin_shift=vin_temp;

end

else //相當 vin 為負值時 begin

vin_temp=~vin+16'd1;

case(shift_bit) 3'd1:begin

if((vin_temp[14]==1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end 3'd2:begin

if((vin_temp[14]==1)||(vin_temp[13]==1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end 3'd3:begin

if((vin_temp[14]==1)||(vin_temp[13]==1)||(vin_temp[12]==1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end 3'd4:begin

if((vin_temp[14]==1)||(vin_temp[13]==1)||(vin_temp[12]==1)||(vin_temp[11]==

1)) vin_temp=16'h7FFF;

else vin_temp=vin_temp<<shift_bit;

end

default: vin_temp=vin_temp;

endcase

vin_shift=~vin_temp+16'd1;

end end endmodule

右移(shift_L.v)

module shift_R(clk,shift_bit,vin,vin_shift);

input clk;

input [15:0] vin;

input [2:0] shift_bit;

reg vin_sign=1'b0;

output reg [15:0] vin_shift=16'd0;

always@(posedge clk) begin

vin_sign=vin[15];

if(vin[15]==1'b1) begin

vin_shift=vin>>shift_bit;

vin_shift[15]=1'b1;

end else

begin

vin_shift=vin>>shift_bit;

vin_shift[15]=1'b0;

end end

endmodule

零交越偵測(zcp.v)

module zcp(clk,vin_plus,vin,sin_counter);

input clk;

input [15:0] vin;

output reg [8:0] sin_counter=9'd1;

output reg vin_plus=1'b0;

reg check_zero=1'b0;

always @(posedge clk) begin

vin_plus=vin[15];

sin_counter=sin_counter+9'd1;

if(check_zero!=vin_plus) begin check_zero=vin_plus;

end endmodule

AD 程式(ad.v)

module ad(clk,in,out_1,out_2,convst,sfrm,start,test);

input clk,sfrm,in,start;

output reg convst=1,test=0;

output reg [15:0] out_1=16'd0,out_2=16'd0;

reg [6:0] counter_1=7'd1;

reg [3:0] counter_2=4'b1110,counter_3=4'd1;

reg [15:0] data=16'd0;

reg i=1'd0;

always @ (negedge clk) begin

if(!start) begin

if(counter_1==5'd0)

begin

convst=1'b0;

counter_1=counter_1+5'b0_0001;

end

else if(counter_1==5'd1) begin

convst=1'b1;

counter_1=counter_1+5'b0_0001;

end

else if(counter_1==5'd19) counter_1=5'b0_0000;

else

counter_1=counter_1+5'b0_0001;

if(sfrm==1'b0) begin if(i==1'd0)

begin

data[counter_2-4'b0001]=in;

counter_2=counter_2-4'b0001;

if(counter_2==4'd0) begin

i=1'd1;

if(counter_3==4'd1) begin

out_1=(data<<2);

counter_3=counter_3+4'd1;

test=1;

end

else if(counter_3==4'd2) begin

out_2=(data<<2);

counter_3=counter_3+4'd1;

test=0;

end

else if(counter_3==4'd5)

//改 counter_3 會改送出資料的頻率,原來 10 是 20K,改成 5 變 40K counter_3=4'd1;

else

counter_3=counter_3+4'd1;

end

counter_2=4'b1110;

end end

else begin

counter_2=4'b1110;

counter_3=4'd1;

out_1=16'd0;

out_2=16'd0;

data=16'd0;

i=1'd0;

counter_1=5'd0;

convst=1;

end end

endmodule

DA 程式(da.v)

module da(la,clk,out,in);

output reg out=0,la=0;

input clk;

reg [15:0] data_save=16'd0;

reg [4:0] counter=5'd15;

input [15:0] in;

always @(negedge clk) begin

if(counter==5'd15) begin

data_save=in;

out=data_save[counter];

la=0;

end

else if(counter==5'd7) begin

la=1;

out=data_save[counter];

end

else if(counter==5'd0) begin

out=data_save[counter];

counter=5'd16;

end else

out=data_save[counter];

counter=counter-1'd1;

end endmodule

除頻程式(clk_conversion.v)

module clk_conversion(clk_in,divider,clk_out);

input clk_in;

input [15:0] divider;

output reg clk_out=1'd0;

reg [15:0] counter=16'd0;

always@(posedge clk_in) begin

if(counter==divider) begin

counter=16'd0;

clk_out=~clk_out;

end else

counter=counter+1;

end endmodule

三角波兼比較器(triangle.v)

module

triangle(vcont_temp,PWM_1_out,PWM_2_out,clk,start,triangle_1,triangle_2,vcont);

output reg PWM_1_out=1'b0,PWM_2_out=1'b0;

output reg [8:0] triangle_1=9'd0,triangle_2=9'd500,vcont=9'd0;

input [15:0] vcont_temp;

reg i=1'b0;

input clk,start;

always @ (negedge clk) begin

//將 vcont 往上移 if(!start)

begin

if(vcont_temp[15]) //vcont_temp[15]=1 的時候,vcont=0 vcont=9'd0;

else begin

vcont[8:0]=vcont_temp[14:6];

if(vcont>9'd500)

vcont=9'd500; //(解析度) end

if(i==1'b1) begn

triangle_1=triangle_1-1'b1;

triangle_2=triangle_2+1'b1;

if(triangle_1==9'd0) i=1'b0;

end else

begin

triangle_1=triangle_1+1'b1;

triangle_2=triangle_2-1'b1;

if(triangle_1==9'd500) i=1'b1;

end

if(vcont>triangle_1) PWM_1_out=1'b0;

else

PWM_1_out=1'b1;

if(vcont<triangle_2) PWM_2_out=1'b0;

else

PWM_2_out=1'b1;

end

else begin

triangle_1=9'd0;

triangle_2=9'd500;

PWM_1_out=1'b0;

PWM_2_out=1'b0;

i=1'b0;

vcont=9'd0;

end end

endmodule

開關(tosw.v)

module tosw(duty,vin_plus,an,bn,startsw);

input duty,vin_plus,startsw;

output reg an=1'b0,bn=1'b0;

always @(duty) begin

if (startsw==1'b0) begin

if (vin_plus==1'b0) //輸入電壓正半週期 begin

if(duty==1'b1) begin

if(duty==1'b1) begin

end endmodule

絕對值(absolute.v)

module absolute(clk,vin,vin_abs);

input clk;

input [15:0] vin;

output reg [15:0] vin_abs=16'd0;

always @(clk) begin

if(vin[15]==1'b1) vin_abs=~vin+16'd1;

else vin_abs=vin;

end endmodu

指撥開關調整 AD 值(ad_dip.v)

module ad_dip(clk,adin,adout,pin_1,pin_2,pin_3,ad_plus);

input [15:0] adin;

input clk,pin_1,pin_2,pin_3,ad_plus;

output reg [15:0] adout;

reg [2:0] x=3'd0;

always @(negedge clk) begin

if(ad_plus==1'b0) begin

adout=adin+16'd788;

//t=1'b1;

x[0]=~pin_3;

case(x)

3'b000: adout=adin+16'd788;

//補償 MAX121 的 offset,輸入 0V 時,AD 值 FCEC=788, 3'b001: adout=adin+16'd1200;

3'b010: adout=adin+16'd1230;

3'b011: adout=adin+16'd1260;

3'b100: adout=adin+16'd1290;

3'b101: adout=adin+16'd1320;

3'b110: adout=adin+16'd1350;

3'b111: adout=adin+16'd1380;

endcase end

end endmodule

指撥開關調整 KI 值(ki_dip.v)

module ki_dip(clk,ki,pin_1,pin_2,pin_3);

input clk,pin_1,pin_2,pin_3;

output reg [15:0] ki;

reg [2:0] x=3'd0;

always @(negedge clk) begin

x[2]=~pin_1;

x[1]=~pin_2;

x[0]=~pin_3;

case(x)

3'b000: ki=16'd10;

3'b001: ki=16'd50;

3'b010: ki=16'd100;

3'b011: ki=16'd200;

3'b100: ki=16'd300;

3'b101: ki=16'd500;

3'b110: ki=16'd700;

3'b111: ki=16'd900;

endcase end

endmodule

指撥開關調整 KP 值(kp_dip.v)

module kp_dip(clk,kp,pin_1,pin_2,pin_3);

input clk,pin_1,pin_2,pin_3;

output reg [15:0] kp;

reg [2:0] x=3'd0;

always @(negedge clk) begin

x[2]=~pin_1;

x[1]=~pin_2;

x[0]=~pin_3;

case(x)

3'b000: kp=16'd50;

3'b001: kp=16'd100;

3'b010: kp=16'd150;

3'b011: kp=16'd200;

3'b100: kp=16'd300;

3'b101: kp=16'd500;

3'b110: kp=16'd800;

3'b111: kp=16'd1000;

endcase end

endmodule

60Hz 三角函數查表(sin_table.v)

module sin_table(sin,cos,sin_counter);

output reg [15:0] sin=16'd0,cos=16'd0;

input [8:0] sin_counter;

always @ (sin_counter) begin

case(sin_counter)

9'd 1 :begin sin=16'd 0 ; cos=16'd 32767 ; end endcase

end endmodule

400Hz 三角函數查表(Hz_sin_table.v)

module Hz_sin_table(sin,cos,sin_counter);

output reg [15:0] sin=16'd0,cos=16'd0;

input [8:0] sin_counter;

always @ (sin_counter) begin

always @ (sin_counter) begin

相關文件