📄 trans.c
字号:
# include "TRANS.h"
# include "UART0.h"
extern unsigned int PLUS_[2][6] = {1};
static unsigned int TRANS_PLUS = 0;
static unsigned char TRANS[PARAM_SUM][TRANS_HITS] = {0};
static unsigned int DAC_IC = 0;
static unsigned int TRANS_Plus_Temp = 0;
static unsigned Line_NO = 0;
//供电电压为9V,则最大值最好在60以内,
//此时最大饱和值为50*60=3000--2.4V*3=7.2V
static unsigned char IC_Indent[LINES_SUM] = {35, 40, 45, 50, 55, 60};
////////////////////////////////////////
//static int Ib_I_Sum=0; //积分项不用
static int Ib_Current_Error=0;
static int Ib_Present_Error=0;
static int Ib_CV = 100;
static unsigned char PID_Flag=0;
////////////////////////////////////////
////////////////////////////输入特性测试/////////////////////////
static unsigned int NPN_IMP_IC[IMP_LINE_SUM] = {700, 1500};
static unsigned int PNP_IMP_IC[IMP_LINE_SUM] = {2500, 1000};
/*********************************第四版本修正说明:****************************
一:基极供电由原来的扩大两倍,修改为扩大三倍,程序部分对应修改为
Transistor[IB] = (AD_Result_Array[3] - AD_Result_Array[2])*3;
//AD_Result_Array[3] * 3//
二:射极采样使用了电压跟随,同时进行了三倍衰减,这样采样后恢复实际值也要乘上三倍
Transistor[VCE] = (AD_Result_Array[0] - AD_Result_Array[1])*3;
//AD_Result_Array[1] * 3//
三:确定电源电压为9V,基极电流由0.01MA按0.01MA自增,采样线为6时,最大基极电流为0.06MA
同时,集电极电压最大等差增量确定为60,此时最大饱和值为40*60=2400--2V*3=6V,
四:确定集电极电流IC绘图压缩率为30,VCE为15;
************************************第五版修正说明******************************
五:改进了采样线第一个点Vce的坐标修正方法,即使第一个误差点的坐标与第二个点坐标
相等
六:改进了容错宏的执行条件,即只有等Index=2时才开始执行,用第三个点和第二个点比较才
有意义,因为第一个点是误差点,第二个点才是正确的采样点
七:DAC设置后延时确定为5MS
************************************第六版修正说明******************************
八:DAC设置后延时改为3MS
九:PD调节部分,Kp参数变为0.5,Kd参数变为0.25,响应曲线和动态性能比较好
十:同样PD调节部分,加了TRANS_Type参数,可以对NPN和PNP型基极电流进行反馈控制
************************************第七版修正说明******************************
十一:增加了测试PNP特性曲线的函数,下一步需要将两个函数合并
十二:硬件部分增加了一个继电器,射极电压测压使用了可调电阻,这样可以精确的定位为3倍
关系,这一点很重要
************************************第八版修正说明******************************
十三:测试NPN与PNP的函数被整合到了一起,对外部留了三个参数做为接口,另外,继电器
驱动端口使用了宏定义,方便程序修改
*******************************************************************************/
void TRANS_Device_INIT(void)
{
P4DIR |= RELAY_PORT; //P4.0用于控制继电器开关动作
CLOSE_RELAY;
}
void Show_Transistor(unsigned int Index,
unsigned char Testing_Type)
{
unsigned int AD_Result_Array[5] = {0};
unsigned long IC_Temp = 0;
unsigned long IB_Temp = 0;
int Transistor[PARAM_SUM]={0};
//TRANS_STR_INIT;
Get_ADC12_SM(AD_Result_Array);
GET_IB;
GET_IC;
GET_VCE;
////输入特性//////////////////////////////////////
GET_VBE;
//////////////////////////////////////////////////上位机程序数据发送
if(Testing_Type == OUT)
{ //输出上位机传送
UART_Send_xy((unsigned int*)&Transistor[VCE], (unsigned int*)&Transistor[IC], 1);
}
else if(Testing_Type == IMPT)
{ //输入上位机传送
UART_Send_xy((unsigned int*)&Transistor[VBE], (unsigned int*)&Transistor[IB], 1);
}
/////////////////////////////////////////////////截止于此
if((Index > (TRANS_HITS - 6))&&(Index < TRANS_HITS))
{
IC_Temp = 100*(unsigned long)Transistor[IC];//求放大倍数
IB_Temp = (unsigned long)Transistor[IB];
Transistor[PLUS] = (unsigned int)(IC_Temp / IB_Temp);
TRANS_Plus_Temp += Transistor[PLUS];
}
if(Index == (TRANS_HITS - 1))
{
TRANS_PLUS = TRANS_Plus_Temp / 5;
///UART_Show_Number(PLUS_[Line_NO/6][Line_NO%6], 1);
Line_NO = (Line_NO+1)%12;
TRANS_Plus_Temp = 0;
} //数据进入液晶缓存 //Vce的压缩率取10-20之间
/////////////////////////////输出特性测Vce/////////////////////////////////
TRANS[VCE][Index] =Get_Real_Value(Transistor[VCE], 1)/15;
////////////////////////////输入特性,除以十,精确到0.1mv///////////////////
TRANS[VBE][Index] = Get_Real_Value(Transistor[VBE], 1)/10;
if(Index > 1)
{
TRANS_VCE_CE;
TRANS_VBE_CE;
}
//////////////////////////////输出特性测Ic//////////////////////////////////
TRANS[IC][Index] = Get_Real_Value(Transistor[IC], 1)/30;
///////////////////////////////输入特性测Ib/////////////////////////////////
TRANS[IB][Index] = Get_Real_Value(Transistor[IB], 1)/30;
if(Index > 1)
{
TRANS_IC_CE;
TRANS_IB_CE;
}
//TRANS_STR_SHOW;
//UART_Show_Number(Get_Real_Value(Transistor[IB], 1), 1);
}
Trans_Info *TRANS_Import_Measure(unsigned char TRANS_Type,
unsigned char Time)
{
unsigned int DAC_Ib = 0;
unsigned char i =0;
static Trans_Info Trans = {NULL,NULL,0};
if(TRANS_Type == NPN)
{
SEND_NPN_IN;
Set_DAC_Data(NPN_IB_INIT, 3);
DAC_DELAY;
DAC_Ib = NPN_IB_INIT+120; //这个增量必须加上,否则将引入很大的误差
Set_DAC_Data(NPN_IMP_IC[Time], 2);
DAC_DELAY;
for(i=0; i< TRANS_HITS; i++)
{
DAC_Ib += IB_INDENT;
Set_DAC_Data(DAC_Ib, 1);
DAC_DELAY;
Show_Transistor(i, IMPT);
}
TRANS[VBE][0] = TRANS[VBE][1]; //第一个通常是误差点
TRANS[IB][0] = TRANS[IB][1]; //所以将第一个点与第二个点重合来画
SEND_OVER;
}
else if(TRANS_Type == PNP)
{
Set_DAC_Data(PNP_IB_INIT, 3);
DAC_DELAY;
SEND_PNP_IN;
DAC_Ib = PNP_IB_INIT-120;
Set_DAC_Data(PNP_IMP_IC[Time], 2);
DAC_DELAY;
for(i=0; i< TRANS_HITS; i++)
{
DAC_Ib -= IB_INDENT;
Set_DAC_Data(DAC_Ib, 1);
DAC_DELAY;
Show_Transistor(i, IMPT);
}
TRANS[VBE][0] = TRANS[VBE][1]; //第一个通常是误差点
TRANS[IB][0] = TRANS[IB][1]; //所以将第一个点与第二个点重合来画
SEND_OVER;
}
TRANS_Measure_Over();
Trans.Ptr_x = TRANS[VBE];
Trans.Ptr_y = TRANS[IB];
return &Trans;
}
Trans_Info * TRANS_Out_Measure(unsigned char TRANS_Type,
unsigned char Time)
{
unsigned int i=0;
static Trans_Info Trans = {NULL,NULL,0};
if(TRANS_Type == NPN)
{
SEND_NPN_OUT;
CLOSE_RELAY;
Set_DAC_Data(NPN_VC_INIT, 3);
DAC_IC = NPN_VC_INIT; //设置集电极起始电压
//设置基极电压
Set_Ib(Get_SP(126, 126, Time), NPN_VCE_SATUR, NPN);
DAC_DELAY; //待电压稳定,各参数建立完成
for(i=0; i< TRANS_HITS; i++)
{ //设置集电极电压,每次递增TRANS_IC_INDENT
Set_DAC_Data(DAC_IC, 2);
DAC_IC += IC_Indent[Time];
DAC_DELAY; //待电压稳定,各参数建立完成
Show_Transistor(i, OUT);
}
TRANS[VCE][0] = TRANS[VCE][1]; //第一个通常是误差点
TRANS[IC][0] = TRANS[IC][1]; //所以将第一个点与第二个点重合来画
SEND_OVER;
}
else if(TRANS_Type == PNP)
{
SEND_PNP_OUT;
Set_DAC_Data(PNP_VC_INIT, 3);
DAC_DELAY;
DAC_IC = PNP_VC_INIT; //设置集电极起始电压
//设置基极电压
Set_Ib(Get_SP(126, 126, Time), PNP_VCE_SATUR, PNP);
DAC_DELAY; //待电压稳定,各参数建立完成
for(i=0; i< TRANS_HITS; i++)
{ //设置集电极电压,每次递减TRANS_IC_INDENT
Set_DAC_Data(DAC_IC, 2);
DAC_IC -= IC_Indent[Time];
if(DAC_IC <650)
{
DAC_IC = 650;
}
DAC_DELAY; //待电压稳定,各参数建立完成
Show_Transistor(i, OUT);
}
TRANS[VCE][0] = TRANS[VCE][1]; //第一个通常是误差点
TRANS[IC][0] = TRANS[IC][1]; //所以将第一个点与第二个点重合来画
SEND_OVER;
}
TRANS_Measure_Over();
Trans.Ptr_x = TRANS[VBE];
Trans.Ptr_y = TRANS[IB];
Trans.wPlus = TRANS_PLUS;
return &Trans;
}
Trans_Info *Diode_Measure(void)
{
unsigned char i = 0;
unsigned int DAC_Ib = 0;
static Trans_Info Trans = {NULL,NULL,0};
DIODE_IMPT;
Set_DAC_Data(NPN_IB_INIT, 3);
DAC_DELAY;
DAC_Ib = NPN_IB_INIT+120;
for(i=0; i< TRANS_HITS;i++)
{
DAC_Ib += IB_INDENT;
Set_DAC_Data(DAC_Ib, 1);
DAC_DELAY;
Show_Transistor(i, IMPT);
}
TRANS[VBE][0] = TRANS[VBE][1]; //第一个通常是误差点
TRANS[IB][0] = TRANS[IB][1]; //所以将第一个点与第二个点重合来画
SEND_OVER;
TRANS_Measure_Over();
Trans.Ptr_x = TRANS[VBE];
Trans.Ptr_y = TRANS[IB];
return &Trans;
}
void TRANS_Measure_Over(void)
{
Set_DAC_Data(0, 1);
Set_DAC_Data(0, 2);
Set_DAC_Data(0, 3);
CLOSE_RELAY;
}
//Ib_SP--->期望值; Ib_FA--->实际值; Ib_CV--->控制量
void TRANS_IB_PID(unsigned int Ib_SP, unsigned int Ib_FA,
unsigned char TRANS_Type)
{
Ib_Present_Error = Ib_Current_Error; //比列项,比列系数Kp暂定0.25
Ib_Current_Error = Ib_SP - Ib_FA; //微分项,微分系数Kd暂定0.125
if((ABS_INT(Ib_Current_Error))>5)
{
PID_Flag = 0;
if(TRANS_Type == NPN)
{ //误差为正说明实际值偏小,这时要增加输入量
Ib_CV += Ib_Current_Error>>2; //比列项
Ib_CV += (Ib_Current_Error - Ib_Present_Error)>>3;
Ib_CV_Limit(5, 2500);
} //微分项
else if(TRANS_Type == PNP) //误差为正说明实际值偏小,这时要增加输入量
{ //但对PNP来说,增加Ib则要相应减小Vb给入值
Ib_CV -= Ib_Current_Error>>3; //比列项
Ib_CV -= (Ib_Current_Error - Ib_Present_Error)>>3;
Ib_CV_Limit(650, 2300);
} //微分项
Set_DAC_Data(Ib_CV, 1);
DAC_DELAY;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -