Routinensammlung und Gewusst-wie für Mikrocontroller

Begrenzung und Sättigung bei Mikrocontrollern

Es geht hierbei um die Absicherung vor Überlaufeffekten. Gerade in der Regelungstechnik lassen sich nicht immer Übersteuerungen vermeiden, dann ist Begrenzung und Sättigung nützlich.

Begrenzung

Hierbei geht es um die Einschränkung eines Wertebereiches einer Zahl, unabhängig von ihrer Herkunft, also Punkt- und Strichrechnung.
Beispielsweise: if (i>10) i=10;

Begrenzung ist in Hochsprachen sehr einfach formulierbar. Siehe Beispiel.

Eine Begrenzung ist auch zweckmäßig bei Bitbreiten-Verringerung; der Übergang zu „Sättigung“ ist in diesem Fall fließend.

Makro-Sammlung (zum Rauskopieren):
PICAVR ATmega8051
1 Byte in W1-Byte-Operanden2-Byte-Operanden1 Byte in A
signed X = Maximum aus X und U (untere Grenze) vzb.   if (x<u) x=u;
Vermeiden!
.macro maxs1 ;X,U
	cp	@0,@1
	brge	pc+2
	mov	@0,@1
.endm
.macro maxs1k ;X,U
	cpi	@0,@1
	brge	pc+2
	ldi	@0,@1
.endm
.macro maxs2 ;XH,XL, UH,UL
	cp	@1,@3
	cpc	@0,@2
	brge	pc+2
	movw	@0:@1,@2:@3
.endm
.macro maxs2k ;XH,XL, U
	cpi	@1,LOW(@2)
	mov	temp,HIGH(@2)
	cpc	@0,temp
	brge	pc+3
	ldiw	@0,@1, @2
.endm
maxs1 macro RA,RB
local e
	mov	a,RA
	clr	c
	subb	a,RB
	swap	a
	rr	a
	xrl	a,PSW
	jnb	ACC.2,e
	mov	a,RB
	mov	RA,a
e:
endm
signed X = Minimum aus X und O (obere Grenze) vzb.   if (x>=o) x=o;
Vermeiden!
.macro mins1 ;X,U
	cp	@0,@1
	brlt	pc+2
	mov	@0,@1
.endm
.macro mins1k ;X,U
	cpi	@0,@1
	brlt	pc+2
	ldi	@0,@1
.endm
.macro mins2 ;XH,XL, UH,UL
	cp	@1,@3
	cpc	@0,@2
	brlt	pc+2
	movw	@0:@1,@2:@3
.endm
.macro mins2k ;XH,XL, U
	cpi	@1,LOW(@2)
	mov	temp,HIGH(@2)
	cpc	@0,temp
	brlt	pc+3
	ldiw	@0,@1, @2
.endm
mins1 macro RA,RB
local e
	mov	a,RB
	clr	c
	subb	a,RA
	swap	a
	rr	a
	xrl	a,PSW
	jb	ACC.2,e
	mov	a,RB
	mov	RA,a
e:
endm
signed X = Eingrenzung von X zwischen U und O vzb.   if (x<u) x=u; if (x>=o) x=o;
Vermeiden!
.macro lims1 ;X,U,O
 	maxs1	@0,@1
 	mins1	@0,@2
.endm
.macro lims1k ;X,U,O
 	maxs1k	@0,@1
 	mins1k	@0,@2
.endm
.macro lims2 ;XH,XL, UH,UL, OH,OL
 	maxs2	@0,@1, @2,@3
 	mins2	@0,@1, @4,@5
.endm
.macro lims2k ;XH,XL, U, O
 	maxs2k	@0,@1, @2
 	mins2k	@0,@1, @3
.endm
lims1 macro x,u,o
	maxs1	x,u
	mins1	x,o
endm
unsigned X = Maximum aus X und U (untere Grenze) vzl.   if (x<u) x=u;
.macro maxu1 ;X,U
	cp	@0,@1
	brsh	pc+2
	mov	@0,@1
.endm
.macro maxu1k ;X,U
	cpi	@0,@1
	brsh	pc+2
	ldi	@0,@1
.endm
.macro maxu2 ;XH,XL, UH,UL
	cp	@1,@3
	cpc	@0,@2
	brsh	pc+2
	movw	@0:@1,@2:@3
.endm
.macro maxu2k ;XH,XL, U
	cpi	@1,LOW(@2)
	mov	temp,HIGH(@2)
	cpc	@0,temp
	brsh	pc+3
	ldiw	@0,@1, @2
.endm
maxu1 macro RB
;X ist in A
	cjne	a,RB,$+3
	jnc	$+4
	mov	a,RB
endm
unsigned X = Minimum aus X und O (obere Grenze) vzl.   if (x>=o) x=o;
.macro minu1 ;X,U
	cp	@0,@1
	brlo	pc+2
	mov	@0,@1
.endm
.macro minu1k ;X,U
	cpi	@0,@1
	brlo	pc+2
	ldi	@0,@1
.endm
.macro minu2 ;XH,XL, UH,UL
	cp	@1,@3
	cpc	@0,@2
	brlo	pc+2
	movw	@0:@1,@2:@3
.endm
.macro minu2k ;XH,XL, U
	cpi	@1,LOW(@2)
	mov	temp,HIGH(@2)
	cpc	@0,temp
	brlo	pc+3
	ldiw	@0,@1, @2
.endm
minu1 macro RB
;X ist in A
	cjne	a,RB,$+3
	jc	$+4
	mov	a,RB
endm
unsigned X = Eingrenzung von X zwischen U und O vzl.   if (x<u) x=u; if (x>=o) x=o;
.macro limu1 ;X,U,O
 	maxu1	@0,@1
 	minu1	@0,@2
.endm
.macro limu1k ;X,U,O
 	maxu1k	@0,@1
 	minu1k	@0,@2
.endm
.macro limu2 ;XH,XL, UH,UL, OH,OL
 	maxu2	@0,@1, @2,@3
 	minu2	@0,@1, @4,@5
.endm
.macro limu2k ;XH,XL, U, O
 	maxu2k	@0,@1, @2
 	minu2k	@0,@1, @3
.endm
limu1 macro u,o
;X ist in A
	maxu1	x,u
	minu1	x,o
endm
signed char X = Begrenzung(signed short X)
Vermeiden!
.macro cwbs ;XH,XL
	subi	@1,0x80	;80h addieren
	sbci	@0,0xFF
	breq	pc+4	;High-Teil 0: OK
	ldi	@1,0xFF
	brge	pc+2	;wenn N^V == 0
	ldi	@1,0
	subi	@1,0x80	;wieder vzb.
.endm
cwbs macro XH,XL
local e
	mov	a,XL
	add	a,#80h
	mov	a,XH
	adc	a,#0
	jz	e
	mov	XL,#7Fh
	swap	a
	rr	a
	xrl	a,PSW
	jnb	ACC.2,e
	inc	XL
e:
endm


Sättigung

Hierbei geht es um die Vermeidung eines Überlaufs nach einer Strichrechenoperation.
Beispielsweise: 90h + A0h = 30h ⇒ FFh

Sättigung ist in Hochsprachen nicht direkt verfügbar! Mancher Leser wird entsprechende MMX-Befehle kennen.

Makro-Sammlung (zum Rauskopieren):
PICAVR ATmega8051
1 Byte in W1-Byte-Operanden2-Byte-Operanden1 Byte in A
vzb. Sättigung nach Addition oder Subtraktion vzb. Zahlen
Vermeiden!
Ausweich auf vzl. += vzb.
.macro sats1	;A
	brvc	pc+4
	ldi	@0,0x7F
	brmi	pc+2
	ldi	@0,0x80
.endm
.macro sats2	;AH,AL
	brvc	pc+6
	ldiw	@0,@1, 0x7FFF
	brmi	pc+3
	ldiw	@0,@1, 0x8000
.endm
sats1 macro
	jnb	PSW.2,$+8
	rlc	a
	mov	a,#80
	subb	a,#0
endm
vzl. Sättigung nach Addition vzl. Zahlen
satu1a macro
	SKPNC
	 movlw	0FFh
endm
.macro satu1a	;A
	brcc	pc+2
	ldi	@0,0xFF
.endm
.macro satu2a	;AH,AL
	brcc	pc+3
	ldiw	@0,@1, 0xFFFF
.endm
satu1a macro
	jnc	$+4
	mov	a,#0FFh
endm
vzl. Sättigung nach Subtraktion vzl. Zahlen
satu1s macro
	SKPNC
	 movlw	0
endm
.macro satu1s	;A
	brcc	pc+2
	ldi	@0,0x00
.endm
.macro satu2s	;AH,AL
	brcc	pc+3
	ldiw	@0,@1, 0x0000
.endm
satu1s macro
	jnc	$+3
	clr	a
endm
vzl. Sättigung nach Addition vzl. (A) + vzb. (B)
Der High-Teil des zweiten (vzb.) Summanden muss angegeben werden
satus1 macro B
	btfsc	B,7
	 goto	$+4
	skpnc
	 movlw	0FFh
	goto	$+3
	skpc
	 movlw	0
endm
.macro satus1	;A, B
	sbrc	@1,7
	 rjmp	pc+4
	brcc	pc+5
	ldi	@0,0xFF
	rjmp	pc+3
	brcs	pc+2
	ldiw	@0,0x00
.endm
.macro satus2	;AH,AL, BH
	sbrc	@2,7
	 rjmp	pc+5
	brcc	pc+7
	ldiw	@0,@1, 0xFFFF
	rjmp	pc+4
	brcs	pc+3
	ldiw	@0,@1, 0x0000
.endm
satus1 macro
;2. Operand in B
	jb	B.7,$+9
	jnc	$+9
	mov	a,0FFh
	sjmp	$+5
	jc	$+3
	clr	a
endm
vzb. Sättigung nach Addition vzb. (A) + vzl. (B)
Vermeiden! Auflösbar durch Inversion des MSB vor und nach der Rechnung mit vzl. Sättigung.


haftmann#software, 20.12.2005