please dont rip this site


The PIC Source Book: Serin (receive data)

receives a byte or string of bytes serially at 300 to 2400 bps (4 MHz clock). Optionally filters incoming data to a particular range of ASCII characters, such as numbers.

Serin lets a PIC application receive data from another PIC or any computer equipped with an RS-232 serial port.

Before we go into the details of using Serin, let's define a term: Polarity is the sense of the serial input. Normally, a computer that sends data via RS-232 will output it to an inverting line driver. The computer will output +5 volts for 1 and 0 volts for 0. The line driver will invert this and increase the voltage swing so that +10 volts is 0 and -10 volts is 1.

When we say "true" polarity, we mean the computer output (+5V = 1). "Inverted" polarity is like the output of the line driver, but without the wide voltage swing (+5V = 0). When you want to connect the PC's serial output directly to a PIC without a line receiver, use inverted polarity and a series resistor of approximately 22k. Static-protection diodes inside the PIC will clip the input voltage to +5V and ground. The resistor will limit the current from the RS-232 line into the PIC to a safe level.

To use Serin, make the desired pin an input and set up the filter flag. With filtering on, Serin will ignore bytes that fall outside the range of ASCII values defined by filt_lo and filt_hi. In the demo program, these are set to accept only the characters representing numbers 0 through 9. You could set them to A and Z or any other contiguous range of ASCII character values. If you want numeric text converted to binary values--as shown in the next entry, Serin (convert # data)--turn filtering on, and leave t he range set for numbers. Specify the baud rate by moving one of the constants B300 through B2400 into the variable baud. Specify the sense by setting or clearing the polarity bit (0 = true, 1 = inverted). Put the number of characters you wish to receive into bytes.

Put the pin number into pin and the port number into port. Call Serin. The routine will automatically receive the specified number of bytes into a buffer at the end of memory. When Serin returns, the data will be stored starting at buffer-1 and the count (number of bytes received) will be in the location buffer.

The reason Serin records the number of bytes actually received is that it can differ from the value you requested with bytes. When the filter is on, Serin will reject bytes data outside the filter range. When it receives the first byte that meets the filter requirements, it sets a flag called filt_1st. Once this flag is set, Serin will continue to accept bytes until it either receives the number specified by bytes, or a character outside the filter range arrives. This allows Serin to receive variable-length numbers and reject text.

To receive a 16-bit number, you would turn on the filter and put 5 in bytes. Serin would receive from 1 to 5 characters representing numbers from 0 to 65535. Input values must not contain commas; 65,535 would be received as "65".

When the filter is off, the buffer will contain exactly the number of bytes you specified. Serin can receive serial data through any pin of any I/O port, and can change port and pin assignments while the program is running. In many applications, it's enough to assign one pin for serial input and leave it at that. The disk that accompanies this book contains stripped versions of Serin for such applications. The advantage is that these use much less program memory than the routine listed here. Check the files SERIN_2.SRC and SERIN_3.SRC on the accompanying disk.

Serin, like the other routines that accept pin and port arguments, requires the short table Pinz. Remember that tables and subroutines must be located in the first 256 words of a 512-word program memory page.

Demonstrating Serin.

To see Serin in operation, connect the circuit below to an erasable PIC or PIC emulator, such as the Parallax downloader. Assemble and run SERIN.SRC. 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). Type a few characters and watch the LEDs display the binary equivalents of the received data. To check out the filtering capability, modify the program to set the filter bit, then reassemble and rerun it. Now the LEDs will respond only when you press the number keys 0 through 9.


;
; ***************************************************************************
; ***  Bubble Software Parallax to PIC Source Converter. Copyright 1999.  ***
; ***  http://www.bubblesoftonline.com                 email: sales@picnpoke.com  ***
; ***************************************************************************
;
; SERIN port, pin, baud, polarity, bytes, filter
; Receives data serially at the specified rate and polarity via the specified 
; port pin. Stores the data as a counted string starting at buffer-1 (buffer is 
; the number of bytes in the string). An optional filter causes the routine to
; ignore data outside a range of ASCII character values set by filt_lo and 
; filt_hi. 

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

buffer 	equ 	d'31' 	; String storage. 
B2400	equ 	d'30' 	; Bit delay for 2400 baud. 
B1200	equ 	d'62' 	; Bit delay for 1200 baud. 
B600	equ 	d'126'	; Bit delay for 600 baud. 
B300	equ 	d'255'	; Bit delay for 300 baud. 
filt_lo	equ 	'0'	; Set filter for ASCII 
filt_hi	equ 	'9'	; chars representing 0-9. 

 org 8
baud	Res 	d'1' 	; Baud rate. 
pin	Res 	d'1' 	; Pin number (0-7).
port	Res 	d'1' 	; Port number (0-2).
bytes	Res 	d'1' 	; Number of bytes to receive. 
temp1	Res 	d'1' 	; Temporary counter for Serin.
temp2	Res 	d'1' 	; Temporary counter for Serin. 
temp3	Res 	d'1' 	; Temporary counter for delay.
ser_fl	Res 	d'1' 	; Flags for serin switches. 

polarity equ	ser_fl.0	; Polser_fl.0arity: 0=true, 1=inverted. 
filter	equ  	ser_fl.1	; Ranser_fl.1ge filter: 0=off, 1=on. 
filt_1st equ  	ser_fl.2	; 1stser_fl.2 filter byte passed?: 0=no, 1=yes. 
aux  	equ	ser_fl.3	; Temser_fl.3porary flag for filter comparisons. 

; Device data and reset vector
 org 0
; Table to convert pin number (0-7) into bit mask (00000001b to 10000000b). 
Pinz         ADDWF pcl                  
             RETLW d'1'                 
             RETLW d'2'
             RETLW d'4'
             RETLW d'8'
             RETLW d'16'
             RETLW d'32'
             RETLW d'64'
             RETLW d'128'
; Subroutine used by Serin to get a bit and delay for a number of loops
; set by temp3. Jumping into get_bit:loop provides the delay, but ignores the 
; input bit. 
get_bit      MOVF port,w                ; Point to port. 
             MOVWF fsr
             MOVF indirect,w            ; IF Polarity = 0 THEN w = Port 
             BTFSC ser_fl,d'0'          ; ELSE w = NOT Port
             COMF indirect,w            
             ANDWF pin,w                
             BTFSC status,z             ; IF w AND pin THEN carry = 1
             BCF status,c               ; ELSE carry = 0. 
             BTFSS status,z             
             BSF status,c               
             MOVF temp1,w               ; Point to buffer location. 
             MOVWF fsr
             RRF indirect               ; Rotate carry into msb of data byte.
get_bit_loop GOTO $+1                   ; Two-cycle nops. 
             GOTO $+1                   
             GOTO $+1                   
             GOTO $+1                   
             GOTO $+1                   
             DECFSZ temp3               
             GOTO get_bit_loop
             RETLW 0h                   

; Main program start. Receives a single byte of data, filtered for numeric 
; characters, and displays the data bits on LEDs connected to port RB. 
start        MOVLW d'15'                ; All inputs. 
             TRIS 5h
             MOVLW d'0'                 ; All outputs for LEDs.
             TRIS 6h
             CLRF 7h                    ; Clear the LEDs. 
             CLRF ser_fl                ; Clear serial flags.
             MOVLW d'1'                 ; Receive 1 byte 
             MOVWF bytes
             BCF ser_fl,d'1'            ; not filtered 
             BSF ser_fl,d'0'            ; inverted polarity
             MOVLW B2400                ; at 2400 baud 
             MOVWF baud
             MOVLW d'2'                 ; via pin 2 
             MOVWF pin
             MOVLW d'0'                 ; of port ra. 
             MOVWF port
             CALL Serin                 ; Receive the data. 
             MOVF buffer-1,w            ; Move byte to LEDs on RB. 
             MOVWF 6h
             GOTO start                 ; Endless loop

; Body of the Serin routine. Expects the baud constant in baud, number of
; bytes to receive in bytes, the I/O port (0-2 for RA through RC) in port, 
; the pin number (0-7) in pin, and the flag settings in ser_fl 
Serin        CLRF buffer                ; Clear buffer counter. 
             BCF ser_fl,d'2'            
             MOVLW 5h                   ; Add offset for port RA.
             ADDWF port
             MOVF pin,w                 
             CALL Pinz                  ; Get bit mask from the table. 
             MOVWF pin                  ; Put the mask into pin. 
             MOVLW buffer-1             ; Pointer for first data address. 
             MOVWF temp1
Serin_poll   MOVF port,w                
             MOVWF fsr
             MOVF indirect,w            ; IF Polarity = 0 THEN w = Port 
             BTFSC ser_fl,d'0'          ; ELSE w = NOT Port
             COMF indirect,w            
             ANDWF pin,w                ; IF pin = 0 THEN receive data
             BTFSS status,z             ; ELSE poll
             GOTO Serin_poll
             BCF status,c               
             RRF baud,w                 ; LET temp3 = baud/2
             MOVWF temp3                ; Set up 1/2 bit time delay. 
             CALL get_bit_loop          ; Jump into delay of get_bit.
             MOVF baud,w                ; Set up full bit time delay. 
             MOVWF temp3
             CALL get_bit_loop          ; Jump into delay of get_bit.
             MOVLW d'8'                 ; Eight data bits.      
             MOVWF temp2
Serin_rcv    MOVF baud,w                ; Set up bit delay.
             MOVWF temp3
             CALL get_bit               ; Get the next data bit.
             DECFSZ temp2               ; Eight bits received?
             GOTO Serin_rcv
Serin_done   MOVF baud,w                ; Set up bit delay.
             MOVWF temp3
             CALL get_bit_loop          ; Wait for stop bit.
             BTFSS ser_fl,d'1'          ; IF filter=0 (off) THEN :skip
             GOTO Serin_skip
             BCF ser_fl,d'3'            ; LET aux = 0. 
             MOVLW filt_lo              ; IF byte < filt_lo THEN aux=1
             SUBWF indirect,w
             BTFSS status,c
             BSF ser_fl,d'3'            
             MOVLW ~filt_hi             ; IF byte > filt_hi THEN aux=1
             ADDWF indirect,w
             BTFSC status,c
             BSF ser_fl,d'3'            
             BTFSS ser_fl,d'3'          ; If aux = 0 (byte is within 
             GOTO Serin_skip
             BTFSC ser_fl,d'2'          ; filter range) :skip. If byte is
             RETLW 0h                   ; out of range, but valid bytes have 
             GOTO Serin_poll            ; been received, return. Else poll. 
Serin_skip   BSF ser_fl,d'2'            
             DECF temp1                 ; Decrement buffer pointer. 
             INCF buffer                ; Increment buffer counter. 
             DECFSZ bytes               ; More bytes to receive: poll.
             GOTO Serin_poll
             RETLW 0h                   



; SERIN port, pin, baud, polarity, bytes, filter ; Receives data serially at the specified rate and polarity via the specified ; port pin. Stores the data as a counted string starting at buffer-1 (buffer is ; the number of bytes in the string). An optional filter causes the routine to ; ignore data outside a range of ASCII character values set by filt_lo and ; filt_hi. buffer = 31 ; String storage. B2400 = 30 ; Bit delay for 2400 baud. B1200 = 62 ; Bit delay for 1200 baud. B600 = 126 ; Bit delay for 600 baud. B300 = 255 ; Bit delay for 300 baud. filt_lo = '0' ; Set filter for ASCII filt_hi = '9' ; chars representing 0-9. org 8 baud ds 1 ; Baud rate. pin ds 1 ; Pin number (0-7). port ds 1 ; Port number (0-2). bytes ds 1 ; Number of bytes to receive. temp1 ds 1 ; Temporary counter for Serin. temp2 ds 1 ; Temporary counter for Serin. temp3 ds 1 ; Temporary counter for delay. ser_fl ds 1 ; Flags for serin switches. polarity = ser_fl.0 ; Polarity: 0=true, 1=inverted. filter = ser_fl.1 ; Range filter: 0=off, 1=on. filt_1st = ser_fl.2 ; 1st filter byte passed?: 0=no, 1=yes. aux = ser_fl.3 ; Temporary flag for filter comparisons. ; Device data and reset vector device pic16c55,xt_osc,wdt_off,protect_off reset start org 0 ; Table to convert pin number (0-7) into bit mask (00000001b to 10000000b). Pinz jmp pc+w retw 1,2,4,8,16,32,64,128 ; Subroutine used by Serin to get a bit and delay for a number of loops ; set by temp3. Jumping into get_bit:loop provides the delay, but ignores the ; input bit. get_bit mov fsr,port ; Point to port. mov w,indirect ; IF Polarity = 0 THEN w = Port snb Polarity ; ELSE w = NOT Port mov w,/indirect AND w,pin snz ; IF w AND pin THEN carry = 1 clc ; ELSE carry = 0. sz stc mov fsr,temp1 ; Point to buffer location. rr indirect ; Rotate carry into msb of data byte. :loop jmp $+1 ; Two-cycle nops. jmp $+1 jmp $+1 jmp $+1 jmp $+1 djnz temp3,:loop ret ; Main program start. Receives a single byte of data, filtered for numeric ; characters, and displays the data bits on LEDs connected to port RB. start mov !ra, #15 ; All inputs. mov !rb,#0 ; All outputs for LEDs. clr rc ; Clear the LEDs. clr ser_fl ; Clear serial flags. mov bytes,#1 ; Receive 1 byte clrb filter ; not filtered setb polarity ; inverted polarity mov baud,#B2400 ; at 2400 baud mov pin,#2 ; via pin 2 mov port,#0 ; of port ra. call Serin ; Receive the data. mov rb,buffer-1 ; Move byte to LEDs on RB. jmp start ; Endless loop ; Body of the Serin routine. Expects the baud constant in baud, number of ; bytes to receive in bytes, the I/O port (0-2 for RA through RC) in port, ; the pin number (0-7) in pin, and the flag settings in ser_fl Serin clr buffer ; Clear buffer counter. clrb filt_1st ADD port,#RA ; Add offset for port RA. mov w,pin call Pinz ; Get bit mask from the table. mov pin,w ; Put the mask into pin. mov temp1,#buffer-1 ; Pointer for first data address. :poll mov fsr,port mov w,indirect ; IF Polarity = 0 THEN w = Port snb Polarity ; ELSE w = NOT Port mov w,/indirect AND w,pin ; IF pin = 0 THEN receive data jnz :poll ; ELSE poll clc mov w,>>baud ; LET temp3 = baud/2 mov temp3,w ; Set up 1/2 bit time delay. call get_bit:loop ; Jump into delay of get_bit. mov temp3,baud ; Set up full bit time delay. call get_bit:loop ; Jump into delay of get_bit. mov temp2,#8 ; Eight data bits. :rcv mov temp3,baud ; Set up bit delay. call get_bit ; Get the next data bit. djnz temp2,:rcv ; Eight bits received? :done mov temp3,baud ; Set up bit delay. call get_bit:loop ; Wait for stop bit. jnb filter,:skip ; IF filter=0 (off) THEN :skip clrb aux ; LET aux = 0. csae indirect,#filt_lo ; IF byte < filt_lo THEN aux=1 setb aux csbe indirect,#filt_hi ; IF byte > filt_hi THEN aux=1 setb aux jnb aux,:skip ; If aux = 0 (byte is within snb filt_1st ; filter range) :skip. If byte is ret ; out of range, but valid bytes have jmp :poll ; been received, return. Else poll. :skip setb filt_1st dec temp1 ; Decrement buffer pointer. inc buffer ; Increment buffer counter. djnz bytes,:poll ; More bytes to receive: poll. ret

See also:


file: /Techref/microchip/seepicsrc/psbpix/serin1.htm, 16KB, , updated: 2014/12/3 11:10, local time: 2024/11/1 03:37,
TOP NEW HELP FIND: 
18.226.185.231:LOG IN
©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://linistepper.com/techref/microchip/seepicsrc/psbpix/serin1.htm"> The PIC Source Book: Serin (receive serial data)</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?