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

📄 pidcalc.s

📁 平缝机的单片机伺服控制系统源代码。本程序为用单片机控制永磁同步电机的低成本方案
💻 S
字号:
	.module PIDCALC.c
	.area text(rom, con, rel)
	.dbfile C:\DOCUME~1\niutao\MYDOCU~1\永磁电机\平缝机\新建文件夹\函数库\PID\PIDCALC.c
	.dbfunc e PIDInit _PIDInit fV
	.dbstruct 0 14 PID
	.dbfield 0 SetValue i
	.dbfield 2 P i
	.dbfield 4 I i
	.dbfield 6 D i
	.dbfield 8 Error I
	.dbfield 10 LastError I
	.dbfield 12 PrevError I
	.dbend
;             pp -> R20,R21
	.even
_PIDInit::
	rcall push_gset1
	movw R20,R16
	sbiw R28,2
	.dbline -1
	.dbline 27
; /*****************************************************************
;  *  文件名:      PID.c
;  *  版本号:      
;  *  创作日期:    2005.7.12
;  *  作者:        Wangzq
;  *  功能说明:    PID增量式算法
;  *  其它说明:    
;  
;  *****************************************************************/
;  
; 
; /*****************************************************************
; 
;  *   修改日期:     
;  *   修改人:
;  *   修改原因:
; 
; *******************************************************************/
;  
; #include "PIDCALC.h"  
;  
; //****************************************************************
; //增量式PID算法
; //
; //*************************************************************** 
; void PIDInit (struct PID *pp )
; {
	.dbline 28
;     memset( pp, 0, sizeof(struct PID ) );
	ldi R24,14
	ldi R25,0
	std y+1,R25
	std y+0,R24
	clr R18
	clr R19
	movw R16,R20
	rcall _memset
	.dbline -2
L1:
	adiw R28,2
	rcall pop_gset1
	.dbline 0 ; func end
	ret
	.dbsym r pp 20 pS[PID]
	.dbend
	.dbfunc e PIDCalc _PIDCalc fc
;         derror -> <dead>
;         perror -> R14,R15
;              K -> R10
;         result -> y+4
;        pidtemp -> y+0
;     Fact_Value -> R12,R13
;             pp -> R10,R11
	.even
_PIDCalc::
	rcall push_gset5
	movw R12,R18
	movw R10,R16
	sbiw R28,8
	.dbline -1
	.dbline 32
; }
; 
; byte PIDCalc(struct PID *pp, word Fact_Value )
; {
	.dbline 37
;     byte  K;          					// PID实际输出值
; 	sword  perror,derror;
;   	sdword result,pidtemp;
; 	
; 	if (pp->SetValue < 300  )         //低速的PID值
	movw R30,R10
	ldd R24,z+0
	ldd R25,z+1
	st -y,R30
	cpi R24,44
	ldi R30,1
	cpc R25,R30
	ld R30,y+
	brsh L3
	.dbline 38
;       {
	.dbline 39
;       	pp->P = KPL;               //低速的p值
	ldi R24,45
	ldi R25,0
	std z+3,R25
	std z+2,R24
	.dbline 40
;         pp->I = KIL;
	ldi R24,5
	movw R30,R10
	std z+5,R25
	std z+4,R24
	.dbline 41
;         pp->D = KDL;
	ldi R24,2
	movw R30,R10
	std z+7,R25
	std z+6,R24
	.dbline 42
;       }
	rjmp L4
L3:
	.dbline 44
;     else 
; 	{
	.dbline 45
; 		if (pp->SetValue > 2500)   //高速的PID值
	ldi R24,2500
	ldi R25,9
	movw R30,R10
	ldd R2,z+0
	ldd R3,z+1
	cp R24,R2
	cpc R25,R3
	brsh L5
	.dbline 46
;          {
	.dbline 47
;      	    pp->P = KPH;          //告诉的p值
	ldi R24,22
	ldi R25,0
	std z+3,R25
	std z+2,R24
	.dbline 48
;             pp->I = KIH;
	ldi R24,3
	movw R30,R10
	std z+5,R25
	std z+4,R24
	.dbline 49
;             pp->D = KDH;
	ldi R24,1
	movw R30,R10
	std z+7,R25
	std z+6,R24
	.dbline 50
;          }
	rjmp L6
L5:
	.dbline 52
;    		else				//中速的PID值,p,i,d按一定的斜率计算
;     	{      
	.dbline 55
;      		
; //*********************计算PID插值常数***************************	   	    
; 			perror = (2500-pp->SetValue);				//计算PID插值常数
	movw R30,R10
	ldd R2,z+0
	ldd R3,z+1
	ldi R24,2500
	ldi R25,9
	movw R14,R24
	sub R14,R2
	sbc R15,R3
	.dbline 57
; 			
; 			pidtemp = (KPL-KPH);
	ldi R20,23
	ldi R21,0
	ldi R22,0
	ldi R23,0
	std y+0,R20
	std y+1,R21
	std y+2,R22
	std y+3,R23
	.dbline 58
; 			pidtemp *= perror;
	movw R2,R14
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	ldd R16,y+0
	ldd R17,y+1
	ldd R18,y+2
	ldd R19,y+3
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	rcall empy32s
	std y+0,R16
	std y+1,R17
	std y+2,R18
	std y+3,R19
	.dbline 59
; 			pidtemp /= PIM;
	ldi R20,152
	ldi R21,8
	ldi R22,0
	ldi R23,0
	ldd R16,y+0
	ldd R17,y+1
	ldd R18,y+2
	ldd R19,y+3
	st -y,R23
	st -y,R22
	st -y,R21
	st -y,R20
	rcall div32s
	std y+0,R16
	std y+1,R17
	std y+2,R18
	std y+3,R19
	.dbline 60
; 			pidtemp += KPH;
	ldi R20,22
	ldi R21,0
	ldi R22,0
	ldi R23,0
	ldd R2,y+0
	ldd R3,y+1
	ldd R4,y+2
	ldd R5,y+3
	add R2,R20
	adc R3,R21
	adc R4,R22
	adc R5,R23
	std y+0,R2
	std y+1,R3
	std y+2,R4
	std y+3,R5
	.dbline 61
; 			pp->P = pidtemp;
	ldd R2,y+0
	ldd R3,y+1
	movw R30,R10
	std z+3,R3
	std z+2,R2
	.dbline 63
; 			
; 			pidtemp = (KIL-KIH);
	ldi R20,2
	ldi R21,0
	ldi R22,0
	ldi R23,0
	std y+0,R20
	std y+1,R21
	std y+2,R22
	std y+3,R23
	.dbline 64
; 			pidtemp *= perror;
	movw R2,R14
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	ldd R16,y+0
	ldd R17,y+1
	ldd R18,y+2
	ldd R19,y+3
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	rcall empy32s
	std y+0,R16
	std y+1,R17
	std y+2,R18
	std y+3,R19
	.dbline 65
; 			pidtemp /= PIM;
	ldi R20,152
	ldi R21,8
	ldi R22,0
	ldi R23,0
	ldd R16,y+0
	ldd R17,y+1
	ldd R18,y+2
	ldd R19,y+3
	st -y,R23
	st -y,R22
	st -y,R21
	st -y,R20
	rcall div32s
	std y+0,R16
	std y+1,R17
	std y+2,R18
	std y+3,R19
	.dbline 66
; 			pidtemp += KIH;
	ldi R20,3
	ldi R21,0
	ldi R22,0
	ldi R23,0
	ldd R2,y+0
	ldd R3,y+1
	ldd R4,y+2
	ldd R5,y+3
	add R2,R20
	adc R3,R21
	adc R4,R22
	adc R5,R23
	std y+0,R2
	std y+1,R3
	std y+2,R4
	std y+3,R5
	.dbline 67
; 			pp->I = pidtemp;
	ldd R2,y+0
	ldd R3,y+1
	movw R30,R10
	std z+5,R3
	std z+4,R2
	.dbline 76
; 			
; //		   	pidtemp = (KDL-KDH);
; //			pidtemp *= perror;
; //			pidtemp /= PIM;
; //			pidtemp += KDH;
; //			pp->D = pidtemp;
; //*********************计算PID插值常数***************************	
; 			
; 		}
L6:
	.dbline 77
; 	}
L4:
	.dbline 80
; 	
; 	//result = 0;// 清零     
; 	if (Fact_Value > 7000)				//转速上限值设定
	ldi R24,7000
	ldi R25,27
	cp R24,R12
	cpc R25,R13
	brsh L7
	.dbline 81
; 	{
	.dbline 82
; 		Fact_Value = 7000;
	movw R12,R24
	.dbline 83
; 	}
L7:
	.dbline 85
; 	                     
;   	pp->Error  = pp->SetValue - Fact_Value;		// 取当前偏差
	movw R30,R10
	ldd R2,z+0
	ldd R3,z+1
	sub R2,R12
	sbc R3,R13
	std z+9,R3
	std z+8,R2
	.dbline 87
; 	
;     perror = pp->Error - pp->LastError;			//计算比例偏差
	movw R30,R10
	ldd R2,z+10
	ldd R3,z+11
	movw R30,R10
	ldd R14,z+8
	ldd R15,z+9
	sub R14,R2
	sbc R15,R3
	.dbline 96
; 
; //*****************************************************************
; //	derror = pp->LastError;						//计算微分偏差
; //	derror += pp->LastError;
; //	derror = pp->Error - derror;
; //	derror += pp->PrevError;
; //****************************************************************
; 	
; 	pp->PrevError = pp->LastError;	// 当前误差Error[-1]赋给上次误差Error[-2] 
	movw R30,R10
	ldd R2,z+10
	ldd R3,z+11
	movw R30,R10
	std z+13,R3
	std z+12,R2
	.dbline 97
;     pp->LastError = pp->Error;		// 取当前误差
	movw R30,R10
	ldd R2,z+8
	ldd R3,z+9
	movw R30,R10
	std z+11,R3
	std z+10,R2
	.dbline 99
; 	
;     pidtemp = perror;           
	movw R2,R14
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	std y+0,R2
	std y+1,R3
	std y+2,R4
	std y+3,R5
	.dbline 100
; 	pidtemp *= (pp->P); 			  
	movw R30,R10
	ldd R2,z+2
	ldd R3,z+3
	clr R4
	clr R5
	ldd R16,y+0
	ldd R17,y+1
	ldd R18,y+2
	ldd R19,y+3
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	rcall empy32s
	std y+0,R16
	std y+1,R17
	std y+2,R18
	std y+3,R19
	.dbline 101
; 	result = pidtemp;						// 比例项 
	ldd R2,y+0
	ldd R3,y+1
	ldd R4,y+2
	ldd R5,y+3
	std y+4,R2
	std y+5,R3
	std y+6,R4
	std y+7,R5
	.dbline 103
; 	
; 	pidtemp = pp->Error;
	movw R30,R10
	ldd R2,z+8
	ldd R3,z+9
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	std y+0,R2
	std y+1,R3
	std y+2,R4
	std y+3,R5
	.dbline 104
; 	pidtemp *= (pp->I);
	movw R30,R10
	ldd R2,z+4
	ldd R3,z+5
	clr R4
	clr R5
	ldd R16,y+0
	ldd R17,y+1
	ldd R18,y+2
	ldd R19,y+3
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	rcall empy32s
	std y+0,R16
	std y+1,R17
	std y+2,R18
	std y+3,R19
	.dbline 105
; 	result += pidtemp;						// 积分项
	ldd R2,y+0
	ldd R3,y+1
	ldd R4,y+2
	ldd R5,y+3
	ldd R6,y+4
	ldd R7,y+5
	ldd R8,y+6
	ldd R9,y+7
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	std y+4,R6
	std y+5,R7
	std y+6,R8
	std y+7,R9
	.dbline 112
; 		
; 		
; //  	pidtemp = derror;
; //		pidtemp *= (pp->D);
; //		result += pidtemp;            	 // 微分项
;   	
; 	SumDu += result;
	ldd R2,y+4
	ldd R3,y+5
	ldd R4,y+6
	ldd R5,y+7
	lds R8,_SumDu+2
	lds R9,_SumDu+2+1
	lds R6,_SumDu
	lds R7,_SumDu+1
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	sts _SumDu+1,R7
	sts _SumDu,R6
	sts _SumDu+2+1,R9
	sts _SumDu+2,R8
	.dbline 114
; 	
; 	if (SumDu <= 0)
	ldi R20,0
	ldi R21,0
	ldi R22,0
	ldi R23,0
	cp R20,R6
	cpc R21,R7
	cpc R22,R8
	cpc R23,R9
	brlt L9
	.dbline 115
; 	{
	.dbline 116
; 		K = 0;
	clr R10
	.dbline 117
; 	}
	rjmp L10
L9:
	.dbline 120
; 	
; 	else 
; 	{
	.dbline 121
; 		result = SumDu;
	lds R4,_SumDu+2
	lds R5,_SumDu+2+1
	lds R2,_SumDu
	lds R3,_SumDu+1
	std y+4,R2
	std y+5,R3
	std y+6,R4
	std y+7,R5
	.dbline 122
; 		result /= 3000;
	ldi R20,184
	ldi R21,11
	ldi R22,0
	ldi R23,0
	ldd R16,y+4
	ldd R17,y+5
	ldd R18,y+6
	ldd R19,y+7
	st -y,R23
	st -y,R22
	st -y,R21
	st -y,R20
	rcall div32s
	std y+4,R16
	std y+5,R17
	std y+6,R18
	std y+7,R19
	.dbline 124
; 		
; 		if (result > 1000) 
	ldi R20,232
	ldi R21,3
	ldi R22,0
	ldi R23,0
	ldd R2,y+4
	ldd R3,y+5
	ldd R4,y+6
	ldd R5,y+7
	cp R20,R2
	cpc R21,R3
	cpc R22,R4
	cpc R23,R5
	brge L11
	.dbline 125
; 			result = 1000;
	ldi R20,232
	ldi R21,3
	ldi R22,0
	ldi R23,0
	std y+4,R20
	std y+5,R21
	std y+6,R22
	std y+7,R23
L11:
	.dbline 127
; 			
; 		result *= 0xff;
	ldd R2,y+4
	ldd R3,y+5
	ldd R4,y+6
	ldd R5,y+7
	ldi R20,255
	ldi R21,0
	ldi R22,0
	ldi R23,0
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	movw R16,R20
	movw R18,R22
	rcall empy32s
	std y+4,R16
	std y+5,R17
	std y+6,R18
	std y+7,R19
	.dbline 128
; 		result /=1000;
	ldi R20,232
	ldi R21,3
	ldi R22,0
	ldi R23,0
	ldd R16,y+4
	ldd R17,y+5
	ldd R18,y+6
	ldd R19,y+7
	st -y,R23
	st -y,R22
	st -y,R21
	st -y,R20
	rcall div32s
	std y+4,R16
	std y+5,R17
	std y+6,R18
	std y+7,R19
	.dbline 130
; 		
; 		K = result;
	ldd R10,y+4
	.dbline 131
; 		K = PIDBound(K, Fact_Value);						//计算控制值上限
	movw R18,R12
	mov R16,R10
	rcall _PIDBound
	mov R10,R16
	.dbline 132
; 	}
L10:
	.dbline 134
; 		
; 	return K;                              
	mov R16,R10
	.dbline -2
L2:
	adiw R28,8
	rcall pop_gset5
	.dbline 0 ; func end
	ret
	.dbsym l derror 1 I
	.dbsym r perror 14 I
	.dbsym r K 10 c
	.dbsym l result 4 L
	.dbsym l pidtemp 0 L
	.dbsym r Fact_Value 12 i
	.dbsym r pp 10 pS[PID]
	.dbend
	.dbfunc e PIDBound _PIDBound fc
;     Fact_Value -> R18,R19
;              K -> R16
	.even
_PIDBound::
	.dbline -1
	.dbline 138
; }   
;  
; byte PIDBound(byte K, word Fact_Value)
; {
	.dbline 144
; 	//if (K >0x7f )
; 	//{
; 	//	K = 0x7f;
; 	//} 
; 	
; 	return K;
	.dbline -2
L13:
	.dbline 0 ; func end
	ret
	.dbsym r Fact_Value 18 i
	.dbsym r K 16 c
	.dbend

⌨️ 快捷键说明

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