A question for the Macro experts....


Closed Thread
Results 1 to 17 of 17
  1. #1
    forgie's Avatar
    forgie Guest

    Default A question for the Macro experts....

    Hi there.
    On my current project I am sending data out to my PC by using HSEROUT. I am sending data from a 12-bit ADC, so to transmit it I use:
    <code>
    HSEROUT [Data / 100, Data // 100]
    </code>

    I use this method so that I can reserve numbers above 100 for communication messages. I'm wondering if it is possible to write a macro that does the above that I could use like this:
    <code>
    @ TRANSMIT _Data
    </code>

    Any tips from the masters would be much appreciated. (I have written a few simple macros, some fully asm, some a mix of asm and PBP, but I could never work out how to use an argument with a macro and then use that argument with a PBP command inside the macro)

  2. #2
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Hi forgie,

    Give this a try...
    Code:
    Data  VAR  WORD
    Temp  VAR  WORD
    
    @TRANSMIT  macro Variable
    @   MOVE?WW  Variable, _Temp    
        HSEROUT [Temp / 100, Temp // 100]
    @ endm
    
    @ TRANSMIT _Data
    DT

  3. #3
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    OR, this one will use less Code Space on each use of the TRANSMIT macro.
    Code:
    Data  VAR  WORD
    Temp  VAR  WORD
    
    TX_Code:
        HSEROUT [Temp / 100, Temp // 100]
    RETURN
    
    ASM
    TRANSMIT  macro Variable
        MOVE?WW  Variable, _Temp    
        L?CALL   _TX_Code
      endm
    ENDASM
    
    @ TRANSMIT _Data
    DT

  4. #4
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Sorry, i'm not an expert but you could try something like
    Code:
    DEFINE OSC 20
    
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_TXSTA 24h
    DEFINE HSER_SPBRG 129 ' 9600 Bauds
    
    wData   var word SYSTEM
    ADCData var word SYSTEM
    xyzData var word SYSTEM
    
    GOTO START
    
    ASM
    TRANSMIT macro ToSend
             MOVE?WW ToSend, wData
             L?CALL UTransmit
             endm
    
    UTransmit 
             endasm  
             HSEROUT [wdata / 100, wdata // 100]
             return
    
    START:
          adcdata=1024
          @ TRANSMIT ADCData
          xyzdata = 500
          @ TRANSMIT xyzData
          
          PAUSE 500
          GOTO START
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  5. #5
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    OUPS!!! didn't see ya Darrel... Sorry.

    mm it looks quite the same BTW... i still learn
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  6. #6
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    No Problem,

    That's what happens when both our brains are grinding at the same time.

    It also gives forgie some confirmation that they will probably work, since 2 people came up with almost the same thing independantly.


    <br>
    DT

  7. #7
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Hehe, i agree.

    Just a question. Is there any possible problem by using
    Code:
    wData   var word SYSTEM
    against
    Code:
    wData   var word
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  8. #8
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Well, can't say for sure, but I've never had any problems with SYSTEM.

    PBP tries to protect against duplicate variable names by adding an underscore "_" in front of everything that's specified by the user.

    The only thing that "SYSTEM" does, is prevent that underscore from being added.

    It could cause a Naming Conflict with other things being used at the ASM level, but when that happens, the compiler will let you know.

    It does make things look nicer without all those _'s. &nbsp;&nbsp;But then, those _'s can make it easier to differentiate between what's PBP and what's ASM variables, when it's debugging time.

    It's hard to say which way is better.
    <br>
    Last edited by Darrel Taylor; - 29th August 2005 at 07:01.
    DT

  9. #9
    forgie's Avatar
    forgie Guest


    Did you find this post helpful? Yes | No

    Default

    Thanks guys, that's exactly what I needed, and it works great. Now to make things more tricky..... the data I'm sending out is in an array, and I normally use this macro inside a for loop that's cycling through the array.

    The old code:
    <code>
    For Sample = 0 to (N_SAMPLES - 1)
    Hserout [Sample_Array[Sample] / 100, Sample_Array[Sample] // 100]
    Next
    </code>


    For obvious reasons, I can't just write:
    <code>
    @ Transmit _Sample_Array[_Sample]
    </code>

    I will rewrite the macro to so that the argument is the Index of the Sample_Array array, so the macro will be dedicated to using that one array, like such:
    <code>
    @ Transmit _Sample
    </code>

    I'll post my macro when I've finished writing it, but just for discussions sake, is there some easy way to call a member of an array using a macro? I could use something like:
    <code>
    Addr = Sample_Array + (2 * Sample)
    @ Transmit _Addr
    </code>
    To do the same thing, right? This doesn't help much since my aim is to improve readability here.

    I guess I could use a macro that takes a word array and an index as arguments:
    <code>
    @ TX_Array _Sample_Array, _Sample
    </code>

    Hmmm. I seem to be answering my own questions by writing it down. Macros now seem much more useful. How would I write the above macro, but have it be able to take Word and Byte arrays? In other words, how do you use If statements in macros?

    Thanks guys,
    forgie

  10. #10
    forgie's Avatar
    forgie Guest


    Did you find this post helpful? Yes | No

    Default

    Oh and, how do you post code like you guys do? I have been using < code>.... whats the tag to put it in a nice little grey box?

  11. #11
    Join Date
    Oct 2004
    Location
    Italy
    Posts
    695


    Did you find this post helpful? Yes | No

  12. #12
    forgie's Avatar
    forgie Guest


    Did you find this post helpful? Yes | No

    Default

    Thanks, Luciano
    My macro now looks like thus:
    Code:
    TXArray	var Sample_Array
    TXIndex	var word SYSTEM
    TXData	var word SYSTEM
    @TX_Sample macro index
    	@ MOVE?WW index, TXIndex
    	TXData = TXArray[TXIndex]
    	Hserout [TXData / 100, TXData // 100]
    	@ endm
    (Sample_Array is a word array that I'm using to store my data in).

    This works great, and I can call it like this:
    Code:
    	@ TX_Sample _Sample
    Thanks for the pointers, fellow PBPers. The only thing I couldn't do was get it to take both the array and the index as arguments.... I have to nut out the whole memory addressing thing in my head before I can get it to work.

  13. #13
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    Good job guy. i just want to remind you something. Every time a macro is called, that duplicate his whole code. so, by using the following
    Code:
    asm
    TX_Sample macro index
    	MOVE?WW index, TXIndex
        L?CALL TXnow
    	endm
    TXnow
        ENDASM
    	TXData = TXArray[TXIndex]
    	Hserout [TXData / 100, TXData // 100]
        RETURN
    this will generate less code everytime you call the macro.

    Here's another method to send a specific index of Word array var.
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_TXSTA 24h
    DEFINE HSER_SPBRG 129 ' 9600 Bauds
    
    TXData  var WORD SYSTEM   
    aVar    var word[4] SYSTEM
    
    avar[0]=0
    avar[1]=100
    avar[2]=1000
    avar[3]=10000
    goto start
    
    asm
    Usend macro index
    	MOVE?WW aVar + (index*2) , TXData
        L?CALL TXnow
    	endm
    TXnow
        ENDASM
    	Hserout [dec TXData,13,10]
        RETURN
    start:
          @ Usend 0
          @ Usend 1
          @ Usend 2
          @ Usend 3
          pause 500
          goto start
    there's probably tons of way like using AOUT?xxx macro too.. well still unsure of that one AOUT?xxx
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

  14. #14
    Join Date
    Jul 2003
    Location
    Colorado Springs
    Posts
    4,959


    Did you find this post helpful? Yes | No

    Default

    Macro's can be usefull. &nbsp;But, they're not always the best choice.
    Code:
    TRANSMIT:
        Temp = Sample_Array(Index)
        HSEROUT [Temp / 100, Temp // 100]
    RETURN
    
    Index = 2 : GOSUB TRANSMIT
    <br>
    DT

  15. #15
    forgie's Avatar
    forgie Guest


    Did you find this post helpful? Yes | No

    Default

    Yes, I was aware of that after reading one of your earlier posts. I am sitting slightly under 50% of my available code space (on an 18f452), and on top of that the data sending routines are used in a part of the code where speed is preferable (but not critical). To use the fastest method I would have to find out what macros HSEROUT calls, and call them directly somehow.... and the smallest code version would be something along the same lines using gosubs. Anyway if the timing becomes more important or code space is an issue then I will rewrite the macro. But for the meantime, I have improved readability by a large degree. Thanks for the ideas/wisdom guys, it's great to know that there's such a concentrated pool of knowledge in this forum to ask when I have a tough PBP question.....

  16. #16
    forgie's Avatar
    forgie Guest


    Did you find this post helpful? Yes | No

    Red face

    Also.... the macro method makes me feel like my code is more 'modular,' and more like a functional language, which makes me feel warm inside

  17. #17
    Join Date
    Sep 2004
    Location
    montreal, canada
    Posts
    6,898


    Did you find this post helpful? Yes | No

    Default

    If you want to shrink your code, the best way is to see if you can use the internal ressource instead of the PBP pre-made function.

    By example, instead of using ADCIN, write/read directly to the register, same for HSEROUT, HSERIN and how much others.

    For a simple HSEROUT
    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    RCSTA =$90
    TXSTA =$24
    SPBRG= 129 ' 9600 Bauds
    
    aVar    var BYTE[7]
    a       var byte
    
    avar[0]="H"
    avar[1]="E"
    avar[2]="L"
    avar[3]="L"
    avar[4]="O"
    AVAR[5]=13
    AVAR[6]=10
    A=0
    start:
        REPEAT
            TXREG=AVAR[A]
            NotEmpty: if TXSTA.1=0 then notempty
            A=A+1
            UNTIL A=7
            A=0
            PAUSE 500  
          goto start
    compile 89 words

    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    RCSTA =$90
    TXSTA =$24
    SPBRG= 129 ' 9600 Bauds
    
    aVar    var BYTE[7]
    
    avar[0]="H"
    avar[1]="E"
    avar[2]="L"
    avar[3]="L"
    avar[4]="O"
    AVAR[5]=13
    AVAR[6]=10
    
    start:
        HSEROUT[STR AVAR]
        PAUSE 500  
        goto start
    compile 103 words.

    Code:
    DEFINE LOADER_USED 1
    DEFINE OSC 20
    DEFINE HSER_RCSTA 90h
    DEFINE HSER_TXSTA 24h
    DEFINE HSER_SPBRG 129 ' 9600 Bauds
    
    aVar    var BYTE[7]
    
    avar[0]="H"
    avar[1]="E"
    avar[2]="L"
    avar[3]="L"
    avar[4]="O"
    AVAR[5]=13
    AVAR[6]=10
    
    start:
        HSEROUT[STR AVAR]
        PAUSE 500  
        goto start
    almost the same as the previous but using PBP DEFINE HSER compile 95 words

    No big improvement so far... i should find a better example next time

    BTW it's always case by case. Scroll your program and look wich statement you call the most, do a SUB with them and TADA. Just be sure to avoid too much nested gosub and it should gives you good results.

    BUT there's always a midpoint between a readable code, and a tight one. Choose your own comfort zone and work with.
    Last edited by mister_e; - 30th August 2005 at 16:59.
    Steve

    It's not a bug, it's a random feature.
    There's no problem, only learning opportunities.

Similar Threads

  1. PBPro error "Macro USBINIT? not found in macro file"
    By Bonxy in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 4th October 2011, 09:06
  2. Replies: 6
    Last Post: - 4th November 2009, 13:36
  3. Really simple question for you experts :)
    By lew247 in forum mel PIC BASIC Pro
    Replies: 5
    Last Post: - 4th June 2008, 01:43
  4. Please answer my first question
    By John_001 in forum Off Topic
    Replies: 1
    Last Post: - 15th September 2006, 06:49
  5. Passing an array as a macro argument?
    By forgie in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 5th September 2005, 17:09

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