Serin (convert # data)

converts a numeric text string received by Serin into a 16-bit number.

PBASIC's Serin can automatically convert incoming text to numbers. This means that a user can type a number like "5280" from the keyboard of a PC or terminal, and Serin will interpret the received string as the 16-bit number 5280 (14A0h).

Using the assembly version of Serin, you can do the same thing. Set up Serin to receive five bytes (for the five digits of a 16-bit number) and set the filter bit. Make sure that the filter range, determined by equates at the beginning of the Serin listing, is set up for ASCII '0' through '9'.

Serin will ignore data other than numbers. Once it begins receiving numeric text, it will store up to five digits in its string buffer. Once five digits are collected or the numeric string is ended by a non-numeric character, Serin will return.

An example will help clarify this. Suppose Serin is called with the filter on and a request for five bytes. The following stream of data arrives:

1st	2nd	3rd	4th	5th	6th	7th	8th	9th
Q	(	5	2	0	)	(	&np;	9	1

Serin rejects the first and second bytes. It recognizes the third through fifth bytes as numbers and stores them in the string. It now has storage remaining for two more numeric bytes. However, the sixth byte is not a number, so Serin stops listening and returns with the three-byte string "520" in the buffer. If it didn't stop, it could skip the parentheses and combine "520" with "91" to produce "52091". That is clearly not the right answer.

Serin will also reject mathematical punctuation, like the minus sign, comma, and decimal point. People or programs sending data for use by Serin must not use these marks in their entries.

Once Serin has stored the data, a call to ASC_BIN converts it to a 16-bit number. If there is no data in the string (the first entry containing the number of bytes is 0), the routine returns with 1 in w to signal the error. Otherwise, it returns the binary equivalent of the text string in the 16-bit variable n1 and a 0 in w. ASC_BIN decrements the string counter to 0, so if the string is to be reused, your program should copy this value and rewrite it after ASC_BIN is done.

Demonstrating ASC_BIN.

To see ASC_BIN in operation, you may run it on the PSIM simulator as suggested in the program listing. For a live demonstration, connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Program the PIC or downloader with the program assembled from the file SERIN_#.SRC on the accompanying disk. Make sure to use a 4-MHz clock on the PIC or downloader. Load a terminal program on the PC connected to the PIC and set it for 2400 baud, no parity , 8 data bits, 1 stop bit (N81). Now type in some numbers and text and watch the LEDs interpret the data as described on the previous page.


;
; ***************************************************************************
; ***  Bubble Software Parallax to PIC Source Converter. Copyright 1999.  ***
; ***  http://www.bubblesoftonline.com                 email: sales@picnpoke.com  ***
; ***************************************************************************
;
; ASC_BIN numeric string
; This program converts a counted string of ASCII characters
; received by Serin into a 16-bit value in the variable n1.

	P = pic16c55
	#include <16c55.inc>   ; processor assembler definitions
	_CONFIG _xt_osc & _wdt_off & _protect_off
 reset start

buffer 	equ 	d'31' 	; String buffer at end of memory
ASC_0 	equ  	'0'	; ASCII chars for nos. are 30h thru 39h.

 org 8
dec_no 	Res 	d'1' 	; Decade (1,10,100...) to work on.
n1H 	Res 	d'1' 	; MSB of converted number.
n1L 	Res 	d'1' 	; LSB of converted number.
n2H 	Res 	d'1' 	; MSB of 16-bit temp variable.
n2L 	Res 	d'1' 	; LSB of 16-bit temp variable.
temp	Res 	d'1' 	; Temporary storage

; Device data and reset vector
 org 0

decade       ADDWF pcl                  
             RETLW d'39'                
             RETLW d'16'
             RETLW d'3'
             RETLW d'232'
             RETLW d'0'
             RETLW d'100'
             RETLW d'0'
             RETLW d'10'
             RETLW d'0'
             RETLW d'1'

start        MOVLW d'0'                 ; Set ports to output.
             TRIS 6h
             MOVLW d'0'                 
             TRIS 7h
             MOVLW d'5'                 ; String count.
             MOVWF buffer
             MOVLW 0x36                 ; Numeric text: "65535."
             MOVWF buffer-1
             MOVLW 0x35                 ; To view the results of the
             MOVWF buffer-2
             MOVLW 0x35                 ; conversion, run this program
             MOVWF buffer-3
             MOVLW 0x33                 ; on the PSIM simulator, or merge
             MOVWF buffer-4
             MOVLW 0x35                 ; it with Serin.
             MOVWF buffer-5
             CALL ASC_BIN               
             MOVF n1L,w                 ; Show result on LEDs.
             MOVWF 6h
             MOVF n1H,w                 
             MOVWF 7h
             GOTO $                     ; Endless loop.

; ASC_BIN gets the value of each digit (0-9) of a numeric string. Depending
; on the number of digits in the string, it looks up the multiplier (10000, 1000,100,10, or 1) and adds that multiplier to n1 digit number of times.
ASC_BIN      CLRF n1H                   ; n1 = 0
             CLRF n1L                   
             MOVLW buffer-1             ; If the string is empty,
             MOVWF fsr
             MOVF buffer                ; return 0 in 16-bit answer
             BTFSS status,z             ; and error code (1) in
             GOTO ASC_BIN_loop
             RETLW d'1'                 ; w. Else, do the conversion.
ASC_BIN_loop MOVLW ASC_0                ; w = 30h (ASCII start point).
              subwf indirect,0          ; w = character_value-30h. <Microchip instruction>
             BTFSC status,z             
             GOTO ASC_BIN_next
             MOVWF temp                 ; temp = w
             MOVLW d'5'                 
             MOVWF dec_no
             MOVF buffer,w              ; dec_no = 5-string_length
             SUBWF dec_no
             BCF status,c               
             RLF dec_no                 ; dec_no = dec_no*2
             MOVF dec_no,w              
             CALL decade                ; Look up MSB of multiplier.
             MOVWF n2H                  ; Store it in MSB of n2.
             INCF dec_no,w              ; Look up the LSB of multiplier.
             CALL decade                
             MOVWF n2L                  ; Store it in LSB of n2.
ASC_BIN_add_it  CALL Add16              ; n1 = n1 + n2.
             DECFSZ temp                ; Repeat 1 to 9 times for each digit.
             GOTO ASC_BIN_add_it
ASC_BIN_next DECF fsr                   ; Get the next byte of the string.
             DECF buffer                ; Adjust string counter.
             BTFSS status,z             ; Any bytes left? Yes: loop.
             GOTO ASC_BIN_loop
             RETLW 0h                   ; No: return.
Add16        MOVF n2L,w                 ; Add the LSBs. If carry,
             ADDWF n1L
             BTFSC status,c             ; increment MSB of sum.
             INCF n1H                   
             MOVF n2H,w                 ; Add the MSBs.
             ADDWF n1H
             RETLW 0h                   

             
             
             end



; ASC_BIN numeric string
; This program converts a counted string of ASCII characters
; received by Serin into a 16-bit value in the variable n1.

buffer	=	31	; String buffer at end of memory
ASC_0	=	'0'	; ASCII chars for nos. are 30h thru 39h.

	org	8
dec_no	ds	1	; Decade (1,10,100...) to work on.
n1H	ds	1	; MSB of converted number.
n1L	ds	1	; LSB of converted number.
n2H	ds	1	; MSB of 16-bit temp variable.
n2L	ds	1	; LSB of 16-bit temp variable.
temp	ds	1	; Temporary storage

; Device data and reset vector
	device	pic16c55,xt_osc,wdt_off,protect_off
	reset	start
	org	0

decade	jmp	pc+w
	retw	39,16,3,232,0,100,0,10,0,1

start	mov	!rb,#0	; Set ports to output.
	mov	!rc,#0
	mov	buffer,#5	; String count.
	mov	buffer-1,#36h	; Numeric text: "65535."
	mov	buffer-2,#35h	; To view the results of the
	mov	buffer-3,#35h	; conversion, run this program
	mov	buffer-4,#33h	; on the PSIM simulator, or merge
	mov	buffer-5,#35h	; it with Serin.
	call	ASC_BIN
	mov	rb,n1L	; Show result on LEDs.
	mov	rc,n1H
	jmp	$	; Endless loop.

; ASC_BIN gets the value of each digit (0-9) of a numeric string. Depending
; on the number of digits in the string, it looks up the multiplier (10000, 1000,100,10, or 1) and adds that multiplier to n1 digit number of times.
ASC_BIN clr	n1H	; n1 = 0
	clr	n1L
	mov	fsr,#buffer-1	; If the string is empty,
	test	buffer	; return 0 in 16-bit answer
	jnz	:loop	; and error code (1) in
	retw	1	; w. Else, do the conversion.
:loop	mov	w,#ASC_0	; w = 30h (ASCII start point).
	sub	indirect,w	; w = character_value-30h.
	jz	:next
	mov	temp,w	; temp = w
	mov	dec_no,#5
	sub	dec_no,buffer	; dec_no = 5-string_length
	clc
	rl	dec_no	; dec_no = dec_no*2
	mov	w,dec_no
	call	decade	; Look up MSB of multiplier.
	mov	n2H,w	; Store it in MSB of n2.
	mov	w,++dec_no	; Look up the LSB of multiplier.
	call	decade
	mov	n2L,w	; Store it in LSB of n2.
:add_it call	Add16	; n1 = n1 + n2.
	djnz	temp,:add_it	; Repeat 1 to 9 times for each digit.
:next	dec	fsr	; Get the next byte of the string.
	dec	buffer	; Adjust string counter.
	jnz	:loop	; Any bytes left? Yes: loop.
	ret	; No: return.
Add16	ADD	n1L,n2L ; Add the LSBs. If carry,
	snc	; increment MSB of sum.
	inc	n1H
	ADD	n1H,n2H ; Add the MSBs.
	ret

See also:

Questions: