Example of Register-Based Communication
- Updated2025-01-24
- 4 minute(s) read
Example of Register-Based Communication
VISA has two standard methods for accessing registers. The first method uses High-Level Access functions. You can use these functions to specify the address to access; the functions then take care of the necessary details to perform the access, from mapping an I/O window to checking for failures. The drawback to using these functions is the amount of software overhead associated with them.
To reduce the overhead, VISA also has Low-Level Access functions. These functions break down the tasks done by the High-Level Access functions and let the program perform each task itself. The advantage is that you can optimize the sequence of calls based on the style of register I/O you are about to perform. However, you must be more knowledgeable about how register accesses work. In addition, you cannot check for errors easily. The following example shows how to perform register I/O using the High-Level Access functions, which is the method we recommend for new users. If you are an experienced user or understand register I/O concepts, you can use the Low-Level Access Operations.
Register-Based Communication Example
(C)
#include "visa.h" int main(void) { ViStatus status; /* For checking errors */ ViSession defaultRM, instr; /* Communication channels */ ViUInt16 deviceID; /* To store the value */ /* Begin by initializing the system */ status = viOpenDefaultRM(&defaultRM); if (status &t; VI_SUCCESS) { /* Error Initializing VISA...exiting */ return -1; } /* Open communication with VXI Device at Logical Addr 16 */ /* NOTE: For simplicity, we will not show error checking */ status = viOpen(defaultRM, "VXI0::16::INSTR", VI_NULL, VI_NULL, &instr); /* Read the Device ID, and write to memory in A24 space */ status = viIn16(instr, VI_A16_SPACE, 0, &deviceID); status = viOut16(instr, VI_A24_SPACE, 0, 0x1234); /* Close down the system */ status = viClose(instr); status = viClose(defaultRM); return 0; }
Register-Based Communication Example (VB)
Private Sub vbMain() Dim stat As ViStatus Dim dfltRM As ViSession Dim sesn As ViSession Dim deviceID As Integer Rem Begin by initializing the system stat = viOpenDefaultRM(dfltRM) If (stat < VI_SUCCESS) Then Rem Error initializing VISA...exiting Exit Sub End If Rem Open communication with VXI Device at Logical Addr 16 Rem NOTE: For simplicity, we will not show error checking stat = viOpen(dfltRM, "VXI0::16::INSTR", VI_NULL, VI_NULL, sesn) Rem Read the Device ID and write to memory in A24 space stat = viIn16(sesn, VI_A16_SPACE, 0, deviceID) stat = viOut16(sesn, VI_A24_SPACE, 0, &H1234) Rem Close down the system stat = viClose(sesn) stat = viClose(dfltRM) End Sub
Register-Based Communication Example
Discussion
The general structure of the register-based communication example is very similar to that of the message-based communication example. The following are some of the basic differences:
- A different address string is used for the VXI device.
- The string functions from the message-based communication example are replaced with register functions.
The address string is still the same format as the address string in the message-based communication example, but it has replaced the GPIB with VXI. Again, remember that the difference in the address string name is the extent to which the specific interface bus will be important. Indeed, since this is a simple string, it is possible to have the program read in the string from a user input or a configuration file. Thus, the program can be compiled and is still portable to different platforms.
As you can see from the programming code, you use different functions to perform I/O with a register-based device. The functions viIn16() and viOut16() read and write 16-bit values to registers in either the A16, A24, or A32 space of VXI. As with the message-based functions, you start by specifying which device you want to talk to by supplying the instr variable. You then identify the address space you are targeting, such as VI_A16_SPACE.
The next parameter warrants close examination. Notice that we want to read in the value of the Device ID register for the device at logical address 16. Logical addresses start at offset 0xC000 in A16 space, and each logical address gets 0x40 bytes of address space. Because the Device ID register is the first address within that 0x40 bytes, the absolute address of the Device ID register for logical address 16 is calculated as follows:
0xC000 + (0x40 * 16) = 0xC400
However, notice that the offset we supplied was 0. The reason for this is that the instr parameter identifies which device you are talking to, and therefore the VISA driver is able to perform the address calculation itself. The 0 indicates the first register in the 0x40 bytes of address space, or the Device ID register. The same holds true for the viOut16() call. Even in A24 or A32 space, although it is possible that you are talking to a device whose memory starts at 0x0, it is more likely that the VXI Resource Manager has provided some other offset, such as 0x200000 for the memory. However, because instr identifies the device, and the Resource Manager has told the driver the offset address of the device's memory, you do not need to know the details of the absolute address. Just provide the offset within the memory space, and VISA does the rest. For more detailed information about other defined VXI registers, refer to the NI-VXI Help.
Again, when you are done with the register I/O, use viClose() to shut down the system.