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

📄 ctr_backup.lst

📁 磁流变阻尼器控制器的源程序
💻 LST
字号:
C51 COMPILER V7.50   CTR_BACKUP                                                            03/27/2008 14:22:15 PAGE 1   


C51 COMPILER V7.50, COMPILATION OF MODULE CTR_BACKUP
OBJECT MODULE PLACED IN ctr_backup.OBJ
COMPILER INVOKED BY: I:\Keil\C51\BIN\C51.EXE ctr_backup.c BROWSE DEBUG OBJECTEXTEND

line level    source

   1          //加定时器已完成 现在的采样频率为32Hz
   2          //主体部分已经完成,Ka已经计算正确,给P2端口赋值能正确显示,但通过Ka给P2传递
   3          //增益时,P2输出亦正确,调整PI算法已调整,振级表是使用自己编写的一个,P0输出
   4          //正确了(实施办法是将P0赋值位置提前就解决了)
   5          #include<stdio.h>
   6          #include<aduc842.h>
   7          #include<math.h>
   8          
   9          #define KP 0.5//暂定Kp=5
  10          #define KI 0.5//暂定Ki=5
  11          
  12          sfr templ=0x86;
  13          sfr temph=0x85;
  14          
  15          void DELAY(int length);
  16          void adc_chan(int chan);// 选择通道
  17          void adc_ini();
  18          void adc_start();
  19          void config();
  20          void uart_ini();
  21          void dac_ini();
  22          void port_ini();
  23          //void TIC_ini();
  24          //void TIC_start();
  25          void readval();//读取AD转换值并转为10进制数子函数
  26          void pi();//PI算法子程序
  27          float Lookuptab(unsigned char voltab);//查表子程序
  28          
  29          int             K;
  30          int   Kout=0;//将K值进行翻转准备输出到P2口
  31          int   xdata num[8];//用作暂时存储K值以便今后进行翻转方便
  32          int   xdata i;
  33          int   Ka;
  34          int   tempval;
  35          float code Table[6]={1.0,2.0,3.0,4.0,5.0,6.0};//自己暂定的振级表,可以根据实际值修改
  36          float UDA;//UDA为DAC0输出
  37          float UIK=0;//UI的初值设为0 
  38          float xdata MK1;//该值为上一次采样保存的电压值
  39          float xdata MK2;//该值为新采样保存的电压值
  40          float RK;
  41          float EK;
  42          float UPK;
  43          float UK;
  44          int xdata level1;
  45          int xdata level2;
  46          
  47          
  48          void adc_int() interrupt 6  //ADC转换完,进入中断
  49          {
  50   1              I2CCON=0x0C8;//灯灭
  51   1              DELAY(2000);
  52   1              I2CCON=0x048;//灯亮  
  53   1              temph=ADCDATAH;
  54   1              templ=ADCDATAL;//转换值暂存到temp中
  55   1              ADCI = 0;//可要可不要,如果不进入ADC中断,则须用户手动清零
C51 COMPILER V7.50   CTR_BACKUP                                                            03/27/2008 14:22:15 PAGE 2   

  56   1              return;
  57   1      }
  58          
  59          
  60          /*void TIC_int () interrupt 10
  61          {
  62                  TIMECON=0x00;
  63              I2CCON=0x048;
  64                  DELAY(2000);
  65                  printf("TIC finished\n");//去掉warning请注释此句
  66                  IEIP2 = 0x00;//关TIC中断
  67          }
  68          */
  69          
  70          
  71          void adc_chan(int chan)
  72          {
  73   1      ADCCON2 = chan;
  74   1      }
  75          
  76          
  77          
  78          void adc_ini()
  79          {
  80   1      ADCCON1 = 0x02C;            // 暂停AD
  81   1      EA          = 0;                                // 中断不使能
  82   1      EADC    = 0;                            // ADC中断不使能
  83   1      
  84   1      }
  85          
  86          void adc_start()
  87          {
  88   1      ADCCON1 = 0x0AC;            // 启动AD,使用内部参考电压
  89   1      EA          = 1;                                // 中断使能
  90   1      EADC    = 1;                            // ADC中断使能
  91   1      }
  92          
  93          void config()
  94          {
  95   1      CFG842 = 0x41;      //暂定
  96   1      PLLCON = 0x03;          //工作频率=2.097152 MHz
  97   1      
  98   1      
  99   1      }
 100          
 101          void uart_ini()         //串口初始化
 102          {
 103   1      T3CON = 0x083;
 104   1      T3FD  = 0x02D;
 105   1      SCON  = 0x052;
 106   1      }
 107          
 108          void dac_ini()
 109          {
 110   1      DACCON = 0x0D;//DAC0 12位异步 0-Cref=5v
 111   1      //DACCON = 0x2D;//DAC0 12位异步 0-Vdd
 112   1      }
 113          
 114          void port_ini()//根据需要设置AD7520增益值
 115          {
 116   1      P0&=0x00;//
 117   1      P2|=0x00;
C51 COMPILER V7.50   CTR_BACKUP                                                            03/27/2008 14:22:15 PAGE 3   

 118   1      //P2|=0x64;//0110,0100
 119   1      //P2|=0xC4;//1110,0101
 120   1      }
 121          
 122          /*void TIC_ini()                //定时器初始化
 123          {
 124          TIMECON = 0x00;
 125          INTVAL = 0x00;
 126          HTHSEC=0x00;
 127          }
 128          
 129          void TIC_start()                //定时器开始计时,中断间隔为4*(1/128)=31.25ms,注意要在TCEN为低的时候给
 130          {                                               //INTVAL和HTHSEC赋值,再开TIC中断,全局中断,最后置TCEN开始计时
 131          TIMECON = 0x0A;//0000,1010
 132          INTVAL = 0x04;
 133          HTHSEC=0x00;
 134          IEIP2 = 0xA4;//TIC中断使能
 135          EA = 1;
 136          TIMECON|=0x01;//启动TIC 
 137          } 
 138          */
 139          
 140          void readval()
 141          {
 142   1      tempval=(int)temph*256;//强制转换为整形数
 143   1      tempval+=(int)templ;//此时计算的是十进制的AD结果,比如若temph:templ=03ff,则对应于1023
 144   1      
 145   1      }
 146          
 147          float Lookuptab(unsigned char voltab)
 148           {
 149   1       return Table[voltab];
 150   1       }
 151          
 152          void pi()
 153          {
 154   1              
 155   1              
 156   1              //UDA=5;//UDA为方便计算设置的一个变量
 157   1              //UK=UDA;//调试时先可直接把Uk=5v来计算,等到完成后在应用下面的PI算法
 158   1              DELAY(500);
 159   1               if(level2 == 0)  {RK=Lookuptab(0);}
 160   1      else if(level2 == 1)  {RK=Lookuptab(1);}
 161   1      else if(level2 == 2)  {RK=Lookuptab(2);}
 162   1      else if(level2 == 3)  {RK=Lookuptab(3);}
 163   1      else if(level2 == 4)  {RK=Lookuptab(4);}
 164   1           else            {RK=Lookuptab(5);}//这段程序目的是查表确定振动的给定参考值以便与采集来的数据比较
 165   1              
 166   1              EK=RK-MK2;
 167   1              UPK=KP*EK;
 168   1              UIK=KI*EK+UIK;
 169   1              UK=UPK+UIK;
 170   1              K=(UK/UDA*1024);//现将()内表达式的值取整,此值处理后即为送往AD7520的增益值,
 171   1      
 172   1              //Ka=K>>2;//因为电路板上低两位已拉高,所以只需要高8位
 173   1              //Ka&=0x00FF;//只用了低八位
 174   1              Ka = 0x00AB;//为测试  方便
 175   1              MK1 = MK2;
 176   1              level1 = level2;
 177   1      }
 178          
 179          
C51 COMPILER V7.50   CTR_BACKUP                                                            03/27/2008 14:22:15 PAGE 4   

 180          void main(void)//主程序开始
 181          {       
 182   1              DELAY(100);
 183   1              config();
 184   1              adc_ini();
 185   1              adc_chan(0);
 186   1              uart_ini();
 187   1              dac_ini();
 188   1              
 189   1              port_ini();
 190   1              
 191   1              //DELAY(2000);
 192   1              //TIC_ini();
 193   1              //DELAY(2000);
 194   1              P0&=0x00;//如果要调整P0口增益值,则打开此句
 195   1              printf("P0=%02BX\n",P0);
 196   1              //DELAY(2000);
 197   1              P0|=0xFF;//第一级AD7520增益先设为不放大,即放大倍数为(1023/1024)
 198   1              //DELAY(2000);
 199   1              printf("P0=%02BX\n",P0);
 200   1              //printf("UIK=%f\n",UIK);
 201   1              DAC0H=0x07;
 202   1          DAC0L=0xFF;//AC0输出恒值5v
 203   1              //i=0;
 204   1              //adc_start();
 205   1              //SCONV = 1;                                    //启动AD转换
 206   1              /////////////////初始化
 207   1              for (i=0;i<8;i++)
 208   1              {
 209   2                      num[i] = 1;
 210   2              }
 211   1              level1 = 1;//初始设定等级为等级1
 212   1              MK1=1.1;//初始设定值为1.1v
 213   1              RK=Lookuptab(1);//查等级为1的参考表,设定RK值
 214   1              EK=RK-MK1;
 215   1              UPK=KP*EK;
 216   1              UIK=KI*EK+UIK;
 217   1              UK=UPK+UIK;
 218   1              UDA = 5.0;
 219   1              K = UK/UDA*1024;
 220   1              //Ka = K>>2; 
 221   1              Ka = 0x00AB;//0110,0100 用于测试用,并不是实际值
 222   1      
 223   1              //////////////////////////////初始化完成
 224   1      
 225   1              while(1){                                       //连续进行AD转换
 226   2              
 227   2              //TIC_start();
 228   2              adc_start();
 229   2              SCONV = 1;                              //开始一次转换
 230   2              DELAY(1000);                    //调延迟,等待转换完毕
 231   2              if (ADCI == 0)                  //中断处理完毕标志,进行输出
 232   2              {
 233   3              printf("temph=%02BX,templ=%02BX\n",temph,templ);//串口输出转换值
 234   3              printf("UIK=%f\n",UIK);
 235   3              
 236   3              readval();
 237   3              DELAY(500);
 238   3              MK2=(float)tempval*5/4096;//必须强制转换为浮点数,否则结果不对
 239   3      
 240   3                       if(0<MK2&MK2<=1)  {level2 = 0;}
 241   3              else if(1<MK2&MK2<=2)  {level2 = 1;}
C51 COMPILER V7.50   CTR_BACKUP                                                            03/27/2008 14:22:15 PAGE 5   

 242   3              else if(2<MK2&MK2<=3)  {level2 = 2;}
 243   3              else if(3<MK2&MK2<=4)  {level2 = 3;}
 244   3              else if(4<MK2&MK2<=5)  {level2 = 4;}
 245   3          else                       {level2 = 5;}//这段程序目的是查表确定振动的给定参考值以便与采集来的数据比较
 246   3              
 247   3      
 248   3      
 249   3              if (level2!=level1)
 250   3              pi();
 251   3              printf("MK1=%f\n",MK1);
 252   3              printf("MK2=%f\n",MK2);
 253   3              printf("RK=%f\n",RK);
 254   3              printf("EK=%f\n",EK);
 255   3              printf("UPK=%f\n",UPK);
 256   3              printf("UIK=%f\n",UIK);
 257   3              printf("UK=%f\n",UK);
 258   3          printf("K=%04X\n",K);
 259   3              printf("Ka=%04X\n",Ka);
 260   3              printf("num[0]=%d\n",num[0]);
 261   3              //printf("gkg %d\n",sizeof(K));
 262   3              /////将Ka值进行翻转并输出到P2口
 263   3              //方法一
 264   3      
 265   3              num[0]=Ka&0x01;
 266   3              num[1]=Ka&0x02;
 267   3              num[2]=Ka&0x04;
 268   3              num[3]=Ka&0x08;
 269   3              num[4]=Ka&0x10;
 270   3              num[5]=Ka&0x20;
 271   3              num[6]=Ka&0x40;
 272   3              num[7]=Ka&0x80;
 273   3      
 274   3              for (i=0;i<8;i++)
 275   3              {
 276   4                      if (num[i]==pow(2,i))
 277   4                         num[i]=1;
 278   4                      else num[i]=0;
 279   4              }
 280   3      
 281   3              //方法二
 282   3              /*
 283   3              for (i=0;i<8;i++)
 284   3              {
 285   3                      Ka = Ka>>i;
 286   3                      num[i]=fmod(Ka,2);
 287   3              }
 288   3              */
 289   3              Kout = 0;
 290   3              for (i=0;i<8;i++)
 291   3              {       
 292   4                      
 293   4                      Kout +=pow(2,(7-i))*num[i];
 294   4              }
 295   3              P2 =Kout; //本应该为此句,再次利用下句做以简单替代用于测试
 296   3              //P2|=Ka;//正式给端口赋值,产生AD7520增益
 297   3              //P2^=Ka;//正式给端口赋值,产生AD7520增益
 298   3              DELAY(500);
 299   3              printf("P2=%02BX\n",P2);//显示P2口置位是否正确
 300   3              printf("P0=%02BX\n",P0);
 301   3              printf("num[0]=%d\n",num[0]);
 302   3              printf("num[1]=%d\n",num[1]);
 303   3              printf("num[2]=%d\n",num[2]);
C51 COMPILER V7.50   CTR_BACKUP                                                            03/27/2008 14:22:15 PAGE 6   

 304   3              printf("num[3]=%d\n",num[3]);
 305   3              printf("num[4]=%d\n",num[4]);
 306   3              printf("num[5]=%d\n",num[5]);
 307   3              printf("num[6]=%d\n",num[6]);
 308   3              printf("num[7]=%d\n\n",num[7]);
 309   3              DELAY(1000);
 310   3      
 311   3      
 312   3              }
 313   2                              }
 314   1      }
 315          
 316          void DELAY(int length)//延迟函数
 317          {
 318   1      while (length >=0)
 319   1          length--;
 320   1      }
 321                          
 322          
 323          
 324          
 325          
 326          
 327          
 328          


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =   2122    ----
   CONSTANT SIZE    =    228    ----
   XDATA SIZE       =     30    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =     32    ----
   IDATA SIZE       =   ----    ----
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

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