有用过NI 公司NET9914芯片的吗,就是GPIB协议的芯片?

2020-01-02 19:39发布

有用过NET9914芯片的朋友吗?我看了它的PDF文档,我不明白里面说的可以有两种模式,即MODE 9914 各MODE 7210模式。到底应该怎么样初始化它啊?是不是两种模式都要进入进行设置呢?有用过的可以讲一下吗?谢谢了!
89条回答
xyz543
1楼 · 2020-01-04 15:54.采纳回答
iamlangzi 发表于 2012-11-23 10:34
您好,非常感谢您的回复。能够将这些给大家学习,真是太不容易了!
希望有机会和您多交流! ...


我已将您要的东西移植到 Keil C51 的工程上了,接下来您得自己学习了.

链接: https://pan.baidu.com/s/1iR4oBeyPWuoDb_4b9-4rXA 提取码: z4mb

GPIB For Keil C51



xyz543
2楼-- · 2020-01-04 11:08
iamlangzi 发表于 2012-11-22 22:55
xyz543:您好,我看了你的代码,中间的一段中断程序,是否有遗漏?此外好多“{”位置是否正确?
能否将这段 ...

空的括号内的程序仅是设置些错误讯息的回应而已,如 i = 1; j = 2 的类似程序,所以我没有必要都给列出来!

另外,您是否已经测试过程序了? 我能提供的也就是这样,这是我能提供的最大的限度了,已包含初始化 NAT9914 及其中断的做法了,相信应该绝对的够您容易上手了!

若您要求完整的源码的话,与其不如您要我来帮您写完您所要的代码好了!! 因为这是商业用代码,一般这代码根本是公司的机密,我能提供这些已经是能直接应用的了吧?!
iamlangzi
3楼-- · 2020-01-04 15:17
您好,非常感谢您的回复。能够将这些给大家学习,真是太不容易了!
希望有机会和您多交流!
iamlangzi
4楼-- · 2020-01-04 17:27
 精彩回答 2  元偷偷看……
iamlangzi
5楼-- · 2020-01-04 18:01
本帖最后由 iamlangzi 于 2012-11-27 21:53 编辑

//Gpibdev5.c
/*
gpibdevc.c 7/28/97
GPIB DEVICE implementation for a small microcontroller operating in tandem
with a NAT9914 chip. This C code is designed for a microcontroller. It implements a
GPIB voltage query, tare, Group Execute Trigger, and DCAS commands.
At startup, this code initializes the microcontroller and the NAT9914 and then waits
in an idle state until the NAT9914 sends an interrupt. The device interprets the
interrupt and tares, resets, executes on the G.E.T. command, reads the voltage and
stuffs it into a buffer, or outputs the contents of the buffer to the Active GPIB
listener.
read_voltage(), handle_GET_trigger(), and adjust_tare() are device specific and
shown here as stubs. The NAT9914 interrupts the microcontroller for BI, BO, GET,
and SDC/DCL.
*/
/* assert() statements draw attention to internal errors */
/* #include <assert.c> */
#include "avr/io.h"
#define assert(a) {}
#include "gpibdevc.h"
#pragma interrupt_handler route_nat9914_interrupts
#define USING_INTERRUPTS
/* to input and output on a microcontroller, read or write to a memory location
*/
#define inp(io_address) *(unsigned char *)io_address
#define outp(io_address, o_data) *( unsigned char *)io_address = o_data;
/* state variable. one of the following values
idle_state 1
reading_state 2
writing_state 3
*/
u_8 GPIB_state;
/* buffer variables
Index is an offset from the base address of the i/o buffer.
io_buffer is both the GPIB input and output buffer.
*/
u_8 Index;
u_8 io_buffer[BUFFER_SIZE];
/* isr0_byte and isr1_byte hold data from the NAT9914 status registers which has not yet
* been processed.
*/
u_8 isr0_byte;
u_8 isr1_byte;


int main(void) {
initialize_device();
do{
/*
* all non-GPIB device code goes in this loop
*/
//#ifndef USING_INTERRUPTS
route_nat9914_interrupts();
//#endif
}while(1);
}



/*
*
* Initialization routines
*
*
*
*/
void initialize_device(void) {
/* initialization sequences for both the microcontroller and the NAT9914
*/
initialize_microcontroller();
/* initialize software variables before the device begins accepting GPIB commands
*/
Index = 0;
GPIB_state = idle_state;
initialize_NAT9914();
asm("cli");
}
void initialize_microcontroller(){
/* initialize the microcontroller
* ...these are microcontroller defaults
* expanded memory mode (set by hardware pins)
* set clock speed
* set hardware interrupt to match capabilities of nat9914
* disable watchdog
*/
}
void initialize_NAT9914(){
/* this routine initializes the NAT9914 and enables the device to receive commands from
* the GPIB network.
*/
u_8 my_gpib_address;
/* ...Make sure GPIB chip is in 9914 mode.
*/
outp(r7210_auxmr, c7210_sw9914);
/* ...Reset the NAT9914. Logically remove device from the GPIB. The device will
* ignore GPIB activity until it is initialized.
*/
outp(r_auxcr, c_ch_rst);
/* ...clear the status registers.
*/
isr0_byte = 0;
isr1_byte = 0;
/* ...set clock speed
*/
outp(r_accr, f_icr | f_2mhz);
/* ...set T1 delay
*/
outp(r_auxcr, c_vstdl);
/* ...enable interrupts
*/
outp(r_imr0, b_bo_ie | b_bi_ie);
outp(r_imr1, b_dcas_ie | b_get_ie);
#ifndef USING_INTERRUPTS
outp(r_auxcr, c_piimr2);
outp(r_imr2, 0x00); /* clear GLINT bit */
#endif
/* ...configure the NEWLINE character to end incoming and outgoing GPIB messages
*/
outp(r_auxcr, c_pieosr);
outp(r_eosr, NEWLINE);
outp(r_auxcr, c_piaccr);
outp(r_accr, f_accra | b_xeos | b_reos);
/* ...set the GPIB address of the device
*/
my_gpib_address = get_gpib_address();
outp(r_adr, my_gpib_address);
/* ...enable the device to receive data and commands from the GPIB network
*/
outp(r_auxcr, c_nswrst);
}
u_8 get_gpib_address(void){
/* read the GPIB address from DIP switches. This device specific function reads the
* address from a set of DIP switches connected to port D.
*/
u_8 gpib_address;
gpib_address = inp(PORT_D);
/* convert the invalid address, 31(decimal) into 30
*/
if(gpib_address == 31)
gpib_address = 30;
return gpib_address;
}
/*
*
* Handle Interrupt Routines
*
*
*
*/
void route_nat9914_interrupts(void) {
/* route_nat9914_interrupts handles the hardware interrupt from the NAT9914.
* It determines what caused the interrupt and calls the appropriate function.
* If no interrupts are pending, then it does nothing.
*/
/* ...read isr0 and isr1, the values must be saved because the act of reading the bits
* in the registers clears the bits.
*/
isr0_byte = isr0_byte | inp(r_isr0);
isr1_byte = isr1_byte | inp(r_isr1);
/* ...determine the cause of the interrupt and handle it
*/
if (isr0_byte & b_bo) handle_BO_int();
if (isr0_byte & b_bi) handle_BI_int();
if (isr1_byte & b_get) handle_GET_trigger();
if (isr1_byte & b_dcas) handle_DCAS_int();
}
void handle_DCAS_int(void) {
/* This routine resets only the GPIB interface of the device and not
* the device itself. Its primary use is recovering after an error on the GPIB.
* If a GPIB error occurs and the device locks up or appears to hang, the GPIB
* controller can issue the SDC or DCL command and place the device into its idle GPIB
* state, clear its buffers and start over.
*/
/* ...reinitialize variables and buffers
*/
Index = 0;
GPIB_state = idle_state;
outp(r_auxcr, c_rhdf);
isr0_byte = 0x00;
isr1_byte = 0x00;
/* ...update serial poll response byte
*/
clear_status_byte_bits( b_mav |
b_rsv |
error_reading |
error_writing |
error_unknown_command);
/* ...acknowledge command received and processed by releasing DAC holdoff
*/
outp(r_auxcr, c_nonvalid);
}

void handle_BI_int(void) {
/* The Byte In handler reads a byte from the NAT9914 and stores it in the input buffer.
* If the device has not finished writing data from a previous command message, the
* device overwrites the old data and issues an error message to the GPIB controller.
*/
assert( GPIB_state==idle_state ||
GPIB_state==reading_state ||
GPIB_state==writing_state);
assert(Index <= BUFFER_SIZE);
/* ...update the gpib state
*/
if (GPIB_state == idle_state) {
Index = 0;
GPIB_state = reading_state;
}
/* ...if the controller is sending data to the device while the device is trying to
* send data to the controller, set an error flag in the status byte to warn the
* controller.
*/
else if (GPIB_state == writing_state){
clear_status_byte_bits(b_mav);
set_status_byte_bits(b_rsv | error_reading);
GPIB_state = reading_state;
Index = 0;
outp(r_auxcr, c_nbaf);
}
/* read data from the NAT9914 into the input buffer. To improve performance loop
* instead of exiting the interrupt handler and then calling the interrupt handler
* again.
*/
do{
/* read the data into the buffer. If the buffer is full, then
* the routine doesn't accept the new byte.
*/
if(Index < BUFFER_SIZE) {
io_buffer[Index]= (u_8) inp(r_dir);
Index++;
}
assert(Index <= BUFFER_SIZE);
/* check for another incoming byte unless the end of the string
* is detected.
*/
isr0_byte = isr0_byte & ~b_bi;
if(!(isr0_byte & b_end)){
isr0_byte = isr0_byte | (u_8) inp(r_isr0);
}
}while (isr0_byte&b_bi);
/* ..if a complete message has been received, interpret before exiting
*/
if (isr0_byte & b_end) parse_input_buffer();
}

void handle_BO_int(void) {
/* This routine places the next byte from the output buffer into the NAT9914. If
* the device was reading data and received a spurious command to write, the function
* issues an error message to the GPIB controller and exits.
*/
assert( GPIB_state==idle_state ||
GPIB_state==reading_state ||
GPIB_state==writing_state);
/* ...update the GPIB state
*/
if (GPIB_state == idle_state) {
/* ...only write if data has been written to the output buffer
*/
if (Index == 0) {
isr0_byte= isr0_byte & ~b_bo;
}
else {
Index = 0;
GPIB_state = writing_state;
}
}
/* ...If the controller and the device are both trying to read data, set an error
* flag in the serial poll response byte
*/
else if (GPIB_state == reading_state){
set_status_byte_bits(error_writing);
isr0_byte = isr0_byte & ~b_bo;
}
/* ...write the data bytes to the NAT9914 until the listener stops listening or the
* device runs out of data. To improve performance loop instead of exiting the
* interrupt handler and then calling the interrupt handler again.
*/
while (isr0_byte&b_bo){
assert(Index <= BUFFER_SIZE);
/* ...output a byte from the output buffer
*/
outp(r_cdor, io_buffer[Index]);
Index++;
/* ...check if NAT9914 is ready to send another byte
*/
isr0_byte = isr0_byte & ~b_bo;
isr0_byte = isr0_byte | (u_8) inp(r_isr0);
/* ...If the device is out of data, update the serial poll response register, stop
* sending data and reset the buffer
*/
if (io_buffer[Index-1] == NEWLINE) {
clear_status_byte_bits(b_mav | b_rsv);
GPIB_state = idle_state;
Index=0;
isr0_byte = isr0_byte & ~b_bo;
}
}
assert( (Index>=0)&&(Index<=BUFFER_SIZE) );
}
/*
*
* Device Dependent Routines
*
*
*
*/
void handle_GET_trigger(void) {
/* This routine performs a device specific trigger action.
*/
/*
* insert code to implement the device specific trigger action
*/
/* release DAC holdoff to acknowledge to other routines and to the GPIB controller
* that the device specific trigger action has been completed.
*/
isr1_byte = isr1_byte & ~b_get;
outp(r_auxcr, c_nonvalid);
}
void read_voltage(void) {
/* This routine is an example of a device specific execute query.
*/
/* ...read the device specific data
*/
/* ...format the device specific data
*/
/* ...output the data to the output buffer
*/
output_data_to_io_buffer('1');
output_data_to_io_buffer('.');
output_data_to_io_buffer('2');
output_data_to_io_buffer('V');
}
void adjust_tare(void) {
/* adjust_tare is an example of a device specific execute command.
*/
/*
* insert your device specific code here
*/
}
/*
*
* GPIB Buffer Routines
*
*
*
*/
void output_data_to_io_buffer( u_8 data_out) {
/* output_data_to_io_buffer writes data to the output buffer. Because its input is
* provided by other functions, it has no error checking.
*/
/* ...check ranges on variables
*/
assert( GPIB_state==idle_state ||
GPIB_state==reading_state ||
GPIB_state==writing_state);
assert((Index>=0)&&(Index<BUFFER_SIZE));
/* ..place the data byte on the output buffer
*/
io_buffer[Index] = data_out;
Index = Index + 1;
}
void parse_input_buffer() {
/* parse the message and call the correct routine. Also, reset the buffer and set the
* device in idle state. If the command just received is invalid, send an error message
* to the GPIB controller.
*/
/* ...check ranges on variables
*/
assert( GPIB_state==idle_state ||
GPIB_state==reading_state ||
GPIB_state==writing_state);
assert((Index>=0) && (Index <= BUFFER_SIZE));
/* ...reset the state variables, since the device now has stopped reading GPIB data
*/
Index = 0;
GPIB_state = idle_state;
isr0_byte = isr0_byte & ~b_end;
/* ...parse the message in the input buffer
*/
if ( io_buffer[0]=='V' &&
io_buffer[1]=='O' &&
io_buffer[2]=='L' &&
io_buffer[3]=='T' &&
io_buffer[4]=='?' ) {
read_voltage();
/* ...terminate the data string and request service now that the data is
* in the buffer
*/
output_data_to_io_buffer(NEWLINE);
set_status_byte_bits(b_mav | b_rsv);
}
else if ( io_buffer[0]=='T' &&
io_buffer[1]=='A' &&
io_buffer[2]=='R' &&
io_buffer[3]=='E' )
adjust_tare();
else{
/* ...if the device received an unrecognized command, send an error
* message
*/
set_status_byte_bits(b_rsv | error_unknown_command);
}
}
/*
*
* Status Byte management routines
*
*
*
*/
void set_status_byte_bits(u_8 srq_byte) {
/* this routine encapsulates writes to the NAT9914's spmr register. It allows the
* calling routine to set any combination of bits without affecting the others. It
* presents a consistent interface for requesting serial polls. Its counterpart is
* clear_status_byte_bits()
*/
u_8 srq_response_byte;
srq_response_byte = (u_8) inp(r_spsr);
srq_response_byte = srq_response_byte | srq_byte;
srq_response_byte = srq_response_byte & ~b_rsv;
outp(r_spmr, srq_response_byte );
/* ...use the rsv2 command to request a serial poll instead of the rsv bit. The rsv2
* command clears itself after the serial poll and mixing rsv2 and rsv can cause
* undefined behavior.
*/
if(srq_byte & b_rsv){
outp(r_auxcr, c_rsv2);
}
}
void clear_status_byte_bits(u_8 srq_byte) {
/* this routine encapsulates writes to the NAT9914's spmr register. It allows the
* calling routine to clear any combination of bits without affecting the others by
* clearing the bits corresponding to the asserted bits of its input. It presents a
* consistent interface for ceasing to request serial polls. Its counterpart is
* set_status_byte_bits().
*/
u_8 srq_response_byte;
srq_response_byte = (u_8) inp(r_spsr);
srq_response_byte = srq_response_byte & ~srq_byte;
srq_response_byte = srq_response_byte & ~b_rsv;
outp(r_spmr, srq_response_byte );
/* ...use the rsv2 command to stop requesting a serial poll instead of the rsv bit.
* The rsv2 command clears itself after the serial poll and mixing rsv2 and rsv can
* cause undefined behavior.
*/
if(srq_byte & b_rsv){
outp(r_auxcr, c_nrsv2);
}
}
iamlangzi
6楼-- · 2020-01-04 21:37
//Gpibdevc.h
/*
gpibdevc.h
*/
#define Base_Address 0x1080
#define error_reading 1<<0
#define error_writing 1<<1
#define error_unknown_command 1<<2
#define NEWLINE 0x0a /* line feed */
#define PORT_D 0x1008
#define interrupt_vector 0xFFF2
/* define i/o addresses of the registers on the nat9914 */
#define r_isr0 (Base_Address )
#define r_imr0 (Base_Address )
#define r_isr1 (Base_Address+1 )
#define r_imr1 (Base_Address+1 )
#define r_adsr (Base_Address+2 )
#define r_imr2 (Base_Address+2 )
#define r_eosr (Base_Address+2 )
#define r_bcr (Base_Address+2 )
#define r_accr (Base_Address+2 )
#define r_bsr (Base_Address+3 )
#define r_auxcr (Base_Address+3 )
#define r_isr2 (Base_Address+4 )
#define r_adr (Base_Address+4 )
#define r_spmr (Base_Address+5)
#define r_spsr (Base_Address+5)
#define r_cptr (Base_Address+6)
#define r_ppr (Base_Address+6)
#define r_dir (Base_Address+7)
#define r_cdor (Base_Address+7)
/* NAT9914 registers in 7210 mode */
#define r7210_auxmr (Base_Address+5)
/* isr0 bits*/
#define b_int0 0x80
#define b_int1 0x40
#define b_bi 0x20
#define b_bo 0x10
#define b_end 0x08
#define b_spas 0x04
#define b_rlc 0x02
#define b_mac 0x01
/* imr0 bits*/
#define b_dma0 0x80
#define b_dma1 0x40
#define b_bi_ie 0x20
#define b_bo_ie 0x10
#define b_end_ie 0x08
#define b_spas_ie 0x04
#define b_rlc_ie 0x02
#define b_mac_ie 0x01
/* isr1 bits*/
#define b_get 0x80
#define b_err 0x40
#define b_unc 0x20
#define b_apt 0x10
#define b_dcas 0x08
#define b_ma 0x04
#define b_srq 0x02
#define b_ifc 0x01
/* imr1 bits*/
#define b_get_ie 0x80
#define b_err_ie 0x40
#define b_unc_ie 0x20
#define b_apt_ie 0x10
#define b_dcas_ie 0x08
#define b_ma_ie 0x04
#define b_srq_ie 0x02
#define b_ifc_ie 0x01
/* adsr bits */
#define b_rem 0x80
#define b_llo 0x40
#define b_atn 0x20
#define b_lpas 0x10
#define b_tpas 0x08
#define b_la 0x04
#define b_ta 0x02
#define b_ulpa 0x01
/* imr2 bits */
#define b_glint 0x80
#define b_stbo_ie 0x40
#define b_nlen 0x20
#define b_lloc_ie 0x08
#define b_atni_ie 0x04
#define b_cic_ie 0x01
/* bcr bits */
#define b_bcr_atn 0x80
#define b_bcr_dav 0x40
#define b_bcr_ndac 0x20
#define b_bcr_nrfd 0x10
#define b_bcr_eoi 0x08
#define b_bcr_srq 0x04
#define b_bcr_ifc 0x02
#define b_bcr_ren 0x01
/* accr fields (shadow registers)*/
#define f_icr 0x20
#define f_accra 0x80
#define f_accrb 0xa0
#define f_accre 0xc0
#define f_accrf 0xd0
#define f_accri 0xe0
/* bsr bits are identical to bcr*/
/* isr2 bits */
#define b_nba 0x80
#define b_stbo 0x40
#define b_nl 0x20
#define b_eos 0x10
#define b_lloc 0x08
#define b_atni 0x04
#define b_cic 0x01
/* adr bits */
#define b_edpa 0x80
#define b_dal 0x40
#define b_dat 0x20
/* spmr/spsr bits */
#define b_rsv 0x40
#define b_mav 0x10
/* accra bits */
#define b_bin 0x10
#define b_xeos 0x08
#define b_reos 0x04
/* accrb bits */
#define b_iss 0x10
#define b_inv 0x08
#define b_lwc 0x04
#define b_speoi 0x02
#define b_atct 0x01
/* accre bits */
#define b_dhadt 0x08
#define b_dhadc 0x04
/* accrf bits */
#define b_dhata 0x08
#define b_dhala 0x04
#define b_dhuntl 0x02
#define b_dhall 0x01
/* accri bits */
#define b_ustd 0x08
#define b_pp1 0x04
#define b_dmae 0x01
/* accr~icr bits */
#define f_1mhz 0x01
#define f_2mhz 0x02
#define f_3mhz 0x03
#define f_4mhz 0x04
#define f_5mhz 0x05
#define f_6mhz 0x06
#define f_7mhz 0x07
#define f_8mhz 0x08
/* auxcr commands */
#define c_nswrst 0x00
#define c_swrst 0x80
#define c_nonvalid 0x01
#define c_valid 0x81
#define c_rhdf 0x02
#define c_nhdfa 0x03
#define c_hdfa 0x83
#define c_nhdfe 0x04
#define c_hdfe 0x84
#define c_nbaf 0x05
#define c_nfget 0x06
#define c_fget 0x86
#define c_nrtl 0x07
#define c_rtl 0x87
#define c_feoi 0x08
#define c_nlon 0x09
#define c_lon 0x89
#define c_nton 0x0a
#define c_ton 0x8a
#define c_gts 0x0b
#define c_tca 0x0c
#define c_tcs 0x0d
#define c_nrpp 0x0e
#define c_rpp 0x8e
#define c_nsic 0x0f
#define c_sic 0x8f
#define c_nsre 0x10
#define c_sre 0x90
#define c_rqc 0x11
#define c_rlc 0x12
#define c_ndai 0x13
#define c_dai 0x93
#define c_pts 0x14
#define c_nstdl 0x15
#define c_stdl 0x95
#define c_nshdw 0x16
#define c_shdw 0x96
#define c_nvstdl 0x17
#define c_vstdl 0x97
#define c_nrsv2 0x18
#define c_rsv2 0x98
#define c_sw7210 0x99
#define c_reqf 0x1a
#define c_reqt 0x9a
#define c_ch_rst 0x1c
#define c_nist 0x1d
#define c_ist 0x9d
#define c_piimr2 0x1e
#define c_pibcr 0x1f
#define c_clrpi 0x9c
#define c_pieosr 0x9e
#define c_piaccr 0x9f
/* NAT9914 in 7210 mode commands */
#define c7210_sw9914 0x15
typedef unsigned char u_8;
/* buffer and GPIB state declarations */
#define BUFFER_SIZE 15
#define idle_state 1
#define reading_state 2
#define writing_state 3
/* function declarations
*/
void initialize_device(void);
u_8 get_gpib_address(void);
void route_nat9914_interrupts(void);
void handle_DCAS_int(void);
void handle_BI_int(void);
void handle_BO_int(void);
void handle_GET_trigger(void);
void parse_input_buffer(void);
void read_voltage(void);
void adjust_tare(void);
void output_data_to_io_buffer(u_8);
void initialize_microcontroller(void);
void initialize_NAT9914(void);
void set_status_byte_bits(u_8);
void clear_status_byte_bits(u_8);
iamlangzi
7楼-- · 2020-01-04 22:43
请教一下:
  采用查询方式后,在接收数据时,if (isr0_byte & b_bi) handle_BI_int();
   ISR0的BI位总是不能置位,真是莫名奇妙,始终不知道什么原因。
  有知道的能否给告诉一下,不胜感激!

一周热门 更多>