Page 136 of 229 Start Back Next End ZBasic Language Reference 126 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