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

📄 增量式模糊控制.lst

📁 增量式模糊PID控制方法AVR单片机mega16
💻 LST
📖 第 1 页 / 共 5 页
字号:
    02A5 5001      SUBI	R16,1
    02A6 DF56      RCALL	_LCD_WriteControl
    02A7 C004      RJMP	0x02AC
(0221) case 4: LCD_WriteControl (0xd4 + column - 1); break;
    02A8 2F04      MOV	R16,R20
    02A9 520C      SUBI	R16,0x2C
    02AA 5001      SUBI	R16,1
    02AB DF51      RCALL	_LCD_WriteControl
(0222) default: break;
    02AC 940E03E8  CALL	pop_gset2
    02AE 9508      RET
(0223) }
(0224) }
(0225) // ************************** //
(0226) // *** Turn the cursor on *** //
(0227) // ************************** //
(0228) void LCD_Cursor_On (void)
(0229) {
(0230) LCD_WriteControl (LCD_CURS_ON);
_LCD_Cursor_On:
    02AF E00D      LDI	R16,0xD
    02B0 DF4C      RCALL	_LCD_WriteControl
    02B1 9508      RET
(0231) }
(0232) // *************************** //
(0233) // *** Turn the cursor off *** //
(0234) // *************************** //
(0235) void LCD_Cursor_Off (void)
(0236) {
(0237) LCD_WriteControl (LCD_ON);
_LCD_Cursor_Off:
    02B2 E00C      LDI	R16,0xC
    02B3 DF49      RCALL	_LCD_WriteControl
    02B4 9508      RET
(0238) }
(0239) // ******************** //
(0240) // *** Turn Off LCD *** //
(0241) // ******************** //
(0242) void LCD_Display_Off (void)
(0243) {
(0244) LCD_WriteControl(LCD_OFF);
_LCD_Display_Off:
    02B5 E008      LDI	R16,0x8
    02B6 DF46      RCALL	_LCD_WriteControl
    02B7 9508      RET
(0245) }
(0246) // ******************* //
(0247) // *** Turn On LCD *** //
(0248) // ******************* //
(0249) void LCD_Display_On (void)
(0250) {
(0251) LCD_WriteControl(LCD_ON);
_LCD_Display_On:
    02B8 E00C      LDI	R16,0xC
    02B9 DF43      RCALL	_LCD_WriteControl
    02BA 9508      RET
_GetDeltFuzzyValue:
  j                    --> R20
  i                    --> R22
  delt_ei              --> R22
  ei                   --> R20
    02BB 940E03F4  CALL	push_gset2
    02BD 01B9      MOVW	R22,R18
    02BE 01A8      MOVW	R20,R16
FILE: D:\仿真\增量式模糊控制\main.c
(0001) #define ENABLE_BIT_DEFINITIONS
(0002) 
(0003) #include "includes.h"
(0004) //#define Vref 25600
(0005) 
(0006) 
(0007) //#define Vref 50000
(0008) void init_adc(void);
(0009) void WDR(void);
(0010) void WDT_init(void);
(0011) 
(0012) //unsigned char adc_mux = 0x01;  //通道选择
(0013) 
(0014) unsigned char RSend;
(0015) unsigned char RS_buf[10];
(0016) unsigned char RS_flag;
(0017) 
(0018) unsigned int SerPoint; //设定目标,应用时实际上取该值的1/10,出现温度的0.x度
(0019) int ei;                //最近1次的偏差,ei = stPID.SetPoint-stPID.T_adc_data[2]
(0020) int LastError;         //SetPoint-T_adc_data[1]
(0021) int delt_ei;           //偏差的变化:delt_ei = PID.LastError-ei
(0022) int T_adc_data[3];     //近3次的测量值,T_adc_data[2]为最近的一次
(0023) int ui;                //ui:输出
(0024) int delt_ui;           //delt_ei为增量式增量输出
(0025) /*
(0026) char DFC_tbl[11][13]={
(0027) //-12,-10,-8,-6,-4,-2,0,+2,+4,+6,+8,+10,+12
(0028)  -5,-5,-4,-4,-3,-3,-3,-3,-3,-2,-2,-1, 0,
(0029)  -5,-5,-4,-3,-2,-2,-2,-2,-2,-2,-1, 0, 0,
(0030) -5,-4,-3,-2,-1,-1,-1,-1,-2,-1, 0, 0, 0,
(0031) -4,-3,-2,-2,-1, 0, 0,-1,-1,-1, 0, 1, 2,
(0032) -3,-2,-1,-1,-1, 0, 0, 0, 1, 1, 2, 3, 4,
(0033)  -3,-2,-1,-1,-1, 0, 0, 1, 1, 1, 2, 3, 4,
(0034) -2,-2,-1,-1,-1, 0, 0, 2, 2, 2, 2, 3, 4,
(0035)  0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 4, 5,
(0036)  0, 0, 0, 0, 1, 1, 1, 2, 3, 3, 3, 4, 5,
(0037)  0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5,
(0038)  0, 0, 0, 0, 2, 2, 3, 3, 4, 5, 5, 5, 5
(0039) };
(0040) */
(0041) char DFC_tbl[11][13]={
(0042) /*-12,-10,-8,-6,-4,-2,0,+2,+4,+6,+8,+10,+12*/
(0043) /*-5*/  5, 5, 5, 3, 3, 3, 1, 1, 0, 0, 0,
(0044) /*-4*/  5, 6, 5, 3, 3, 3, 1, 1, 0, 0, 0,
(0045) /*-3*/  5, 5, 5, 4, 4, 4, 1, 1, 0,-1,-1,
(0046) /*-2*/  5, 6, 5, 3, 3, 1, 0, 0,-2,-3,-3, 
(0047) /*-1*/  5, 6, 5, 3, 3, 1, 0,-2,-2,-3,-3, 
(0048) /*0*/   5, 6, 5, 3, 1, 0, 0,-3,-5,-6,-5, 
(0049) /*1*/   3, 3, 2, 1, 0,-1,-3,-3,-5,-6,-5, 
(0050) /*2*/   3, 3, 1, 0, 0,-1,-3,-3,-5,-6,-5, 
(0051) /*3*/   1, 1, 0, 0, 0,-1,-2,-2,-5,-5,-5, 
(0052) /*4*/   0, 0,-1,-1,-2,-3,-3,-3,-5,-6,-5, 
(0053) /*5*/   0, 0,-1,-1,-2,-3,-3,-3,-5,-6,-5, 
(0054) };
(0055) 
(0056) int GetDeltFuzzyValue(int ei,int delt_ei)
(0057) {
(0058)   unsigned char i,j;
(0059)   #define delt_M 20
(0060)   if(ei > delt_M)
    02BF E184      LDI	R24,0x14
    02C0 E090      LDI	R25,0
    02C1 1784      CP	R24,R20
    02C2 0795      CPC	R25,R21
    02C3 F414      BGE	0x02C6
(0061)     ei = delt_M;
    02C4 E144      LDI	R20,0x14
    02C5 E050      LDI	R21,0
(0062)   if(ei<-delt_M)
    02C6 3E4C      CPI	R20,0xEC
    02C7 EFEF      LDI	R30,0xFF
    02C8 075E      CPC	R21,R30
    02C9 F414      BGE	0x02CC
(0063)     ei = -delt_M;	
    02CA EE4C      LDI	R20,0xEC
    02CB EF5F      LDI	R21,0xFF
(0064)   i = delt_ei + 5;
    02CC 5F6B      SUBI	R22,0xFB
    02CD 4F7F      SBCI	R23,0xFF
(0065)   j = 6 + ei*6/delt_M;
    02CE E006      LDI	R16,6
    02CF E010      LDI	R17,0
    02D0 019A      MOVW	R18,R20
    02D1 940E03D8  CALL	empy16s
    02D3 E124      LDI	R18,0x14
    02D4 E030      LDI	R19,0
    02D5 940E03A2  CALL	div16s
    02D7 2F40      MOV	R20,R16
    02D8 5F4A      SUBI	R20,0xFA
    02D9 4F5F      SBCI	R21,0xFF
(0066)   return DFC_tbl[i][j]; 
    02DA E08D      LDI	R24,0xD
    02DB 9F86      MUL	R24,R22
    02DC 0110      MOVW	R2,R0
    02DD E78D      LDI	R24,0x7D
    02DE E090      LDI	R25,0
    02DF 0E28      ADD	R2,R24
    02E0 1E39      ADC	R3,R25
    02E1 2FE4      MOV	R30,R20
    02E2 27FF      CLR	R31
    02E3 0DE2      ADD	R30,R2
    02E4 1DF3      ADC	R31,R3
    02E5 8100      LDD	R16,Z+0
    02E6 2711      CLR	R17
    02E7 940E03E8  CALL	pop_gset2
    02E9 9508      RET
(0067) }
(0068) /*
(0069) int GetDeltFuzzyValue(int ei,int delt_ei)
(0070) {
(0071)   unsigned char i,j;
(0072)   #define delt_M 20
(0073)   if(ei > delt_M)
(0074)     ei = delt_M;
(0075)   if(ei<-delt_M)
(0076)     ei = -delt_M;	
(0077)   i = delt_ei + 5;
(0078)   j = 5 + ei*5/delt_M;
(0079)   return DFC_tbl[i][j]; 
(0080) }
(0081) */
(0082) void Delt_FuzzyCtrl(void)
(0083) {
(0084)   #define delt_Um 50
(0085)   LastError = ei;//刷新近2次偏差
_Delt_FuzzyCtrl:
    02EA 9020013A  LDS	R2,ei
    02EC 9030013B  LDS	R3,ei+1
    02EE 92300139  STS	LastError+1,R3
    02F0 92200138  STS	LastError,R2
(0086)   ei = ADC-SerPoint;//ei = SerPoint - ADC;//ei = SerPoint - T_adc_data[2];
    02F2 9020013C  LDS	R2,SerPoint
    02F4 9030013D  LDS	R3,SerPoint+1
    02F6 B044      IN	R4,0x04
    02F7 B055      IN	R5,0x05
    02F8 1842      SUB	R4,R2
    02F9 0853      SBC	R5,R3
    02FA 9250013B  STS	ei+1,R5
    02FC 9240013A  STS	ei,R4
(0087)   delt_ei = LastError-ei;//刷新偏差的变化
    02FE 0112      MOVW	R2,R4
    02FF 90400138  LDS	R4,LastError
    0301 90500139  LDS	R5,LastError+1
    0303 1842      SUB	R4,R2
    0304 0853      SBC	R5,R3
    0305 92500137  STS	delt_ei+1,R5
    0307 92400136  STS	delt_ei,R4
(0088)   if(delt_ei > 5)
    0309 E085      LDI	R24,5
    030A E090      LDI	R25,0
    030B 1584      CP	R24,R4
    030C 0595      CPC	R25,R5
    030D F424      BGE	0x0312
(0089)     delt_ei = 5;
    030E 93900137  STS	delt_ei+1,R25
    0310 93800136  STS	delt_ei,R24
(0090)   if(delt_ei < -5)
    0312 91800136  LDS	R24,delt_ei
    0314 91900137  LDS	R25,delt_ei+1
    0316 3F8B      CPI	R24,0xFB
    0317 EFEF      LDI	R30,0xFF
    0318 079E      CPC	R25,R30
    0319 F434      BGE	0x0320
(0091)     delt_ei = -5;
    031A EF8B      LDI	R24,0xFB
    031B EF9F      LDI	R25,0xFF
    031C 93900137  STS	delt_ei+1,R25
    031E 93800136  STS	delt_ei,R24
(0092)   delt_ui = GetDeltFuzzyValue(ei,delt_ei);//采用模糊控制模型
    0320 91200136  LDS	R18,delt_ei
    0322 91300137  LDS	R19,delt_ei+1
    0324 9100013A  LDS	R16,ei
    0326 9110013B  LDS	R17,ei+1
    0328 DF92      RCALL	_GetDeltFuzzyValue
    0329 9310012D  STS	delt_ui+1,R17
    032B 9300012C  STS	delt_ui,R16
(0093)   //delt_ui = delt_ui; //delt_ui = delt_ui*2;                    //其中2是比例因子K
(0094)   if(delt_ui > delt_Um)
    032D E382      LDI	R24,0x32
    032E E090      LDI	R25,0
    032F 1780      CP	R24,R16
    0330 0791      CPC	R25,R17
    0331 F424      BGE	0x0336
(0095)     delt_ui = delt_Um;
    0332 9390012D  STS	delt_ui+1,R25
    0334 9380012C  STS	delt_ui,R24
(0096)   if(delt_ui < -delt_Um)//if(delt_ui < -delt_Um)
    0336 9180012C  LDS	R24,delt_ui
    0338 9190012D  LDS	R25,delt_ui+1
    033A 3C8E      CPI	R24,0xCE
    033B EFEF      LDI	R30,0xFF
    033C 079E      CPC	R25,R30
    033D F434      BGE	0x0344
(0097)     delt_ui = -delt_Um;//delt_ui = -delt_Um;
    033E EC8E      LDI	R24,0xCE
    033F EF9F      LDI	R25,0xFF
    0340 9390012D  STS	delt_ui+1,R25
    0342 9380012C  STS	delt_ui,R24
(0098)   ui += delt_ui;
    0344 9020012C  LDS	R2,delt_ui
    0346 9030012D  LDS	R3,delt_ui+1
    0348 9040012E  LDS	R4,ui
    034A 9050012F  LDS	R5,ui+1
    034C 0C42      ADD	R4,R2
    034D 1C53      ADC	R5,R3
    034E 9250012F  STS	ui+1,R5
    0350 9240012E  STS	ui,R4
(0099)   if(ui<1)
    0352 01C2      MOVW	R24,R4
    0353 3081      CPI	R24,1
    0354 E0E0      LDI	R30,0
    0355 079E      CPC	R25,R30
    0356 F434      BGE	0x035D
(0100)     ui = 1;
    0357 E081      LDI	R24,1
    0358 E090      LDI	R25,0
    0359 9390012F  STS	ui+1,R25
    035B 9380012E  STS	ui,R24
    035D 9508      RET
_main:
  count                --> Y+1
  j                    --> Y+0
  RS                   --> R20
  value                --> R20
  test                 --> R20
    035E 9724      SBIW	R28,4
(0101) }
(0102) void main(void)
(0103) {       
(0104)     float j;  
(0105)     int count;
(0106)     unsigned char *test = "The Voltage is: ";
    035F E144      LDI	R20,0x14
    0360 E051      LDI	R21,1
(0107)     unsigned char *value = "0.000 V";	
    0361 E04C      LDI	R20,0xC
    0362 E051      LDI	R21,1
(0108)     unsigned char *RS;
(0109)     RS = RS_buf;
    0363 E34F      LDI	R20,0x3F
    0364 E051      LDI	R21,1
(0110)     RS_flag = 0;
    0365 2422      CLR	R2
    0366 9220013E  STS	RS_flag,R2
(0111)     delay_nms(1);  
    0368 E001      LDI	R16,1
    0369 E010      LDI	R17,0
    036A 940E00D6  CALL	_delay_nms
(0112) 	SerPoint=500;  
    036C EF84      LDI	R24,0xF4
    036D E091      LDI	R25,1
    036E 9390013D  STS	SerPoint+1,R25
    0370 9380013C  STS	SerPoint,R24
(0113)     //dataport=0xff;
(0114)     OSCCAL=0Xab;//系统时钟校准,不同的芯片和不的频率,
    0372 EA8B      LDI	R24,0xAB
    0373 BF81      OUT	0x31,R24
(0115)     init_adc();	
    0374 940E037B  CALL	_init_adc
    0376 C001      RJMP	0x0378
(0116)     //InitSerial();    
(0117)     //init_time1();
(0118) 	/*
(0119)     Init_LCD();  
(0120)    // WDT_init();
(0121)           
(0122)     LCD_DisplayString(1,1,test);    
(0123)     LCD_DisplayString(2,1,value);    
(0124)     //put_string(value);  
(0125)     //put_char(0x0d);
(0126)     //put_char(0x0a); 
(0127) 	SerPoint=500;    
(0128)     while(1) 
(0129)     {        
(0130)        // j = (float)(((float)((Vref/1023)))*(ADCH*256+ADCL))/1000.00;
(0131)         //j = (float)(((float)((Vref/1023)))*( ADC&0X3FF))/1000.00;
(0132) 
(0133) 	    count = ADC;			
(0134)         value[0] = count /1000 + 0x30;
(0135)         count = count %1000;
(0136)         value[2] = count /100+0x30;
(0137)         count = count %100;
(0138)         value[3] = count  /10 + 0x30;			 
(0139)         value[4] = count  %10 + 0x30;			 
(0140)       
(0141)         LCD_Cursor(0,1);
(0142)         LCD_DisplayString(2,1,value); 
(0143) 		
(0144) 		
(0145) 		Delt_FuzzyCtrl();
(0146) 		
(0147) 		count = ui;			
(0148)         value[0] = count /1000+0x30;
(0149)         count = count %1000;
(0150)         value[2] = count /100+0x30;
(0151)         count = count %100;
(0152)         value[3] = count  /10 + 0x30;			 
(0153)         value[4] = count  %10 + 0x30;			 
(0154)       
(0155)         LCD_Cursor(0,1);
(0156)         LCD_DisplayString(1,1,value); 
(0157) 		*/
(0158)         //put_string(value); 
(0159)         //put_char(0x0d);
(0160)         //put_char(0x0a);        
(0161)               
(0162)          while(1) 
(0163)             {
(0164) 			  Delt_FuzzyCtrl();
    0377 DF72      RCALL	_Delt_FuzzyCtrl
    0378 CFFE      RJMP	0x0377
    0379 9624      ADIW	R28,4
    037A 9508      RET
FILE: D:\仿真\增量式模糊控制\AD.C
(0001) #define AD_C
(0002) #include "includes.h"
(0003) unsigned char  adc_mux = 0x01 ;
(0004) 
(0005) /******************************************************************************/
(0006) /******************************************************************************/
(0007) void init_adc(void)
(0008) {	
(0009) 
(0010)     //WDR();       //看门狗计数清零
(0011)     //WDTCR=0x0F;  //使能watchdog,并且,采用2048K分频,典型溢出时间5V时2.1S
(0012)     // ADCSRA=0X00;
(0013)     ADCSR = 0x00; 
_init_adc:
    037B 2422      CLR	R2
    037C B826      OUT	0x06,R2

⌨️ 快捷键说明

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