variable name generating with macro
Peter Verkaik
Posts: 3,956
Hi,
I want to generate variables using a macro.
The macro argument is the variable name prefix
myMacro··macro·name
??\1_count·ds·1··;count value
When I have
myMacro lowpass
then I want the macro to create
lowpass_count ds 1 ;count value
Is that at all possible?
The macro above generates
\1_count ds 1 ;count value
regards peter
·
I want to generate variables using a macro.
The macro argument is the variable name prefix
myMacro··macro·name
??\1_count·ds·1··;count value
When I have
myMacro lowpass
then I want the macro to create
lowpass_count ds 1 ;count value
Is that at all possible?
The macro above generates
\1_count ds 1 ;count value
regards peter
·
Comments
Had to use
myMacro··macro·prefix
prefix??_??count·ds·1··;count value
Thanks to
http://www.piclist.com/techref/new/letter/news0403.htm
regards peter
That URL should probably be
http://www.sxlist.com/techref/new/letter/news0403.htm·
although it is possible to use SASM to write code for PIC 16C5x chips, I really doubt anyone is...
Really happy to see someone actually using macros, and I hope we see more of it.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
Perhaps you can now.
I am trying to conserve a macro argument to use it in another macro.
myMacro··macro·prefix
myMacro_prefix = prefix
prefix??_??count·ds·1··;count value
endm
myMacro_code
·· inc myMacro_prefix??_??count
endm
Somewhere in my code I place
ifdef myMacro_prefix
myMacro_code
endif
But this does not work.
I get
· inc myMacro_prefix_count
The idea is to let the code operate on defined variables
so I can create a library of code that is only included if
certain variables are defined.
regards peter
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
uart···macro·prefix
prefix??_??bank··equ·$
prefix??_??count·ds·1··;number of bits
prefix??_??divide·ds·1··;timing counter
prefix??_??low··ds·1··;shift register
prefix??_??high·ds·1··;value
prefix??_??format·ds·1
· prefix??_??bits_0·equ·prefix??_??format.0·;bits 1 and 0 specify number of total bits
· prefix??_??bits_1·equ·prefix??_??format.1·;01 -> 9bits, 10 -> 10bits, 11 -> 11bits (start+data+parity+stop)
· prefix??_??7bits·equ·prefix??_??format.2·;set for 7 databits (0 = 8 databits)
· prefix??_??even·equ·prefix??_??format.3·;set for even parity
· prefix??_??odd·equ·prefix??_??format.4·;set for odd parity
· prefix??_??data·equ·prefix??_??format.5·;set if valid value, cleared after value grabbed
· prefix??_??enable·equ·prefix??_??format.6·;set to enable uart
· prefix??_??parity·equ·prefix??_??format.7·;parity bit placeholder
prefix??_??baud·ds·1··;baudrate
prefix??_??datapin·ds·1··;high nib = port (5 to 9), low nib = pin (0 to 7)
· prefix??_??error·equ·prefix??_??datapin.3·;set if parity error
prefix??_??hspin·ds·1··;high nib = port (5 to 9), low nib = pin (0 to 7)
endm
rxuart_data··macro·prefix
rxprefix··=·?\1?
uart prefix
endm
txuart_data··macro·prefix
txprefix··=·?\1?
uart prefix
endm
;rxuart_code··macro·prefix
uart_receive
···mov·fsr,vp_bank··;select target uart rambank
···jnb·prefix??_??enable,:rxdone
···mov·w,<>prefix??_??datapin··;port (ra to re) in lownib
···and·w,#$0F
···mov·fsr,w···;ports ra to re
···mov·w,indf···;read all pins
···mov·isr_temp,w··;save pin states
···mov·fsr,vp_bank
···mov·w,prefix??_??datapin··;pin number 0 to 7 in lownib
···call·pinmask···;get mask for pin
···and·isr_temp,w··;extract bit for pin
···test·prefix??_??count··;currently receiving byte?
···sz····;no
···jmp·:rx1···;yes, jump ahead
···mov·w,--prefix??_??format··;ready bits for start
···and·w,#$03···;number of bits 1, 2 or 3
···or·w,#$08···;9, 10 or 11
···test·isr_temp··;start bit?
···snz····;no
···mov·prefix??_??count,w··;yes, renew bit count
···mov·w,>>prefix??_??baud··;half bittime delay
···add·w,prefix??_??baud··;plus bittime delay -> start delay
···mov·prefix??_??divide,w
:rx1
···clc
···test·isr_temp
···sz
···stc
···decsz·prefix??_??divide··;middle of next bit?
········· ··jmp·:rxdone···;no
···dec·prefix??_??count··;last bit?
···jz·:rx2···;yes
···rr·prefix??_??low···;no, rotate in new bit
···movb·prefix??_??parity,C··;save b0
···jmp·:rx3···;renew delay time
:rx2
···mov·w,prefix??_??low··;save byte to allow receive another byte
···mov·prefix??_??high,w
···setb·prefix??_??data···;mark byte received
:rx3
···mov·w,prefix??_??baud··;renew delay time
···mov·prefix??_??divide,w
:rxdone
···retp
; RAM Bank Register VP definitions
;
·; userram0
·;
···org·userram0_org
rxuart_data rx
txuart_data tx
·; userram1
·;
···org·userram1_org
rxuart_data rx1
txuart_data tx1
So I have multiple uart records, but only a single uart receive subroutine.
(the uart data is at equal offsets in different banks, vp_bank sets the
correct bank before probing the pins)
in my code I have
ifdef rxprefix
rxuart_code txprefix
endif
I need that prefix to access the earlier defined variables.
Hope this clarifies what I try to accomplish.
regards peter
·
I can understand "So I have multiple uart records, but only a single uart receive subroutine." that makes sense because you are using FSR / bank to switch between the variables but it doesn't make sense be cause you can't use macros to switch between the data pins for example. The macro could be used to compile a SEPERATE bit of code for each uart from the same source code where a parameter would used to change the code compiled to match the data pin for that usart.
Are you thinking that the macro will cause ONE bit of code to be generated that will allow the data pin to be changed with the variables? It doesn't work that way.
You found some information on that page at
http://www.sxlist.com/techref/new/letter/news0403.htm· but did you actually read that entire article? It does a pretty good job of explaining what macros are.
"Macros are code that is executed by the compiler rather than by the processor. E.g. by SASM rather than by the SX. Macros are programs that generate code for the processor just like you generate code for the processor. You write the MACRO program so that it will write code for you instead of you haveing to write the code each time yourself. Macros are like a "mini-me" that I have taught how to write code. The programming language that you write macros in, are the compiler directives like IFDEF, REPT, EQU, and so on."
Since macro code is executed by the compiler (SASM) it is all done executing by the time it gets into the SX; it can not have any effect on the code at "run time" inside the SX.
Or is this just something that I'm still not understanding? Are you planning on invoking the rxuart_code macro once for each uart?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
the attachement may clarify it better.
The idea is to let macros DECLARE variables and include the code that operates on these variables.
The rxuart macro·for example, DECLARES 8 byte variables with a specified prefix (different prefix
for different receive uarts) but also DEFINES the same variables with a fixed name. These
defined variables gets redefined for each rxuart macro call.
The fsr is set to the propr rambank before calling uart_receive (which is only included once).
The used datapin is specified in variable lib_rx_datapin and is different for each uart.
All recieve uarts must be declared at the same rambank offset but different rambanks,
otherwise it doesn't work.
This way I hope to create a library of code I can use by simply calling a macro after setting
the ram address.
· org·bank0_org
data···=·$
defvp 1,rxuart,rx
defvp 2,txuart,tx
· org·bank1_org
data···=·$
defvp 3,rxuart,rx1
defvp 4,txuart,tx1
egards peter
This code works:
Does that help? Or am I missing something else... If this gets your first example working, I can move on to the more complex ones.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
Why do you take up a file register for "vp_bank"? You could just mov fsr, #vp??nr??_bank after vp??nr??_isr thereby saving a register and a cycle. Or am I missing something there?
I will have to spend quite some time to understand all of the features you have in this... but I appears it will be worth it. With some include files to seperate things out, that could be a very nice template. Will you publish the result when you are satisfied with it?
Thanks!
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
---
James Newton, Host of SXList.com
james@sxlist.com 1-619-652-0593 fax:1-208-279-8767
SX FAQ / Code / Tutorials / Documentation:
http://www.sxlist.com Pick faster!
I use vp_bank if and only if executing inside the isr. The main level code
does not touch vp_bank. Notice that I have a single isr subroutine for
multiple uart records (each in their own·rambank) so vp_bank gets
loaded prior to executing that isr subroutine. (Perhaps I should rename it
to isr_bank). Inside that isr, fsr is changed because of dynamic pin access,
and so fsr is reloaded from vp_bank to access the correct rambank afterwards.
In general, a VP macro
consists of isr code (labelled vp??nr??_isr),
main code (labelled vp??nr??_main),
and additional routines called by either isr code or main code.
I have completed the vplib.src with an i2c_slave macro.
This particular macro requires two isr_flags (one to notify when
a byte is received, and another one to notify when a byte is needed).
I am still struggling with the·format for the defvp macro.
For now, I use nr+1 as the 2nd isr flag for that macro.
The end goal, is to move·all constants and macros to an include file,
so in the project file only an include is visable.
regards peter