;****************************************** ;*** SOFTWARE UART FOR '84 ************* ;*** by Gordon MacNee ************* ;****************************************** ; WDOG ON 4MHz XTAL ;****************************************** ;THIS ROUTINE IS DESIGNED TO DEMONSTARTE THAT WE DO ;NOT NEED A HARDWARE UART TO RUN A RS232 COMMS CHANNEL ;WE COULD MODIFY THE CODE TO WAIT FOR AN INTERRUPT SIGNALLING ;ACTIVITY ON THE RECEIVE CHANNEL AND RUN THE TRANSMIT ROUTINE ;WITHOUT INTERRUPTS - WE WILL ONLY BE ABLE TO TRANSMIT OR RECEIVE ;WE WILL NOT BE ABLE TO TX AND RX AT THE SAME TIME ;IN PRACTICE THIS DOES NOT ;LIMIT THE USEFULNESS OF THIS ROUTINE ;THIS SOFTWARE IS BASED ON APPLICATION NOTE AN510 ;TO RUN AT 9600 BAUD THE TIME BETWEEN BITS IS 104uS ;SO WE NEED A TX LOOP THAT TAKES 104uS PER BIT AND ;AN RX LOOP THAT SAMPLES THE DATA HALF WAY THROUGH ;THE 104uS BIT LENGTH LIST P=16F84,F=INHX8M INADD EQU 00 ;INDIRECT POINTER RTCC EQU 01 ;RTCC REG OPT EQU 81H ;OPTION REG PCL EQU 02 ;PROGRAM COUNTER LOW BYTE STATUS EQU 03 ;STATUS REG ;STATUS REG FLAGS #DEFINE C STATUS,00 ;CARRY FLAG #DEFINE Z STATUS,02 ;ZERO FLAG RP0 EQU 05 ;REG PAGE SELECT FSR EQU 04 ;FILE SELECT REG PORTA EQU 05H ;PORT A (F5) TRISA EQU 85H PORTB EQU 06H ;PORT B (F6) TRISB EQU 86H ;BIT DEFS #DEFINE RX PORTB,0 ;SO WE CAN RUN RX ON INTERRUPT #DEFINE TX PORTB,1 PCLATH EQU 0AH ;UPPER BITS OF ADDRESS POINTER INTCON EQU 0BH ;INTERRUPT CONTROL REG ;BIT DEFS GIE EQU 07H ;GLOBAL INT ENABLE BIT PEIE EQU 06H ;PERIPHERAL INT ENABLE BIT ;GENERAL EQUATES W_STORE EQU 20H ;IN BOTH PAGES STAT_STORE EQU 21H ;PAGE 0 ONLY TXREG EQU 22H ;TX DATA REG RCREG EQU 23H ;RX DATA REG BIT_COUNT EQU 24H ;BIT COUNTER COUNT EQU 25H ;USED IN DELAY ROUTINES TEMP_REG EQU 26H ORG 000 ;RESET VECTOR GOTO CLDSTT ;COLDSTART VECTOR ;THIS IS THE INTERRUPT VECTOR ORG 04H ;INTERRUPT VECTOR ;THIS ROUTINE WILL STORE THEN RESTORE THE W REG ;AND STATUS REG - THIS IS A GENERAL BLOCK OF CODE ;AND CAN BE INCLUDED IN ANY BLOCK OF CODE THAT ;MAY USE INTERRUPTS ;NOTE THAT WE SHOULD ALSO STORE PCLATCH REG ;IF WE EXCEED THE 2K PROGRAMME SPACE BOUNDERY INT_ROUTINE ;STORE W AND STATUS MOVWF W_STORE MOVFW STATUS BCF STATUS,RP0 ;MOVE TO PAGE 0 MOVWF STAT_STORE ;TEST HERE TO SEE WHICH INTERRUPT SOURCE NEEDS SERVICING INT_RET MOVFW STAT_STORE MOVWF STATUS SWAPF W_STORE SWAPF W_STORE,W RETFIE ;*********************************** ;*** SUBROUTINES **** ;*********************************** DELAY_52 MOVLW .13 GOTO D0 DELAY_96 ;96uS DELAY MOVLW .30 D0 MOVWF COUNT D1 DECFSZ COUNT GOTO D1 NOP RETURN ;8 BITS NO PARITY ONE STOP BIT TX_LOOP ;ENTER ROUTINE WITH DATA TO TX LOADED INTO XMTREG ;DISABLE INTERRUPTS WHEN RUNNING THIS ROUTINE TO PRESERVE TIMING MOVLW 08H ;NUMBER OF BITS TO TX MOVWF BIT_COUNT BCF TX ;START BIT GOTO $ + 1 GOTO $ + 1 NOP TX1 CALL DELAY_96 ;1 BIT LENGTH RRF TXREG ;ROT LEFT FOR MSB FIRST BTFSC C BSF TX ;DATA IS A ONE BTFSS C BCF TX ;DATA IS A ZERO DECFSZ BIT_COUNT GOTO TX1 ;GET NEXT BIT CALL DELAY_96 MOVLW 01 CALL D0 BSF TX ;STOP BIT CALL DELAY_96 RETURN RX_LOOP BTFSC RX ;TEST FOR START BIT GOTO RX_LOOP ;INT_RET MOVLW 08H ;NUMBER OF BITS MOVWF BIT_COUNT CLRF RCREG CALL DELAY_96 ;TO END OF START BIT RX1 CALL DELAY_52 ;1/2 BIT DELAY GOTO $ + 1 NOP BCF C ;PRECLEAR CARRY FLAG RRF RCREG BTFSC RX ;SKIP IF DATA = 0 BSF RCREG,7 CALL DELAY_52 ;1/2 BIT DELAY DECFSZ BIT_COUNT GOTO RX1 ;IF WE GET HERE THEN WE ARE FINISHED RETURN ;********************************** ;*** START OF MAIN CODE *** ;********************************** CLDSTT ;TEST FOR TO OR PD HERE IF REQUIRED CLRWDT CONFIG_IO ;USE THIS ROUTINE TO SETUP I/O BCF STATUS,RP0 MOVLW B'00000011' MOVWF PORTB BSF STATUS,RP0 MOVLW B'00000001' MOVWF TRISB BCF STATUS,RP0 TEST1 CALL RX_LOOP CALL DELAY_96 MOVFW RCREG MOVWF TXREG CALL TX_LOOP GOTO TEST1 END