Last edited by test153; - 6th February 2009 at 00:59.
For the past few days I have been searching the net for some sample code for the soft uart - since I couldn't find anything useful that worked I ask you guys. Anyone that can point me to some site with anything useful?
Also I found this asm code:
I've tried it but I just get a "Stack underflow executing retlw". Also how do one call the inch routine from picbasic?Code:SERBUF var byte TEMP var byte COUNTS var byte ASM ; ******************************************************************** ; INCH ROUTINE ; THIS ROUTINE INPUTS RS232 DATA USING A 22K OHM RESISTOR, NO LEVEL- ; CHANGING INVERTER IS USED. GPIO,3 = RX (MARK = 0, SPACE = 1). ; THIS ROUTINE USES A 8-DATA BIT PER CHARACTER PROTOCOL. ; TO RECIEVE A CHARACTER, CALL inch. THE RECEIVED CHARACTER IS PLACED ; IN THE REG 'W' AND IN THE REG 'SERBUF'. ; CHARACTER WILL ECHO IF 'retlw 0' IS REM-ED OUT. ; VARIABLES USED: REG 'TEMP' AND REG 'SERBUF' BOTH VARIABLES ARE ; SHARED WITH THE 'outch' ROUTINE ; ROUTINES CALLED: 'half_baud' AND 'baud' FOR THE BAUD-RATE TIMING. ; ******************************************************************** inch btfss GPIO,3 ; SKIP ON START BIT = "SPACE" (+RS232) goto inch ; ELSE KEEP LOOKING FOR A START BIT movlw d'08' ; START SERIAL INPUT SEQUENCE movwf _TEMP ; COLLECT 8 DATA BITS clrf _SERBUF ; CLEAR SERIAL CHARACTER BUFFER call half_baud ; DELAY FOR ONE HALF BAUD TIME btfss GPIO,3 ; FALL THRU IF START BIT STILL = "SPACE" goto inch ; ELSE IT WAS JUST A NOISE SPIKE, LOOP inch1 call baud ; DELAY ONE BAUD-BIT TIME ( = 1/BAUD-RATE) bcf STATUS,0 ; CLEAR THE CARRY BIT rrf _SERBUF,F ; ROTATE CRY -> MSB, ROTATE MSB RIGHT btfss GPIO,3 ; IS INPUT = "SPACE" (+RS232) ? bsf _SERBUF,7 ; ...SKIP IF YES, ELSE SET BIT TO LOGIC '1' decfsz _TEMP,F ; EIGHT COUNTS YET? goto inch1 ; ...NO, GET ANOTHER BIT call baud ; DELAY FOR THE FIRST STOP BIT movf _SERBUF,W ; Put the character in reg 'W' retlw 0 ; NOTE: REM THIS OUT IF YOU NEED AN "ECHO" ; ...AND FALL THROUGH TO THE 'OUTCH' ROUTINE ; ******************************************************************** ; BAUD ROUTINE @ 4 MHz ; BAUD RATE: CONSTANT: ; 1200 Baud D'137' ; 2400 Baud D'68' ; 4800 Baud D'34' ; 9600 Baud D'16' ; 19200 Baud D'8' ; 38400 Baud and up - use 'NOP' delays ; VARIABLES USED: REG 'COUNT' ; ROUTINES CALLED: NONE ; ******************************************************************** baud ; AT 2400 BAUD THE PERIOD IS 416.6 US ; CLK = 4MHz movlw D'68' ; 1 US (BAUD RATE CONSTANT) movwf _COUNTS ; 1 US baud1 decfsz _COUNTS,F ; 1 US (+ 1 US MORE IF SKIP) goto baud1 ; 2 US ; FALL THRU...AFTER 1+1+3x68+1 = 207 US half_baud movlw D'68' ; 1 US movwf _COUNTS ; 1 US hbaud1 decfsz _COUNTS,F ; 1 US (+ 1 US MORE IF SKIP) goto hbaud1 ; 2 US retlw 0 ; ...AFTER 1+1+3x68+1 = 207 US (X2=414 US) ENDASM END
Last edited by test153; - 7th February 2009 at 14:58.
RETLW 0 is the same (almost) as RETURN, this ca be remove if you're not using a GOSUB to call it. A return without a previous Gosub call, will indeed "underflow" the stack.
If you sit this routine in a interrupt service routine, check the PBP manual somewhere at the end about INterrupts.
Steve
It's not a bug, it's a random feature.
There's no problem, only learning opportunities.
Ok, so I need the interrupt to gosub the rs232 routine and how do I call a asm routine outside the asm...endasm?
If you do not believe in MAGIC, Consider how currency has value simply by printing it, and is then traded for real assets.
.
Gold is the money of kings, silver is the money of gentlemen, barter is the money of peasants - but debt is the money of slaves
.
There simply is no "Happy Spam" If you do it you will disappear from this forum.
Well I have this code and still get underflow errors... I have a pritty good idea of what the code does, but I can't understand why it gives me this undeflow error as it is called from the main loop.
Code:SERBUF var byte TEMP var byte COUNTS var byte ASM ; ******************************************************************** ; INCH ROUTINE ; THIS ROUTINE INPUTS RS232 DATA USING A 22K OHM RESISTOR, NO LEVEL- ; CHANGING INVERTER IS USED. GPIO,3 = RX (MARK = 0, SPACE = 1). ; THIS ROUTINE USES A 8-DATA BIT PER CHARACTER PROTOCOL. ; TO RECIEVE A CHARACTER, CALL inch. THE RECEIVED CHARACTER IS PLACED ; IN THE REG 'W' AND IN THE REG 'SERBUF'. ; CHARACTER WILL ECHO IF 'retlw 0' IS REM-ED OUT. ; VARIABLES USED: REG 'TEMP' AND REG 'SERBUF' BOTH VARIABLES ARE ; SHARED WITH THE 'outch' ROUTINE ; ROUTINES CALLED: 'half_baud' AND 'baud' FOR THE BAUD-RATE TIMING. ; ******************************************************************** inch: btfss GPIO,3 ; SKIP ON START BIT = "SPACE" (+RS232) goto inch ; ELSE KEEP LOOKING FOR A START BIT movlw d'08' ; START SERIAL INPUT SEQUENCE movwf _TEMP ; COLLECT 8 DATA BITS clrf _SERBUF ; CLEAR SERIAL CHARACTER BUFFER call half_baud ; DELAY FOR ONE HALF BAUD TIME btfss GPIO,3 ; FALL THRU IF START BIT STILL = "SPACE" goto inch ; ELSE IT WAS JUST A NOISE SPIKE, LOOP inch1: call baud ; DELAY ONE BAUD-BIT TIME ( = 1/BAUD-RATE) bcf STATUS,0 ; CLEAR THE CARRY BIT rrf _SERBUF,F ; ROTATE CRY -> MSB, ROTATE MSB RIGHT btfss GPIO,3 ; IS INPUT = "SPACE" (+RS232) ? bsf _SERBUF,7 ; ...SKIP IF YES, ELSE SET BIT TO LOGIC '1' decfsz _TEMP,F ; EIGHT COUNTS YET? goto inch1 ; ...NO, GET ANOTHER BIT call baud ; DELAY FOR THE FIRST STOP BIT movf _SERBUF,W ; Put the character in reg 'W' retlw 0 ; NOTE: REM THIS OUT IF YOU NEED AN "ECHO" ; ...AND FALL THROUGH TO THE 'OUTCH' ROUTINE ; ******************************************************************** ; BAUD ROUTINE @ 4 MHz ; BAUD RATE: CONSTANT: ; 1200 Baud D'137' ; 2400 Baud D'68' ; 4800 Baud D'34' ; 9600 Baud D'16' ; 19200 Baud D'8' ; 38400 Baud and up - use 'NOP' delays ; VARIABLES USED: REG 'COUNT' ; ROUTINES CALLED: NONE ; ******************************************************************** baud: ; AT 2400 BAUD THE PERIOD IS 416.6 US ; CLK = 4MHz movlw D'68' ; 1 US (BAUD RATE CONSTANT) movwf _COUNTS ; 1 US baud1: decfsz _COUNTS,F ; 1 US (+ 1 US MORE IF SKIP) goto baud1 ; 2 US ; FALL THRU...AFTER 1+1+3x68+1 = 207 US half_baud: movlw D'68' ; 1 US movwf _COUNTS ; 1 US hbaud1: decfsz _COUNTS,F ; 1 US (+ 1 US MORE IF SKIP) goto hbaud1 ; 2 US retlw 0 ; ...AFTER 1+1+3x68+1 = 207 US (X2=414 US) ENDASM high porta.0 loop: @ goto inch if SERBUF = 49 then low porta.0 goto loop END
Bookmarks