; ; *************************************************************************** ; *** Bubble Software Parallax to PIC Source Converter. Copyright 1999. *** ; *** http://www.picnpoke.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 ; Polser_fl.0arity: 0=true, 1=inverted. filter equ ; Ranser_fl.1ge filter: 0=off, 1=on. filt_1st equ ; 1stser_fl.2 filter byte passed?: 0=no, 1=yes. aux equ ; 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 end