; NoIntSer - Macro Definitions for Simple NRZ Serial Routines ; ; NRZSerialInit Speed, Rate, Polarity, TXPort, TXPin, RXPort, RXPin, TimeOut ; - Initialize the Serial Output Port ; - Save the Serial Parameters ; Where: ; Speed - Processor Execution Speed ; Rate - Data Rate ; Polarity - "1" for Positive, "-1" for Negative ; TXPort, TXPin - Port, Pin for Data Transmit ; RXPort, RXPin - Port, Pin for Data Receive ; TimeOut - Receive TimeOut in msecs. If "0" then Skip ; NRZSend - Send the Value in "w" out ; NRZReceive - Wait for a character to come in. If Carry set, then ; wait timed out. ; ; NRZSerialRoutines ; - This Defines "NRZSend" and "NRZReceive" which pass a byte (in "w") to ; and from the Mainline ; NRZSend - Send the Value in "w" out ; NRZReceive - Wait for a character to come in. If Carry set, then ; wait timed out. ; ; The code Produced by this Macro will work in Low-End and Mid-Range PICMicros. ; ; Dependencies: ; Vars.inc - Myke Predko's Variable Declaration Macro ; ; Myke Predko ; 99.06.25 ; NRZSerialInit macro Speed, Rate, Polarity, TXPort, TXPin, RXPort, RXPin, TimeOut variable NRZSpeed, NRZRate, NRZPolarity, NRZTimeOut variable NRZTXPort, NRZTXPin, NRZRXPort, NRZRXPin ERRORLEVEL 1,-224 #define NRZSerialInitializied NRZSpeed = Speed NRZRate = Rate NRZPolarity = Polarity NRZTimeOut = TimeOut NRZTXPort = TXPort NRZTXPin = TXPin NRZRXPort = RXPort NRZRXPin = RXPin VarAdd NRZDlay, 1 VarAdd NRZCount, 1 VarAdd NRZByte, 1 VarAdd TXOutputPort, 1 movlw 0x0FF ^ (1 << NRZTXPin) ; Define the Output Port movwf TXOutputPort TRIS NRZTXPort endm NRZSerialRoutines macro ifndef NRZSerialInitializied error "Serial I/O Port Declarations Not Made" endif ; This Macro provides "NRZSend" and "NRZReceive" Subroutines. ; The Data Format is 8-N-1 ; These subroutines cannot be used concurrently. ; "NRZReceive" Returns with Carry Set When Timeout is Exhausted ; When Data Received, "NRZReceive" returns with Carry Reset ; when Data fully Received. NRZSend ; Send Data to Out variable HiDlay, LoDlay ; Delay Values for Tx Loop variable TXExpected, TXActual; Test Values for TX for Errors variable TXError ; Percent Difference Between E/A TXExpected = ((NRZSpeed / NRZRate) / 4) - 19 HiDlay = (TXExpected / (7 * 256)) + 1 LoDlay = ((TXExpected - (7 * 256 * (HiDlay - 1))) / 7) + 1 TXActual = ((LoDlay - 1) * 7) + ((HiDlay - 1) * 7 * 256) if (TXActual > TXExpected ) ; Actual is Greater than Expected TXError = (((TXActual - TXExpected) * 100) / TXExpected) else TXError = (((TXExpected - TXActual) * 100) / TXExpected) endif if (TXError > 2) error "Transmit Bit Error Rate is Greater than 2%" endif movwf NRZByte movlw 10 ; Sending 10 Bits movwf NRZCount if (NRZPolarity < 0) ; Negative Polarity? comf Byte bsf STATUS, C ; Start Bit else bcf STATUS, C endif ; NRZSendLoop movf NRZTXPort, w ; Set/Reset Bit Appropriately andlw 0x0FF ^ (1 << NRZTXPin) btfsc STATUS, C iorlw 1 << NRZTXPin movwf NRZTXPort movlw HiDlay ; Large Delay movwf NRZDlay movlw LoDlay ; Short Delay subwf INTCON, w ; Decrement "Short" Delay xorlw 0x0FF addwf INTCON, w btfsc STATUS, Z ; Delay Loop - 7 Cycles decfsz NRZDlay, f goto $ - 5 if (NRZPolarity < 0) ; Negative Polarity? bcf STATUS, C ; Stop Bit to Shift Out else bsf STATUS, C endif rrf NRZByte, f ; Shift the Output Byte Down decfsz NRZCount, f ; Repeat for Each Bit goto $ - 17 ; Go Back to NRZSendLoop return NRZReceive ; Receive Subroutine ; Wait for Byte to Receive (with optional TimeOut) variable RXExpected, RXActual; Test Values for Rx for Errors variable RXError ; Percent Difference Between E/A if (NRZTimeOut != 0) RXExpected = ((NRZSpeed / 1000) * NRZTimeOut) / 4 HiDlay = (RXExpected / (32 * 256)) + 1 LoDlay = ((RXExpected - (32 * 256 * (HiDlay - 1))) / 32) + 1 if (HiDlay > 0x0FF) error "Timeout Delay is Too Long for PICMicro to Process" endif movlw HiDlay ; Large Delay movwf NRZDlay movlw LoDlay ; Short Delay if (NRZPolarity < 0) btfsc NRZRXPort, NRZRXPin else btfss NRZRXPort, NRZRXPin endif goto $ + 21 ; Have the Start Bit nop ; One Cycle Delay goto $ + 1 ; 22 Cycles Delay (for 32 in Total) goto $ + 1 goto $ + 1 goto $ + 1 goto $ + 1 goto $ + 1 goto $ + 1 goto $ + 1 goto $ + 1 goto $ + 1 goto $ + 1 subwf INTCON, w ; Decrement "Short" Delay xorlw 0x0FF addwf INTCON, w btfsc STATUS, Z ; Delay Loop - 9 Cycles decfsz NRZDlay, f goto $ - 19 bsf STATUS, C ; Failed - Error if (NRZPolarity < 0) goto $ + 35 ; Return the Error else goto $ + 34 ; Return the Error endif else ; Wait for the Start Bit if (NRZPolarity < 0) btfss NRZRXPort, NRZRXPin else btfsc NRZRXPort, NRZRXPin endif goto $ - 1 ; No Start Bit Yet endif RXExpected = (NRZSpeed / NRZRate) / (4 * 2) HiDlay = (RXExpected / (7 * 256)) + 1 LoDlay = ((RXExpected - (7 * 256 * (HiDlay - 1))) / 7) + 1 movlw HiDlay ; 1/2 Bit Delay movwf NRZCount movlw LoDlay ; Short Delay subwf INTCON, w ; Decrement "Short" Delay xorlw 0x0FF addwf INTCON, w btfsc STATUS, Z ; Delay Loop - 7 Cycles decfsz NRZCount, f goto $ - 5 if (NRZPolarity < 0) ; Is there a Valid Start Bit? btfsc NRZRXPort, NRZRXPin else btfsc NRZRXPort, NRZRXPin endif if (NRZTimeOut == 0) goto $ - 12 ; No... else goto $ - 20 endif movlw 9 ; Read 9 Bits movwf NRZCount RXExpected = ((NRZSpeed / NRZRate) / 4) - 16 HiDlay = (RXExpected / (7 * 256)) + 1 LoDlay = ((RXExpected - (7 * 256 * (HiDlay - 1))) / 7) + 1 RXActual = ((LoDlay - 1) * 7) + ((HiDlay - 1) * 7 * 256) if (RXActual > RXExpected ) ; Actual is Greater than Expected RXError = (((RXActual - RXExpected) * 100) / RXExpected) else RXError = (((RXExpected - RXActual) * 100) / RXExpected) endif if (RXError > 2) error "Receive Bit Error Rate is Greater than 2%" endif ; NRZReceiveLoop - Come Here for each Bit bcf STATUS, C ; Assume Low Bit Coming in btfsc NRZRXPort, NRZRXPin bsf STATUS, C rrf NRZByte, f ; Save the Read in Bit movlw HiDlay ; 1 Bit Delay movwf NRZDlay movlw LoDlay ; Short Delay subwf INTCON, w ; Decrement "Short" Delay xorlw 0x0FF addwf INTCON, w btfsc STATUS, Z ; Delay Loop - 7 Cycles decfsz NRZDlay, f goto $ - 5 decfsz NRZCount, f ; Repeat for Each Bit goto $ - 14 bsf STATUS, C ; Assume No Stop Bit if (NRZPolarity < 0) btfsc NRZRXPort, NRZRXPin goto $ + 4 else ; Positive Polarity btfss NRZRXPort, NRZRXPin goto $ + 3 endif bcf STATUS, C movf NRZByte, w ; Return the Received Byte if (NRZPolarity < 0) xorlw 0x0FF ; Invert it? endif return endm