Serout code space


Closed Thread
Results 1 to 12 of 12

Hybrid View

  1. #1
    Join Date
    Aug 2003
    Posts
    985

    Default Serout code space

    Hi Guys,
    I thought it should be possible to save space if bit banging serial manually.
    Maybe just if one speed, or one direction is needed, which is transmit only in this case,
    and the byte value is destroyed by the send each time.
    That’s what the code is. The delay of course depends on the baud rate you want, and the pic’s clock speed.

    Now I’m thinking on the receive side, a fast enough pic should be able to determine the received baud rate
    with the very first received byte, by measuring the duration of the start to stop bit,
    rather then sending a known byte value and trying to receive at each baud rate until it’s interpreted properly.


    Code:
    ‘ PBP software serial out 8N1
    delay var word ‘ set baud rate delay
    txbyte var byte ‘ byte to send
    count var byte ‘ counter
    
    delay = 0’ set serial delay here
    
    main:
    txbyte = “H"
    GOSUB serialout
    txbyte = “E"
    GOSUB serialout
    txbyte = “L"
    GOSUB serialout
    txbyte = “L"
    GOSUB serialout
    txbyte = “O"
    GOSUB serialout
    txbyte = $20 ‘ space
    GOSUB serialout
    goto main
    
    
    serialout:
    ‘ start bit
    PORTB.1 = 0’ tx clear
    PAUSEUS delay ‘ start bit delay
    
    ‘ send byte
    FOR count = 0 TO 7
    IF txbyte.bit0 = 1 THEN
    PORTB.1 = 1
    ELSE
    PORTB.1 = 0
    ENDIF
    txbyte = txbyte >> 1
    PAUSEUS delay ‘ data bit delay
    NEXT count
    PORTB.1 = 1
    PAUSEUS delay ‘ stop bit delay
    RETURN

  2. #2
    Join Date
    Oct 2005
    Location
    Sweden
    Posts
    3,612


    Did you find this post helpful? Yes | No

    Default Re: Serout code space

    Hi Art,
    Interesting. I suppose you've verified that it actually is "better"? By how much? I think it's not really fair to compare against SEROUT. Instead, you should compare against DEBUG since it, just like your routine, handles the baudrate calculation at compile time - unlike SEROUT/SEROUT2.

    Like compare your code with
    Code:
    DEFINE DEBUG_REG PORTB
    DEFINE DEBUG_BIT 1
    DEFINE DEBUG_BAUD 2400
    
    Main:
    DEBUG "Hello", $20
    Goto Main
    I might be missing something but as far as I can see the problem with doint autobaud detect on an unknown byte is you don't know what the first databit after the startbit actually is so you don't really KNOW if the next edge is the end of the startbit or the end of any arbitrary databit. I believe a common byte is either $55 or $AA because every bit changes.

    In any case, please keep posting about your findings!

    /Henrik.

  3. #3
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Serout code space

    Haha, you’re right there. I can’t even measure the start bit alone because the next bit could be either value.
    I didn’t consider that!

    IIRC, 2400 baud timing is 417uS, so you’d maybe subtract a little from that to make up for the instruction time of the serial code itself.
    No, it’s not fair to compare with Serout, and Debug didn’t even occur to me.

    So long as I could use asm like PBP compiler does in the end, it could be smaller.
    When I did decompile PBP in the past, all bytes were sent to functions like this via it’s intermediate system variables,
    so that’s an extra copy for nothing:

    Code:
    Your PBP var -> system var -> serial routine
    Unless that has been changed in further PBP revisions, it’s still one up
    It also occurred to me since last night that serial input code may, or may not be included in a PBP program if only output code is used.

    Ps. It probably goes without saying, the main loop in that example was verbose for readability, and should be replaced by reading the data out of an array!
    Last edited by Art; - 21st November 2016 at 03:08.

  4. #4
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Serout code space

    and:
    Code:
    IF txbyte.bit0 = 1 THEN
    PORTB.1 = 1
    ELSE
    PORTB.1 = 0
    ENDIF
    should be replaced with:

    Code:
    PORTB.1 =  txbyte.bit0
    While still in BASIC.

  5. #5
    Join Date
    May 2013
    Location
    australia
    Posts
    2,643


    Did you find this post helpful? Yes | No

    Default Re: Serout code space

    IT MAY NOT BE WORTH THE EFFORT ,tried this on a 12f683

    90 words

    Code:
    #CONFIG
        __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _CP_OFF
    #ENDCONFIG
    DEFINE OSC 8 'LETS PBP KNOW WE WILL BE RUNNING AT 8MHZ
    
    'PIN DEFENITIONS
    '
    'GP3 
    'GP4 USED FOR TRIGGER INPUT
    'GP5 USED FOR LED
    'SET UP THE  REGISTERS
    OSCCON = %01110001  '8MHZ INTERNAL CLOCK USED
    CMCON0 = %00000111 'CIN PINS ARE I/O, COUT PIN IS I/O
    TRISIO = %00111011 ' GP2  OUTPUT THE REST ARE INPUTS 
    ANSEL = 0 'NO ANALOG PORTS - ALL DIGITAL
    WPU = %00010000 'GP4 WEAK PULL UP ENABLED.
        
        DEFINE DEBUG_REG GPIO
        DEFINE DEBUG_BIT 2
        DEFINE DEBUG_BAUD 9600
        DEFINE DEBUG_MODE 0
    '    LATB.7=1
    'PBP software serial out 8N1
    delay var word ' set baud rate delay
    txbyte var byte ' byte to send
    bcount var byte ' counter
    serpin var gpio.2
    delay = 100 ' set serial delay here   9600
    main:
    txbyte = "H"
    GOSUB serialout
    txbyte = "E"
    GOSUB serialout
    txbyte = "L"
    GOSUB serialout
    txbyte = "L"
    GOSUB serialout
    txbyte = "O"
    GOSUB serialout
    txbyte = $20 ' space
    GOSUB serialout
    goto main
     
    serialout:
    Debug  txbyte 
    RETURN
    98 words for arts version

    Code:
    #CONFIG
        __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_ON & _CP_OFF
    #ENDCONFIG
    DEFINE OSC 8 'LETS PBP KNOW WE WILL BE RUNNING AT 8MHZ
    
    'PIN DEFENITIONS
    '
    'GP3 
    'GP4 USED FOR TRIGGER INPUT
    'GP5 USED FOR LED
    'SET UP THE  REGISTERS
    OSCCON = %01110001  '8MHZ INTERNAL CLOCK USED
    CMCON0 = %00000111 'CIN PINS ARE I/O, COUT PIN IS I/O
    TRISIO = %00111011 ' GP2  OUTPUT THE REST ARE INPUTS 
    ANSEL = 0 'NO ANALOG PORTS - ALL DIGITAL
    WPU = %00010000 'GP4 WEAK PULL UP ENABLED.
        
    'PBP software serial out 8N1
    delay var word ' set baud rate delay
    txbyte var byte ' byte to send
    bcount var byte ' counter
    serpin var gpio.2
    delay = 100 ' set serial delay here   9600
    main:
    txbyte = "H"
    GOSUB serialout
    txbyte = "E"
    GOSUB serialout
    txbyte = "L"
    GOSUB serialout
    txbyte = "L"
    GOSUB serialout
    txbyte = "O"
    GOSUB serialout
    txbyte = $20 ' space
    GOSUB serialout
    goto main
     
    serialout:
    
    ' start bit
    serpin = 0  ' tx clear
    PAUSEUS delay ' start bit delay
    ' send byte
    FOR bcount = 0 TO 7
    serpin=txbyte.0
    txbyte = txbyte >> 1
    PAUSEUS delay ' data bit delay
     
    NEXT  
    serpin= 1
    PAUSEUS delay ' stop bit delay
    RETURN
    Warning I'm not a teacher

  6. #6
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    Default Re: Serout code space

    Nice
    If it could be matched in space, I’d still prefer to see my own code, just that I’ve never had a reason to do it until now.
    It would be less in asm though, and I still think I could top it.

    It was worth the effort to do with a dsPic where the pin was not mappable to UART, so incidentally tried with PBP as well.

    No BASIC For/Next loop, instead I’d count down to zero.
    No shift command, instead an asm rotate to ensure only 1 instruction,
    My own delay routine, which is conveniently right before a return, so can be called multiple times.
    watchdog timer resets also have to be turned off because PBP won’t put them in it’s own routines, but in YOUR code.

    To my disadvantage, there needs to be some value stored in Delay, which would claim some more space.


    Something like this (untested).. and I can’t remember if PBP labels need the underscore or not.
    Code:
    count var byte
    pdelay var byte
    
    serialout:
    @ movlw	,8
    @ movwf	_count	,F
    @ clrf PORTB	,1
    @ call pausedelay
    sendbyte:
    PORTB.1 = txbyte.bit0
    @ rrf txbyte	,F
    @ call pausedelay
    @ decfsz _count
    goto sendbyte
    @ bsf PORTB	,1
    pausedelay:
    @ movlw	,210
    @ movwf	_pdelay	,F
    zpausedelay:
    decfsz _pdelay
    @ goto zpausedelay
    @ return
    Last edited by Art; - 21st November 2016 at 05:52.

Similar Threads

  1. Working code but my layman approach uses too much code space
    By Christopher4187 in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 14th December 2012, 20:44
  2. I'm running out of code space example.
    By retepsnikrep in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 21st June 2010, 20:33
  3. Minimizing code space
    By Tobias in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 30th May 2009, 07:25
  4. Need more code space
    By Sphere in forum General
    Replies: 2
    Last Post: - 19th September 2005, 20:49
  5. Need more code space
    By ghutchison in forum General
    Replies: 1
    Last Post: - 12th February 2005, 20:54

Members who have read this thread : 0

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts