论坛风格切换切换到宽版
  • 3730阅读
  • 2回复

pi算法遇到的疑问 [复制链接]

上一主题 下一主题
离线XLDZZ
 
发帖
443
只看楼主 倒序阅读 0楼 发表于: 2011-03-03
程序如下:
ad_val();是ad数据采集程序,程序没有问题。我用它来做过数字电压表10bit精度
比我的victor表精度还高。

思路是这样的,ad采集电压数据,然后用我事先给定的数据相减得到一个带符号数val_t(此数为int型),在对此值求积分。得到积分后的数据val_p.

然后用此值来给16位定时器赋值
speed_l=speed&0xff;   //取低8位数据
speed_h=speed&0xff00>>8;//取高8位数据
发现我把ad口接地,后脉冲频率恒定。但是与逻辑相反。因为接地后ad返回数据
为零那么执行
if(val_p>=0)//给定大于反馈,电压低
           {  
        speed=speed+val_p;//主轴加速
那么速度应该是初始设定值,但是现在看来是执行了
if(val_p<0)//给定小于反馈,电压高
         {
        val_p=val_p*-1;//数据变换,求绝对值
        speed=speed-val_p;//主轴减速
        if(speed<=1000)//限制低速速度 频率9.68hz 进给量1.16mm/min
          {
            speed=0;
          }
因为 示波器上看就是10hz左右,没想通为什么。
ad口直接接电源,照理因该执行
if(val_p>=0)//给定大于反馈,电压低
           {  
        speed=speed+val_p;//主轴加速
        if(speed>=64285)//限制高速速度 频率500hz 进给量60mm/min
          {
          speed=64285;
          }
           }
速度会限制在500hz 但是频率在无规律变化。时快时慢。
还请高手指点







int pi()//pi求解函数
           {
      for(p_cunt=0;p_cunt<=ki;p_cunt++)   //此处决定积分时间 积分时间由宏定义完成
        {
        for(i_cunt=0;i_cunt<=19;i_cunt++)//数据放大20倍,total放大200倍
          {
          val_temp=ad_val();
          val_t=val_t+val_temp;
          }        
          val_tp=val_g-val_t;//计算偏差,单次偏差
          val_p=val_p+val_tp;//求积分,ki次偏差数据和
        }
       
      if(val_p>=0)//给定大于反馈,电压低
           {  
        speed=speed+val_p;//主轴加速
        if(speed>=64285)//限制高速速度 频率500hz 进给量60mm/min
          {
          speed=64285;
          }
           }
      if(val_p<0)//给定小于反馈,电压高
         {
        val_p=val_p*-1;//数据变换,求绝对值
        speed=speed-val_p;//主轴减速
        if(speed<=1000)//限制低速速度 频率9.68hz 进给量1.16mm/min
          {
            speed=0;
          }
           }//end if(val_p<0)  
              speed_l=speed&0xff;   //取低8位数据
      speed_h=speed&0xff00>>8;//取高8位数据
      }//end pi
离线XLDZZ
发帖
443
只看该作者 1楼 发表于: 2011-03-04
问题找到了 程序是执行了
if(val_p>=0)//给定大于反馈,电压低
    {  
      speed=speed+val_p;/
    if(speed>=64285)//限制高速速度 频率500hz 进给量60mm/min
      {
        speed=64285;
      }
    }
也执行了第二个if

问题是在,以下两条语句。本意是把32位数(第二个if把值限定在64285)
装入两个无符号int型16位数。等到定时器1中断时,清完中断标记就把
这两个16位赋值给两个定时器寄存器tmr1h,tmr1l。现在的现象好像
是数据丢失。也就是tmr1l,tmr1h.的值不是speed_,speed_h的值
而是个非常小的值。

第二 中断时调用的变量需要保护吗?是否由于没有现场保护才出现
数据丢失的现象

speed_l=speed&0xff;   //取低8位数据
speed_h=speed&0xff00>>8;//取高8位数据
在线BG4UVR
发帖
11207
只看该作者 2楼 发表于: 2011-03-05
恢发变量用 volatile 声明