关键词不能为空

当前您在: 主页 > 英语 >

数字锁相环 逆变器 程序

作者:高考题库网
来源:https://www.bjmy2z.cn/gaokao
2020-10-31 10:16
tags:5655

好听的英文歌曲名字-民王

2020年10月31日发(作者:干志坚)


DSPIC30F2010
单相逆变



数字锁相环

程序




#include 中断优先级还没设置,先 t2,t1,spwm,其他
#include
#include
#include
#define _T1ON
#define _T2ON
_FOSC(CSW_FSCM_OFF & XT_PLL8);
_FWDT(WDT_OFF);
_FBORPOR( RST_PWMPIN& PWMxH_ACT_HI& PWMxL_ACT_HI&PBOR_OFF &
MCLR_EN);
_FGS(CODE_PROT_OFF);


void IC2_INI(void);
void T2_INI(void);
void PWM_INI(void);
void AD_INI(void);
void T1_INI(void);

void PWM_CAL(unsigned int ,unsigned int k,unsigned int a );
void IOUT_PROTECT(void);
void US_PROTECT(void);
void PROTECT_RE(void);
void PID_CAL(void);
void smooth_test(unsigned int ,unsigned int );
void smooth_3_test(unsigned int a,unsigned int b,unsigned int c);

unsigned int IC2_0,IC2_1; 捕捉周期用,前后相减
unsigned long CAP_T,CAP_T_0; 捕捉得到的周期,不过有分频,记得<<3
unsigned int CAP_N,PWM_N,AD_N,T1_N;
unsigned int AD0,AD1; ADCBUF的结果读到这里来,采样满64次后,转存并清
空,记得清空
unsigned int UD,US,AD_N_200,AD_N_50; AD转存的数据,供外部计算用,64次计数到

unsigned int AD2,AD3,IOUT,UO; 正弦波采样采用均方根的方法要用32位变量来存,ad结
果和转存数
unsigned int Kp,Ki,Ud0,Ud1,Us0,Us1; pid环节数,和2次处理的采样电压数据
unsigned int UD_10,US_10,IOUT_10,UO_10; 采样结果,转换为10位的有效值,
unsigned int RE_DELAY; 保护后延迟计数,计数1时,等于一个周波50个约


1s
unsigned char PROTECT_FLAG; 保护标志位


unsigned int io_10_0,io_10_1,io_10_2,io_10_max_temp,io_10_m ax,smooth_fail_n; 电流采样
的全局变量


const unsigned int d1[100]= 0~90度份100份的正弦
{515 ,1544 ,2573 ,3601 ,4629 ,5655 ,6680 ,7703 ,8724 ,9743
,
10760 ,11774 ,12785 ,13793 ,14798 ,15799 ,16796 ,17789 ,18778 ,19762
,
20741 ,21715 ,22683 ,23646 ,24603 ,25554 ,26499 ,27437 ,28369 ,29293
,
30210 ,31120 ,32022 ,32916 ,33803 ,34680 ,35549 ,36410 ,37261 ,38103
,
38936 ,39760 ,40573 ,41376 ,42170 ,42952 ,43724 ,44486 ,45236 ,45976
,
46703 ,47420 ,48125 ,48817 ,49498 ,50167 ,50823 ,51467 ,52097 ,52716
,
53321 ,53913 ,54491 ,55056 ,55608 ,56146 ,56670 ,57180 ,57676 ,58158
,
58625 ,59078 ,59516 ,59940 ,60349 ,60742 ,61121 ,61485 ,61834 ,62167
,
62486 ,62788 ,63075 ,63347 ,63603 ,63843 ,64068 ,64277 ,64470 ,64647
,
64808 ,64953 ,65082 ,65195 ,65292 ,65372 ,65437 ,65485 ,65518 ,65534
,
};
unsigned int PWM_N,k,a; n=当前在的段的位置,k映射到0~99的查表位置,a变比后
期主要控制这个

unsigned long temp;
********************* ****************************
主程序
********* *****************************************
int main(void)
{
LCD_Init();
LCD_WRITE_8BIT(LINE1,CMD);
DISP_10(78);
PWM_INI();
AD_INI();


T1_INI();
T2_INI();
_T2ON=1;

IC2_INI();
_IC2IE=1;
_T1ON=1;
_T1IE=1;
_ADON=1;
_ADIF=0;
_ADIE=1;
a=32768;
while(_IC2IF==0)
_PTEN=1;
_PWMIE=1;
_PWMIP=7;

Ki=60;
Kp=7;
IOUT_10=1;
while(1)
{
LCD_WRITE_8BIT(LINE1,CMD);
DISP_10(IOUT_10);
DISP_10(UD_10);
nop;
delay1ms(200);

}

}


*************************************
捕捉初始化程序,IC1 IC2
**************************************
void IC2_INI(void)
{ _TRISD1=1;
IC2CON
=0; 空闲运行
=1; 1=采样tmr2,0=采样tmr3
=0B00; 每1次捕捉中断
只读,溢出
只读,缓冲器非空
过零点时启动pwm


=0B011; 每一个上升沿捕捉一次
000=关闭捕捉
_IC2IF=0;
_IC2IE=0;

}

*******************************************
T2初始化,为ic2提供时基
*******************************************

void T2_INI(void)
{
=0; 设置前关闭
=0; 空闲运行
=0; 门控计数禁止
=0B01; 1:8
T2CONbits.T32=0; 禁止32位计数
=0; 内部时钟源

TMR2=0; 初始化计数值
PR2=49999; 周期满,就是不周期
=0; 定时器工作
_T2IF=0;
_T2IE=0;
}

******************************************
IC2捕捉中断程序,锁频锁相用;入口参数IC2BUF,出口参数PTPER,PWM_N
*******************************************
void __attribute__ ((interrupt)) _IC2Interrupt(void)
{
_IC2IF=0;

PWM_N=200; 实现锁相
IC2_0=IC2_1;
IC2_1=IC2BUF;
CAP_T_0=CAP_T;
if(IC2_0 else CAP_T=(long)IC2_1+100000-IC2_0;
if(CAP_TCAP_T_0-64) return;
PTPER=(CAP_T<<3)400-1; 重新设置pwm周期,实现锁频
PWM_N=200; 实现锁相
PR1=(CAP_T<<3)200-1; 定时器1 ,1:1分频,一个周期分为64份,为ad提供出发时



这里把PR1的结果多减去几个,这样一个周期完成,使得定时器的
时间多点,
要是少了就麻烦,采样次数会少一个,这样对电流采样是要守相位
的很不利,
于是 把它减小几个,这样在pwm_n=0是,定时器会多点时间,把
时间清掉,就可以保证相位了。必须保 证最大值在相位区间内
结果在pwm中断中开始相位补偿,这里就不补了,要不然这个数
不好确定
CAP_N++;
if(CAP_N==64)CAP_N=0;
return;
}

**********************************************
void __attribute__ ((interrupt)) _PWMInterrupt(void)
**********************************************
{
_PWMIF=0; _PWMIF=0;
* if(PWM_N==0) 把t1 的ad时间清理,保住采样相位,对才
交流有效,这里进行相位补偿,多减少加
{ 无论这里pwm_N=多少,都没关系,只要一
个周期进行一次时间补偿就行了。
if(TMR1<(PR1>>1)) TMR1=0;
else TMR1=PR1-10;

}
*
if(PWM_N<100)
{
k=PWM_N;
PWM_CAL(PWM_N,k,a);
}
else if(PWM_N<200)
{
k=200-PWM_N-1;
PWM_CAL(PWM_N,k,a);
}
else if(PWM_N<300)
{
k=PWM_N-200;负数的
PWM_CAL(PWM_N,k,a);
}
else if(PWM_N<400)


{
k=400-PWM_N-1;
PWM_CAL(PWM_N,k,a);
}
PWM_N++;
if(PWM_N==400)PWM_N=0;
_PWMIF=0;
}
***************************** ************************
void PWM_CAL(unsigned int n,unsigned int k,unsigned int a ) 占空比计算,调用=
PWM_CAL(n,k,a);
************ *****************************************
{
unsigned int _sin,tempd; a=变比,_sin=查表得正弦值,tempd=a*_sin>>17;
unsigned long a_sin,temppdc; a_sin=a*_sin,temppdc=PTPER*tempd;
_sin=d1[k];
PDC1=PTPER*(1+-a*_sin) ***<<32
a、_sin 小于1,都扩大2^16倍,
a_sin=a;
a_sin=a_sin*_sin; 计算结果为32位
a_sin=a_sin>>17;移动后是15位 ***>>17
tempd=a_sin; 结果存起来
if( n<200)tempd=32768+tempd; 加1,结果为16位;1被扩大了2^15倍,两个15位数相加
为16位;
else tempd=32768-tempd;
temppdc=(PTPER+1); _16*_16为_32
temppdc=temppdc*tempd;
temppdc=temppdc>>15; 结果>>16得到16位要的结果 ***>>15 (**扩大和缩小移位刚
好全抵消**)。
PDC1=temppdc-1; 结果赋给寄存器
}
tmd的,两个(a、b)16位相乘 结果还是16位,应该这样,
一个(c)32位,先把16位数赋给32位,然后32位乘16位,
结果为32位,不管内部怎么乘的,这个结果没有益处,就会正确。


* ************************************************** **
void PWM_INI(void)
******************** *********************************
{
IO

_TRISE0=0;
_TRISE1=0;


_RE0=0;
_RE1=0;
PTCON=0;
_PTEN=0; 后面来使能
_PTSIDL=0; 空闲运行
_PTOPS=0B000; 后分频1:1
_PTCKPS=0B00; 输入时钟分频1:1
_PTMOD=0B00; 自由模式

PTMR=0;
_PTDIR=0; 向上计数
PTMR=0; 从0开始计数,以后开始时要设置


PTPER=1199; pwm周期

PWMCON1=0X00FF;
_PMOD1=0; pwm1互补模式输出
_PMOD2=0;
_PMOD3=0;


_PEN1L=1; 使能pwm1H、L的输出
_PEN1H=1;
_PEN2L=0;
_PEN2H=0;
_PEN3L=0;
_PEN3H=0;

PWMCON2=0;
_SEVOPS=0B0000; 特殊事件分频
_IUE=0;此为无 0=对PDC的更新与pwm时基同步,1=立即更新,对于
spwm要注意
与OVDCON有关
_OSYNC=1; 输改写与pwm基时同步
_UDIS=0; 使能占空比和周期寄存器更新

DTCON1=0;
_DTAPS=0B00; 死区分频1:1
_DTA=6; 死区时间8*40um
DTCON2在这个芯片中没有

FLTACON=0; 故障A、B输入引脚,这里禁止
SEVTCMP=0; 特殊事件比较,不管



OVDCON=0XFF00; 默认这个值,高位为1,输出pwm
INT
_PWMIF=0;
_PWMIE=0;
_PTEN=0;
}
******************************* ***********************************
ADC初始化,四通道,同时采样,顺序转换,触发信号,由T1给,其他自动工作
**** ************************************************** **************
void AD_INI(void)
{
_TRISB0=1;
_TRISB3=1;
_TRISB4=1;
_TRISB5=1;
adcon1
_ADON=0;
_ADSIDL=0;
_FORM=0;
_SSRC=0B111; 自动采样,结束采样位,开始转换
_SIMSAM=1;
_ASAM=0; 自动采样
_SAMP=0; 开始采样
_DONE
ADCON2
_VCFG=0B000;
_CSCNA=0;
=0B10;
_BUFS
_SMPI=0; 中断次数
_BUFM=0;
_ALTS=0;
ADCON3
_SAMC=1;
_ADRC=0;
_ADCS=7;
ADCHS
_CH0NA=0; NA=负
_CH123NA=0;
_CH0SA=0; SA=正
_CH123SA=1; 0=012;1=345
ADPCFG
ADPCFG=0B00000;


ADSSL 扫描输入引脚
}

void AD_INI0(void)

{

配置ad模块
_TRISB0=1; 1.21配置io
_TRISB3=1;
_TRISB4=1;
_TRISB5=1;
1.22配置参考电压

2 ad的中断设置
_ADIF=0;
_ADIE=0; (**这里注意下**)
3 启动ad 开始采样
_ADON=0; (**这里注意下**)


ADCON1
_FORM=0B00; 采样整数
_SSRC=0B111; 000=手动触发采样;111=自动转换
_SIMSAM=1; CHPS中各路同时采样(与顺序采样相反)
_ASAM=0; 手动控制采样位
_SAMP= 采样使能位,控制用,这里不设置
_DONE
ADCON2
_VCFG=0B000;采样电平为vccvdd 。
_CSCNA=0; CH0+ 不扫描输入,如果扫描输入就只能 用ch0,
置0
_CHPS=0B10; 选择通道使用位 0 1 2 3
_BUFS BUFM=1时有效,这里无视
_SMPI=0; 完成4次转换采样产生中断
_BUFM=0; 使用字格式BUF
_ALTS=0; 使用mux a
ADCON3
_SAMC=1; 自动采样时间位1Tad
_ADRC=0; 时钟源由系统产生
_ADCS=7; 对应与24mpis,这个最小的就是这个,
2*154*241000-1=6.6 取_ADCS=7


会忽略CH123.这要


ADCHS
_CH0SA=0; ch0 采样an0
_CH123SA=1; 0=ch123采样an012,1=345
_CH0NA=0; ch0负通道选vref-
_CH123NA=0; ch123负通道vref-
* _CH0SB=0;
_CH123SB=0;
_CH0NB=0;
_CH123NB=0;
* mux b 的通道不用管他 没用到
ADPCFG 数字模拟选择位
ADPCFG=0XFF00; 1数字 0 模拟,低4个位数字模拟
_PCFG0~_PCFG3=0, 其他=1
ADCSSL 扫描选择位 CH0的扫描,因为用了 四路采样,这个启动只能用一路ch0,所以
应关掉。
ADCSSL=0; 扫描低四位
_CSSL0~_CSSL3=1, 其他=0



}

****************************** **************************
T1初始化,为ad提供时间
* ************************************************** ****
void T1_INI(void)
{
T1CON=(T1_OFF & T1_IDLE_CON & T1_GATE_OFF & T1_PS_1_1 &
T1_SYNC_EXT_OFF & T1_SOURCE_INT);

=0;
=0;
=0;
=0B00; 1:1分频
=0;
=0; 内部时钟
TMR1=0;
PR1=2400; 周期时间在 捕捉时已经给定了。
=1; 中断开始
_T1IF=0; 中断标志位 允许位
_T1IE=0;
}

******** ***********************************************


T1中断,中断时 启动 ad采样,然后退出,接着就等待ad的中断
** ************************************************** **
void __attribute__ ((interrupt)) _T1Interrupt (void) 函数名前面是一个不是2个
{
IFS0bits.T1IF=0;
T1_N++;
if(T1_N==200)T1_N=0;
_SAMP=1;

}

********************************************** *********
ADC中断,把所有采样值累加起来,最后求平均,这样会容易点,效果如何,知 道了再告
诉你、
********************************** ********************
void __attribute__ ((interrupt)) _ADCInterrupt (void)
{
_ADIF=0;
AD_N++;

AD0=AD0+ADCBUF0; ud
AD2=AD2+ADCBUF2; us
AD1=ADCBUF1; io
AD3=ADCBUF3; uo
电流
if(PWM_N==10 || PWM_N==11 || PWM_N==12)
{
smooth_fail_n=0;
io_10_max_temp=0;
io_10_max=0; 如果要与前一次最大值比较,这里要先存变量值
}

io_10_0=io_10_1;
io_10_1=io_10_2; 电流
采样的数据进行处理,并执行过流保护
io_10_2=AD1;
if(80 smooth_test(io_10_1,io_10_2);
smooth_3_test(io_10_0,io_10_1,io_10_2);
if(AD_N==60 && smooth_fail_n==0 && PROTECT_FLAG==0)
if((PWM_N==120 || PWM_N==121 || PWM_N==123) && PROTECT_FLAG==0)
因为一个ad对应2个pwm,这里不用多个就会少掉哦。

{


io_10_max=io_10_max_temp;
IOUT_10=io_10_max;
IOUT_PROTECT();
}


电流清零与一周期事件处理

if(AD_N==200)
{
AD_N=0;
AD_N_200=1;
IOUT=AD1;
UO=AD3;
AD1=0;
AD3=0; 忘记清零是不对的哦
}

if(AD_N_200==1)
{
AD_N_200=0;
if(RE_DELAY!=0)RE_DELAY--;
}
电压 处理
if(AD_N==0 || AD_N==50 || AD_N==100 || AD_N==150)
{
AD_N_50=1;
UD=AD0; 这里视具体链接设置
US=AD2; 这四个是采样累计变量
AD0=0;
AD2=0;
}
电压处理 pi 欠压保护

if(AD_N_50==1)
{
AD_N_50=0;
UD_10=UD50;
US_10=US50;
PID_CAL();
US_PROTECT();
}

if(_PTEN==0)PROTECT_RE();




}


*******************************************
平滑度检测,无干扰测试,但愿成功
*****************************************
平滑度测试,如果成功则采到最大值



void smooth_test(unsigned int a,unsigned int b)
{
unsigned int c,max_temp;
if(a>b)
{
c=a-b;
max_temp=a;
}
else
{
c=b-a;
max_temp=b;
}

if(c<45) 最小是8,最大60就可以了,
太大可能会无法排除干扰,太小会误以为有干扰
{
if(max_temp>io_10_max_temp)
io_10_max_temp=max_temp;
}
else smooth_fail_n++;
}


****************************
也是平滑度测试 3个点连续则认为是无干扰了,采回最大值,
***************************
void smooth_3_test(unsigned int a,unsigned int b,unsigned int c)
{

if(a-45 {


if(a>b)io_10_max_temp=a;
else io_10_max_temp=b;
if(io_10_max_temp }
}



********************************************
过流保护
*******************************************
void IOUT_PROTECT(void)
{
if(PROTECT_FLAG==1)return;
保护时电流检测为0,所以再重新启动后才能再次进行检测保护
if(IOUT_10>=735)
只有第一次欠压时才成立,
{
_PTEN=0; ?=1.5*0.1*10*(10235)=307
PROTECT_FLAG=1;
RE_DELAY=100;
IOUT_10=1;
}
}

*********************************************
欠压保护,us<50v
****************************** *****************
void US_PROTECT(void)
{
if(PROTECT_FLAG==1)return;
护状态直接返回就行了,在保护恢复时再次检测就行了
if(US_10<=654)
欠压时一直成立
{
_PTEN=0; ?=50128.2*8.2*(10235)=654
PROTECT_FLAG=1;
RE_DELAY=100;
}
}

*******************************************
保护恢复,判断
*****************************************


再保










void PROTECT_RE(void)
{

if(RE_DELAY==0)
RE_DELAY再AD采样中的ADC_N_64进行--操作,这样一个数值表示一个周期
{
IOUT_10=1; ******保护后电流不会采样,这个最大值被一直保持了,要及
时清零否则无法恢复保护

if(US_10>674) 原先
if(US_10>654 && IOUT_10<307) ,由于保护后电流为零,这里加上电流的约束
条件无意义
{
while(_IC2IF==0) *********没有捕捉功能时
***********
_PTEN=1;
PROTECT_FLAG=0;
因为这个没清零,结果只能保护一次
} 捕捉到过零点时启动pwm这样可以提高准确度,减小畸变等
原因的结果处理干扰,多一重保护
else RE_DELAY=50; 保护
恢复失败再次延时2s,对欠压保护有效,过流要再次开通后才知道是否需要保护。

}
}
**********************************
PID计算环节
**********************************
void PID_CAL(void)
{
unsigned long pi1,pi2,pi3;


Us0=Us1;0X1F0;
Ud0=Ud1;0x20F;
if(Us1>US_10+1 || Us1 Us1=US_10;0X200; 这两个数据还要处理。
if(Ud1>UD_10+1 || Ud1 Ud1=UD_10+5;0x20F; 这里补偿,实际ud偏高,因为采样结果偏小,调得偏高
了,所以这里加点上去,
可以这样说吧,实际是30.3,但采样才30.0(因为稳在30.0幅度)所以
补偿点。

pi1=(long)a+(((long)Kp*Us1)>>1)+((long)Kp+Ki)* Ud0; 这里>>n位,Ki,Kp可以扩大2^n


被,来提高精度,最大n=10
pi2=(long)Kp*Ud1+((((long)Kp+Ki)*Us0)>>1);
精度要求1%,则每次改变0.1%,或者更小。
if(pi1>pi2)
{
pi3=pi1-pi2;
if(pi3>65535)
a=65535;
else a=pi3;
}
else a=0;
限制幅值就是限制a的化量。
}

名师在线课堂-beef


itsucks-公倍数是什么


安澜的意思-胸有丘壑


smock-judging


it怎么读-频率是什么意思


艾米视频电脑版-presided


飞行员英文-墨绖


哮怎么读-吉芬商品



本文更新与2020-10-31 10:16,由作者提供,不代表本网站立场,转载请注明出处:https://www.bjmy2z.cn/gaokao/434880.html

数字锁相环 逆变器 程序的相关文章

  • 爱心与尊严的高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊严高中作文题库

    1.关于爱心和尊严的作文八百字 我们不必怀疑富翁的捐助,毕竟普施爱心,善莫大焉,它是一 种美;我们也不必指责苛求受捐者的冷漠的拒绝,因为人总是有尊 严的,这也是一种美。

    小学作文
  • 爱心与尊重的作文题库

    1.作文关爱与尊重议论文 如果说没有爱就没有教育的话,那么离开了尊重同样也谈不上教育。 因为每一位孩子都渴望得到他人的尊重,尤其是教师的尊重。可是在现实生活中,不时会有

    小学作文
  • 爱心责任100字作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任心的作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文
  • 爱心责任作文题库

    1.有关爱心,坚持,责任的作文题库各三个 一则150字左右 (要事例) “胜不骄,败不馁”这句话我常听外婆说起。 这句名言的意思是说胜利了抄不骄傲,失败了不气馁。我真正体会到它

    小学作文