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

📄 convert.asm

📁 convert.asm: 1.From ASCII resp. BCD to binary 2.From binary to ASCII resp. BCD 3.From binary to H
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; ********************************************************
; * Number conversion routines, Version 0.1 January 2002 *
; * (C)2002 by info@avr-asm-tutorial.net                 *
; ********************************************************
;
; The following rules apply for all conversion routines:
; - Errors during conversion set the T-bit in the status
;   register.
; - Z points to either SRAM (Z>=$0060) or to registers
;   ($0001 .. $001D, exclude R0, R16 and R30/31).
; - ASCII- and BCD-coded numbers with multiple digits are
;   placed with higher significant digits at lower adres-
;   ses. Z should always point to the most significant
;   digit.
; - 16-bit-binary values are generally located in the
;   registers rBin1H:rBin1L. These must be defined within
;   the calling program.
; - Register rmp (range: R16..R29) is used within the
;   routines, its content is changed.
; - Register pair Z is used within the routines, its
;   content is set depending on the result.
; - Some routines use register R0 temporarily, its content
;   is restored.
; - Due to the use of the Z-Register pair the header file
;   for the target processor (xxxxdef.inc) must be inclu-
;   ded in the calling program or ZH (R31) and ZL (R30)
;   must be defined manually. Otherwise an error message
;   results, or you will get crazy things going on, when
;   you run the program.
; - Because subroutines and push/pop-operations are used
;   within these routines you must set the stack pointer
;   (SPH:SPL, resp. SPL for devices with equal or less
;   than 256 Byte internal SRAM).
;
; ***************** Routines Overview ********************
; Routines   Input        Conditions           Out, Errors
; --------------------------------------------------------
; AscToBin2  Z points on  stops at first non-  16-bit-bin
;            first ASCII  non-decimal digit,   rBin1H:L,
;            char         ignores leading      Overflow
;                         blanks and zeros
; Asc5ToBin2 Z points on  requires exact 5     16-bit-bin
;            first ASCII  valid digits,        rBin1H:L,
;            char         ignores leading      Overflow
;                         blanks and zeros     and non-dec
; Bcd5ToBin2 5-digit-BCD  requires exact 5     16-bit-bin
;            Z points to  valid digits         rBin1H:L
;            first digit                       Overflow
;                                              and non-BCD
; Bin2ToBcd5 16-bit-bin   Z points to first    5-digit-BCD
;            in rBin1H:L  BCD digit            Z on first,
;                                              no errors
; Bin2ToHex4 16-bit-bin   Z points to first    4-digit-hex
;            in rBin1H:L  Hex ASCII digit,     Z on first
;                         hex digits A..F      no errors
; Hex4ToBin2 4-digit-hex  Z points to first    16-bit-bin
;            Z points to  hex ASCII digit,     rBin1H:L,
;            first char   requires 4 digits,   invalid hex
;                         A..F or a..f ok      digit
; ******************* Conversion code ********************
;
; Package I: From ASCII resp. BCD to binary
;
; AscToBin2
; =========
; converts an ASCII coded number to a 2-Byte bi-
; nary
; In: Z points to first digit, conversion stops at first
;   digit detected or if overflow of the result occurs,
;   end of number must be terminated by a non-decimal
;   ASCII-digit!
; Out: Z points to first non-valid digit or to the digit
;   where the overflow occurred, if number is valid the
;   T-Flag is clear and the number is in registers
;   rBin1H:rBin1L
; Used registers: rBin1H:L (result), rBin2H:L (restored
;   after use), rmp
; Called subroutines: Bin1Mul10
;
AscToBin2:
	clr rBin1H ; Clear the result
	clr rBin1L
	clt ; Clear error flag bit
AscToBin2a:
	ld rmp,Z+ ; ignore leading blanks and zeros
	cpi rmp,' ' ; blank?
	breq AscToBin2a
	cpi rmp,'0' ; zero?
	breq AscToBin2a
AscToBin2b:
	subi rmp,'0' ; subtract ASCII zero
	brcs AscToBin2d ; End of the number
	cpi rmp,10 ; check invalid digit
	brcc AscToBin2d ; No-decimal char
	rcall Bin1Mul10 ; Multiply binary number by 10
	brts AscToBin2c ; overflow, return with T-Flag set
	add rBin1L,rmp ; add the digit to the binary
	ld rmp,Z+ ; read next char
	brcc AscToBin2b ; no overflow to binary MSB
	inc rBin1H ; Overflow to binary MSB
	brne AscToBin2b ; no overflow of binary MSB
	set ; Set overflow flag
AscToBin2c:
	sbiw ZL,1 ; Back one char, last char end/invalid
AscToBin2d:
	ret
;
; Asc5ToBin2
; ==========
; converts a 5-digit ASCII to a 16-bit-binary
; In: Z points to first decimal ASCII-digit, leading
;   blanks and zeros are ok. Requires exact 5 digits.
; Result: T-Flag reports result:
;   T=0: result in rBin1H:rBin1L, valid, Z points to
;     first digit of the hex-ASCII-number
;   T=1: error, Z points to the first illegal character
;     or to the digit, where the overflow occurred
; Used registers: rBin1H:L (result), R0 (restored after
;   use), rBin2H:L (restored after use), rmp
; Called subroutines: Bin1Mul10
;
Asc5ToBin2:
	push R0 ; R0 is used as counter, save it first
	ldi rmp,6 ; five chars, one too much
	mov R0,rmp
	clr rBin1H ; Clear result
	clr rBin1L
	clt ; Clear T-Bit
Asc5ToBin2a:
	dec R0 ; all chars read?
	breq Asc5ToBin2d ; last char
	ld rmp,Z+ ; read a char
	cpi rmp,' ' ; ignore blanks
	breq Asc5ToBin2a ; next char
	cpi rmp,'0' ; ignore leading zeros
	breq Asc5ToBin2a ; next char
Asc5ToBin2b:
	subi rmp,'0' ; treat digit
	brcs Asc5ToBin2e ; Last char was invalid
	cpi rmp,10 ; digit > 9
	brcc Asc5ToBin2e ; Last char invalid
	rcall Bin1Mul10 ; Multiply result by 10
	brts Asc5ToBin2e ; Overflow occurred
	add rBin1L,rmp ; add the digit
	ld rmp,z+
	brcc Asc5ToBin2c ; no overflow to MSB
	inc rBin1H ; Overflow to MSB
	breq Asc5ToBin2e ; Overflow of MSB
Asc5ToBin2c:
	dec R0 ; downcount number of digits
	brne Asc5ToBin2b ; convert more chars
Asc5ToBin2d: ; End of ASCII number reached ok
	sbiw ZL,5 ; Restore start position of ASCII number
	pop R0 ; Restore register R0
	ret
Asc5ToBin2e: ; Last char was invalid
	sbiw ZL,1 ; Point to invalid char
	pop R0 ; Restore register R0
	set ; Set T-Flag for error
	ret ; and return with error condition set
;
; Bcd5ToBin2
; ==========
; converts a 5-bit-BCD to a 16-bit-binary
; In: Z points to the most signifant digit of the BCD
; Out: T-flag shows general result:
;   T=0: Binary in rBin1H:L is valid, Z points to the
;     first digit of the BCD converted
;   T=1: Error during conversion. Either the BCD was too
;     big (must be 0..65535, Z points to BCD where the
;     overflow occurred) or an illegal BCD was detected
;     (Z points to the first non-BCD digit).
; Used registers: rBin1H:L (result), R0 (restored after
;   use), rBin2H:L (restored after use), rmp
; Called subroutines: Bin1Mul10
;
Bcd5ToBin2:
	push R0 ; Save register
	clr rBin1H ; Empty result
	clr rBin1L
	ldi rmp,5 ; Set counter to 5
	mov R0,rmp
	clt ; Clear error flag
Bcd5ToBin2a:
	ld rmp,Z+ ; Read BCD digit
	cpi rmp,10 ; is it valid?
	brcc Bcd5ToBin2c ; invalid BCD
	rcall Bin1Mul10 ; Multiply result by 10
	brts Bcd5ToBin2c ; Overflow occurred
	add rBin1L,rmp ; add digit
	brcc Bcd5ToBin2b ; No overflow to MSB
	inc rBin1H ; Overflow to MSB
	breq Bcd5ToBin2c ; Overflow of MSB
Bcd5ToBin2b:
	dec R0 ; another digit?
	brne Bcd5ToBin2a ; Yes
	pop R0 ; Restore register
	sbiw ZL,5 ; Set to first BCD digit
	ret ; Return
Bcd5ToBin2c:
	sbiw ZL,1 ; back one digit
	pop R0 ; Restore register
	set ; Set T-flag, error
	ret ; and return
;
; Bin1Mul10
; =========
; multiplies a 16-bit-binary by 10
; Sub used by: AscToBin2, Asc5ToBin2, Bcd5ToBin2
; In: 16-bit-binary in rBin1H:L
; Out: T-flag shows general result:
;   T=0: Valid result, 16-bit-binary in rBin1H:L ok
;   T=1: Overflow occurred, number too big
;
Bin1Mul10:
	push rBin2H ; Save the register of 16-bit-binary 2
	push rBin2L
	mov rBin2H,rBin1H ; Copy the number
	mov rBin2L,rBin1L
	add rBin1L,rBin1L ; Multiply by 2
	adc rBin1H,rBin1H
	brcs Bin1Mul10b ; overflow, get out of here
Bin1Mul10a:
	add rBin1L,rbin1L ; again multiply by 2 (4*number reached)
	adc rBin1H,rBin1H
	brcs Bin1Mul10b ; overflow, get out of here
	add rBin1L,rBin2L ; add the copied number (5*number reached)
	adc rBin1H,rBin2H
	brcs Bin1Mul10b ;overflow, get out of here
	add rBin1L,rBin1L ; again multiply by 2 (10*number reached)
	adc rBin1H,rBin1H
	brcc Bin1Mul10c ; no overflow occurred, don't set T-flag
Bin1Mul10b:
	set ; an overflow occurred during multplication
Bin1Mul10c:
	pop rBin2L ; Restore the registers of 16-bit-binary 2
	pop rBin2H
	ret
;
; *************************************************

⌨️ 快捷键说明

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