DonTronics Home Page

Top | Bottom
Go Back | Go Forward

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       )       (    &nsp;  &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.picnpoke.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:
http://www.piclist.com/techref/microchip/rs232.htm
http://www.piclist.com/techref/microchip/math/radix/index.htm
 
 

DonTronics Home Page
Top | Bottom
Go Back | Go Forward