⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcdccontrol.c

📁 对BOOST电路采用pi控制
💻 C
字号:
// 该程序用于进行A/D转换的演示,A/D转换的结果存于数足ADRESULT[16]中,
// 寄存器cesi用于测试每个A/D转换的结果 
#include           "regs240x.h"

                     /* 常量声明 */
    #define Vo_amplify 18.53;         // Vo经过运放的调节倍数
    #define Vo_Constant 28.0;         // 输出恒定值
    #define Vo_error 0.5;             // 输出允许误差值
    #define PWM_period 2000;          // 根据40M时钟设定PWM的输出周期值
    #define Kp 0.001;                 // PI控制的比例参数
    #define Ki 0.001;                   // PI控制的积分参数
                   
                     /* 变量声明 */
    
   float ek_1_overall=0;
   float dk_1_overall=0;
    
    
    int i;
    


                     /* 屏蔽中断子程序 */     
void inline disable() 
{
    asm(" setc INTM");
}

                     /* 开总中断子程序 */
void inline enable()
{
    asm(" clrc INTM"); 
}

                     /* 系统初始化子程序 */
Initial()
{
   
   asm(" setc      SXM");	 // 符号位扩展有效
   asm(" clrc     OVM");	 // 累加器中结果正常溢出
   asm(" clrc      CNF");	 // B0被配置为数据存储空间
   SCSR1=0x81FE;	         // CLKIN=6M,CLKOUT=4*CLKIN=24M
   WDCR=0x0E8;	             // 不使能看门狗,因为SCSR2中的WDOVERRIDE
			                 // 即WD复位后的缺省值为1,故可以用软件禁止看门狗
   IMR=0x0003;	             // 允许INT1,INT2中断
   IFR=0x0FFFF;	             // 清除全部中断标志,"写1清0"
   WSGR=0x00;                // 禁止所有的等待状态
   
   i=0;
   return;
   
}

                     /* 定时器1初始化 */
//1/(40*10(6))*64*(T2PER+1)=5*10(-3)   T2PER=3124
void Timer3init()
{
  
   EVBIMRA=0X0080;           // 允许定时器2的周期中断
   EVBIFRA=EVBIFRA&0X0080;   // 清除定时器2的周期中断标志
   T3CON=0X160C;             // timer2为连续增计数模式预分频值为64,使用内部时钟
   T3PER=0X0ffff; //0X1869//0x0c34             // TIMER2的周期寄存器的值根据5ms(10ms)的定时和预分频值确定
   T3CNT=0X00;               // TIMER2的计数器清零
   
   return;
  
}

                     /* AD初始化子程序 */
void  ADinit()
{
   
   //GPTCONA=0X000;	         // T1,T2无事件启动AD转换,禁止T2周期中断触发AD转换
  
   ADCTRL1=0X10;	         // 采样时间窗口预定标位ACQ PS3-ACQ PS0为0,
		                     // 转换时间预定标位CPS为0,AD为启动/停止模式,排
		                     // 序器为级连工作方式,且禁止特殊的两种工作模式
   ADCTRL2=0X0000;	         // 不可以用EVB的一个事件信号触发AD转换,不用中断模式
  
   MAXCONV=0X07;	// 16通道
   CHSELSEQ1=0X3333;
   CHSELSEQ2=0X3333;
   CHSELSEQ3=0X3333;
   CHSELSEQ4=0X3333;// 转换通道是0-15  */
   
   CALIBRATION=0x0000;        //不启用校正功能
   
   return;
   
}

                       /* PWM初始化子程序 */             
//1/(40(6))*1*(T1PER+1)=1/(20(3))
void  PWMinit()
{
   
    MCRA=MCRA|0X0140;	      // IOPA6/PWM1,IOPB0/PWM3设置为基本功能引脚
	ACTRA=0X0AAA;			  // 设置PWM1,3比较输出方式:高有效
	DBTCONA=0X00;			  // 不使能死区控制
	
	CMPR1=0;
	CMPR2=0;                  // 初始化PWM1,3占空比为0,输出低
	
	T1CON=0X1000;		      // 定时器1为连续增计数模式,预定标系数为X/1(X为CPU时钟频率)
	T1PER=0X07CF;		      // 设置定时器1的周期寄存器,确定PWM频率为20KHZ
	COMCONA=0X8200;		      // 使能比较操作
	
	return;
	
}

                        /* 启动AD转换子程序 */
void  ADsoc()
{
   
    ADCTRL2=ADCTRL2|0X4000;	  // 复位SEQ1,且清除INT FLAG SEQ1标志写"1"清0
    ADCTRL2=ADCTRL2|0x2000;   // 软件触发启动SEQ1   
    
    return; 
    
}

                        /* 采样数据处理程序 */
float  ADprocess()
{
    int i;                   //暂时变量,用于for循环
    int ADRESULT[8];	         // 用于保存AD转换的结果
    int result;            // 存放Vo的暂时结果
    float Vo_AD;              // 存放输入电压
    
    //asm(" clrc      SXM");	  // 抑制符号位扩展
   //Vo_temp=0;
  
   ADRESULT[0]=RESULT0>>6;       // 将AD转换结果右移6位
   ADRESULT[0]=ADRESULT[0]&0x03ff;  // 去掉后2位(由外界干扰引起的测量不准
  // Vo_temp+=ADRESULT;
   ADRESULT[1]=RESULT1>>6;
   ADRESULT[1]=ADRESULT[1]&0x03ff;
  // Vo_temp+=ADRESULT;
   ADRESULT[2]=RESULT2>>6;
   ADRESULT[2]=ADRESULT[2]&0x03fc;
  // Vo_temp+=ADRESULT;
   ADRESULT[3]=RESULT3>>6;
   ADRESULT[3]=ADRESULT[3]&0x03fc;
   //Vo+=ADRESULT;
   ADRESULT[4]=RESULT4>>6;
   ADRESULT[4]=ADRESULT[4]&0x03fc;
   //Vo+=ADRESULT;
   ADRESULT[5]=RESULT5>>6;
   ADRESULT[5]=ADRESULT[5]&0x03fc;
   //Vo+=ADRESULT;
   ADRESULT[6]=RESULT6>>6;
   ADRESULT[6]=ADRESULT[6]&0x03fc;
   //Vo+=ADRESULT;
   ADRESULT[7]=RESULT7>>6;
   ADRESULT[7]=ADRESULT[7]&0x03fc;
   result=ADRESULT[0]+ADRESULT[1];
   
   for(i=2;i<8;i++)
   {
      result=result+ADRESULT[i];
    }  
    
   //Vo+=ADRESULT;
   result=result/8;                   // 取8个AD转换结果的平均值
   Vo_AD=result*3.3/1023;            // 计算Vo模拟量
   Vo_AD=Vo_AD * Vo_amplify;            // 计算Vo真实值
   
  // asm(" setc      SXM");	 // 符号位扩展有效
   return Vo_AD;
   
} 

                             /* 输出恒定控制字程序 */
void BoostControl(float Vo_BC)
{
   
    float ek;                // 存放当前误差
    float ek_1;              // 存放上次误差
    float dk;                // 存放当前PI控制输出量
    float dk_1;              // 存放上一次PI控制输出量
    float delta_dk;            // delta_dk=dk-dk_1
    
   //float Vo=0;              // 存放输入电压
   float Vh,Vl,temp1,temp2;
   int CMPR1_TEMP;
   Vh=Vo_Constant;
   Vh=Vh+Vo_error;
   Vl=Vo_Constant;
   Vl=Vl-Vo_error;
   ek_1=ek_1_overall*10;
   dk_1=dk_1_overall*10;
   if(Vo_BC>Vh || Vo_BC<Vl)
   {
       ek=Vo_Constant;
       ek=ek-Vo_BC;          // 计算当前误差
       delta_dk=Ki
       delta_dk+=Kp; 
       delta_dk=delta_dk*ek;
       temp1=Kp;
       temp1=temp1*ek_1;
       delta_dk=delta_dk-temp1;
       dk=dk_1+delta_dk;           // 计算当前占空比dk
       if(dk>0.1428)                  // 限幅,占空比最大为14.29%
       {
          dk=0.1428;
       }
       if(dk<0)
       {
          dk=0;
       }
       temp2=PWM_period;
       temp2=temp2*dk;
       CMPR1_TEMP=temp2;          // 通过得到的dk设置比较寄存器
       CMPR1=CMPR1_TEMP;
       ek_1_overall=ek/10;                    // 计算完成,则当前误差作为下次计算的上一次误差
       dk_1_overall=dk/10;                    // 当前控制量作为下次计算的上一次控制量
   }
   return;
}   

                       /* 若是其它中断则直接返回子程序 */
void interrupt nothing()
{
   return;
}

                       /* 定时器2周期中断服务程序 */
void interrupt t3int()
{
   
   int flag;                    // 定义一个局部变量
   float Vo;
   
   i=i+1; // 察看中断次数
   
   flag=EVBIFRA&0X0080;
   if(flag!=0x0080)
   {
       enable();                // 允许总中断
       return;                  // 如果不是定时器2总中断,则直接返回
    }
// 如果是定时器2的周期中断,则执行下面的程序
    ADsoc();                    // 启动AD转换
    flag=AUTO_SEQ_SR&0X0F00;
    while(flag>0){flag=AUTO_SEQ_SR&0X0F00;}            // 等待AD转换结束
    Vo=ADprocess();                // 对采样数据处理
    BoostControl(Vo);            // 对Boost电路进行PI控制,使输出维持在28V
    
    T3CNT=0X00;                 // 定时器2的计数器重新赋0
    EVBIFRA=EVBIFRA&0X0080;     // 清除定时器2周期中断标志,否则以后的中断将被忽略
    enable();                   // 允许总中断,因一旦进入中断服务程序后总中断就自动关闭
    return;
    
}

                        /* 主函数 */
main()
{
  // float a=0.00001;
   disable( );	               // 禁止总中断
   Initial( );	               // 系统初始化
  /* ek_1=a;
   dk_1=a;
   dk_1=1.6/4;
   a=dk_1;
   a=a*4.0;
   ek_1=0;
   dk_1=0;*/
   Timer3init();               // 定时器2初始化
   ADinit( );	               // AD初始化子程序
   PWMinit();                  // PWM输出初始化
	
   T1CON=T1CON|0x0040;		   // 启动定时器1,启动PWM输出
   
   enable( ); 	               // 开总中断
   T3CON=T3CON|0x0040;		   // 启动定时器2
   T3CON=T3CON|0x0040;	
   
   while(1)
   {
       ;
   }	                       // 等待中断
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -