📄 增量式模糊控制.lst
字号:
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 + -