|
|
|
|
EE Design > In Technical
Title: Implementing software RS-232 serial communication in PIC Microcontrollers Author: Vincent Wong Date: 29th March 2005 Below shows the subroutines for RS-232 interface using software. This is very usefull if the hardware version is not available or additional serial ports are required in a system which is usually limited to 1 serial port. We first define the I/Os to funtion as RxD and TxD. #DEFINE SER_OUT PORTA,0 ;DATA TO BE SEND TO RS232 CONVERTER #DEFINE SER_IN PORTA,2 ;DATA READ FROM IRC-80S Here we define the clock and baudrate of the system. I have tested it to work properly with 9600 Bps and with lower baudrate. CLKRATE EQU .4000000 ; 4 MHZ CLOCK RATE BDRATE EQU .9600 ; 9600 BAUD FCLK EQU CLKRATE/4 BAUDFIG EQU ((FCLK/BDRATE)/3-2) ;MUST BE A 8 BIT VALUE BAUD2 EQU BAUDFIG/2 ;HALF BIT TIME This is the receive data subroutine. The program will wait and when a valid data is received, the read data will be returned to the working register. GET_RS232: MOVLW BAUD2 ;SET UP HALF BIT DELAY MOVWF DELTMP MOVLW .9 ;SET UP BIT COUNTER MOVWF COUNT GETRXL: BTFSC SER_IN ;WATCH FOR LOW ON RX LINE, START BIT GOTO GETRXL HALFBT: DECFSZ DELTMP,F ;MOVE OUT 1/2 BIT TIME GOTO HALFBT MOVLW BAUDFIG ;SET UP FULL BIT DELAY MOVWF DELTMP RXWAIT: DECFSZ DELTMP,F ;LETS WAIT FOR THIS BIT TO PASS BY GOTO RXWAIT MOVLW BAUDFIG ;SET UP BIT DELAY AGAIN MOVWF DELTMP DECFSZ COUNT,F ;ARE ALL BITS IN YET? GOTO RXGO MOVF REC_DATA,W ;PUT RESULT INTO W RETURN ;WE DON'T WAIT FOR STOP BITS, NO REASON TO RXGO: BCF STATUS,C ;CLEAR THE CARRY BIT ALWAYS BTFSC SER_IN ;SKIP IF RX IS LOW BSF STATUS,C ;SET THE CARRY IF RX WAS HIGH RRF REC_DATA,F ;SHIFT C >>>> INTO OUR HOLDING REG GOTO RXWAIT ;GO DO THE NEXT BIT ;WE SENSE THE BIT'S STATE IN THE ;MIDDLE OF A BIT TIME. THAT'S WHY ;WE DID THE HALF BIT TIME DELAY. This is the send out data subroutine. The program read the data to be send from the working register the send out to the defined RxD pin at the appropriate baudrate. SEND_RS232: BCF STATUS,RP0 MOVWF RS232_CHR ;STORE OUR DATA BYTE WAS IN W BCF SER_OUT ;TX = LOW, START BIT HERE MOVLW BAUDFIG ;SET UP OUR DELAY MOVWF DELTMP MOVLW .9 ;SET UP BIT COUNTER MOVWF COUNT TXWAIT: DECFSZ DELTMP,F GOTO TXWAIT ;WAIT FOR BIT TIME TO END MOVLW BAUDFIG ;SET UP BIT DELAY AGAIN MOVWF DELTMP DECFSZ COUNT,F ;SEE IF WE ARE DONE YET GOTO NEXTBIT BSF SER_OUT ;TX = HIGH - 2 STOP BITS TXWAIT1:DECFSZ DELTMP,F GOTO TXWAIT1 ;WAIT FOR BIT TIME TO END MOVLW BAUDFIG ;SET UP BIT DELAY AGAIN MOVWF DELTMP TXWAIT2:DECFSZ DELTMP,F GOTO TXWAIT2 ;WAIT FOR BIT TIME TO END BSF SER_OUT ;TX = HIGH RETURN NEXTBIT:RRF RS232_CHR,F ;SHIFT IT >>>> TO C BTFSS STATUS,C ;SKIP IF C = HIGH GOTO SETLO BSF SER_OUT ;TX = HIGH GOTO TXWAIT SETLO: BCF SER_OUT ;TX = LOW GOTO TXWAIT |