ZBasic Language Reference
132
ZBasic Microcontrollers
For passing values to and receiving values from external functions, the CType() function may be useful
for casting to/from ZBasic values. See the description of CType() in the ZBasic System Library Manual.
Also, note that if you have header files for the external code modules you may find it more convenient to
import the identifiers directly from the header file. See section 6.8 for more information.
It is also useful to note that if you include C, C++ or assembly language files in your project, when the
compiler is invoked to process them the special identifier ZBASIC_APP is defined. You may use this
identifier in conditionals to control the features or configuration of the included code.
6.3 Defining Interrupt Service Routines
For the native mode devices you may write special-purpose code to service hardware interrupts. This
may be useful, for example, to add some interrupt-driven capability to your program that is not directly
supported by ZBasic. The syntax for defining an interrupt service routine (ISR) is similar to that for
defining a subroutine, illustrated here by example. Note that the definition of an ISR does not allow
parameters but the parentheses are, nonetheless, required.
ISR Timer1_CompB()
' place the ISR code here
End ISR
The ISR name following the ISR keyword must be valid for the underlying processor. The set of valid ISR
names may be found in one of the XML resource description files located in a subdirectory of the ZBasic
installation directory.. See Appendix N for more information on the resource description files.
It is important to note that some ISRs are added to your application automatically depending on the set of
ZBasic System Library routines that it uses and whether certain resources like the RTC and serial
channels are used. See the ZBasic System Library Reference Manual for more information on the
various ISRs that can be provided automatically. If you attempt to define an ISR having the same name
as one that is automatically added the compiler will issue an error message indicating the attempt to
define a duplicate ISR.
For the form of ISR definition shown in the example above, the compiler takes care of saving the
necessary registers upon entry, establishing the standard register state, restoring registers upon exit and
executing a return from interrupt instruction. For special cases, you may define a naked ISR one in
which none of this is done. Using this special form is advised only for advanced programmers,
particularly those that understand the nuances of the underlying code.
An example of a naked ISR containing only a return from interrupt is shown below. This is commonly
called a stub ISR. It is important to note that defining a naked ISR with no code statements in it at all
results in undefined behavior. At a minimum, you should always include an assembly language reti as
shown in the example below.
ISR Timer1_CompB() Attribute(Naked)
#asm
reti
#endasm
End ISR
Sometimes, it is desirable to have the same ISR service multiple interrupts. This can be accomplished by
defining an ISR that is aliased to another ISR as shown below.
ISR Timer1_CompA()
' place the common ISR code here
End ISR
ISR Timer1_CompB() Alias Timer1_CompA
End ISR
|