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.
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 10:10, local time: 2024/12/25 08:34,
3.137.219.213:LOG IN
|
©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? <A HREF="http://techref.massmind.org/techref/microchip/seepicsrc/psbpix/serin1.htm"> The PIC Source Book: Serin (receive serial data)</A> |
Did you find what you needed? |
Welcome to massmind.org! |
Welcome to techref.massmind.org! |
.