#include <stdio.h>#include <math.h>#include <string.h>#include "mscbemb.h"Defines | |
| #define | MAX_VOLTAGE 28000 |
| #define | MAX_CURRENT 75 |
| #define | MINDEL 100 |
| #define | TPC_R 393.4 |
| #define | IOFF -0.1718 |
| #define | GPIB_ADDR_0 4 |
| #define | DEMAND_CHANGED (1<<0) |
| #define | RAMP_UP (1<<1) |
| #define | RAMP_DOWN (1<<2) |
| #define | HV_LIMIT_CHANGED (1<<3) |
| #define | CUR_LIMIT_CHANGED (1<<4) |
| #define | CUR_LIMIT_BYPASS (1<<7) |
| #define | STATUS_RAMP_UP (1<<0) |
| #define | STATUS_RAMP_DOWN (1<<1) |
| #define | STATUS_VLIMIT (1<<2) |
| #define | STATUS_ILIMIT (1<<3) |
| #define | STATUS_LOWCUR (1<<4) |
| #define | STATUS_HICUR (1<<5) |
Functions | |
| void | user_write (unsigned char index) reentrant |
| unsigned char | send (unsigned char adr, char *str) |
| unsigned char | send_byte (unsigned char b) |
| unsigned char | enter (unsigned char adr, char *str, unsigned char maxlen) |
| void | set_voltage_limit (float value) |
| void | set_hv (float value) reentrant |
| void | read_hvi (void) |
| void | ramp_hv (void) |
| void | set_current_limit (float value) |
| void | user_init (unsigned char init) |
| unsigned char | user_read (unsigned char index) |
| unsigned char | user_func (unsigned char *data_in, unsigned char *data_out) |
| void | user_loop (void) |
Variables | |
| unsigned char idata | _n_sub_addr = 1 |
| char code | node_name [] = "CCBERTAN410" |
| char xdata | svn_rev_code [] = "$Rev: 1399 $" |
| unsigned char idata | chn_bits = 0 |
| int | Ibypass = 0 |
| float xdata | u_actual |
| unsigned long xdata | t_ramp |
| char xdata | str [32] |
| char xdata * | buf |
| unsigned char xdata | tiwp |
| struct { | |
| unsigned char status | |
| float u_demand | |
| float u_meas | |
| float i_meas | |
| unsigned int ramp_up | |
| unsigned int ramp_down | |
| float u_limit | |
| float i_limit | |
| char warning [32] | |
| char date [24] | |
| unsigned char gpib_adr | |
| unsigned long mytime | |
| } | user_data |
| MSCB_INFO_VAR code | vars [] |
| MSCB_INFO_VAR * | variables = vars |
| SYS_INFO | sys_info |
| #define CUR_LIMIT_BYPASS (1<<7) |
| #define CUR_LIMIT_CHANGED (1<<4) |
| #define DEMAND_CHANGED (1<<0) |
| #define GPIB_ADDR_0 4 |
| #define HV_LIMIT_CHANGED (1<<3) |
| #define IOFF -0.1718 |
| #define MAX_CURRENT 75 |
| #define MAX_VOLTAGE 28000 |
| #define MINDEL 100 |
| #define RAMP_DOWN (1<<2) |
| #define RAMP_UP (1<<1) |
| #define STATUS_HICUR (1<<5) |
| #define STATUS_ILIMIT (1<<3) |
| #define STATUS_LOWCUR (1<<4) |
| #define STATUS_RAMP_DOWN (1<<1) |
| #define STATUS_RAMP_UP (1<<0) |
| #define STATUS_VLIMIT (1<<2) |
| #define TPC_R 393.4 |
| unsigned char enter | ( | unsigned char | adr, | |
| char * | str, | |||
| unsigned char | maxlen | |||
| ) |
00406 { 00407 unsigned long t; 00408 unsigned char i, flag; 00409 unsigned int j; 00410 00411 /*---- address cycle ----*/ 00412 // GPIB_REN = 0; 00413 GPIB_ATN = 0; // assert attention 00414 send_byte(0x3F); // unlisten 00415 send_byte(0x5F); // untalk 00416 send_byte(0x20 | 21); // listen 21 00417 send_byte(0x40 | adr); // talk device 00418 GPIB_ATN = 1; // remove attention 00419 00420 /*---- data cycles ----*/ 00421 00422 GPIB_NDAC = 0; // init NDAC line 00423 00424 for(i=0;i<maxlen;i++) str[i] = 0; 00425 00426 for (i = 0; i < maxlen; i++) { 00427 yield(); 00428 00429 GPIB_NRFD = 1; // signal ready for data 00430 00431 /* wait 1s for DAV go low */ 00432 t = time(); 00433 do { 00434 if (GPIB_DAV == 0) 00435 break; 00436 00437 yield(); 00438 00439 } while (time() - t < 100); 00440 00441 if (GPIB_DAV == 1) { 00442 GPIB_NDAC = 1; 00443 GPIB_NRFD = 1; 00444 GPIB_REN = 1; 00445 return 0; // timeout 00446 } 00447 00448 GPIB_NRFD = 0; // signal busy 00449 00450 str[i] = ~GPIB_DATA; // read negated data 00451 00452 flag = GPIB_EOI; // read EOI flag 00453 00454 GPIB_NDAC = 1; // signal acknowledge 00455 00456 /* wait for DAV go high */ 00457 for (j = 0; j < 1000; j++) { 00458 delay_us(10); 00459 if (GPIB_DAV == 1) 00460 break; 00461 } 00462 GPIB_NDAC = 0; // remove acknowledge 00463 00464 if (flag == 0) // stop if end of data 00465 break; 00466 } 00467 00468 GPIB_NDAC = 1; // release handshake lines 00469 GPIB_NRFD = 1; 00470 00471 /* stop talker */ 00472 GPIB_ATN = 0; // assert attention 00473 send_byte(0x3F); // unlisten 00474 send_byte(0x5F); // untalk 00475 GPIB_ATN = 1; // remove attention 00476 GPIB_REN = 1; 00477 return i; 00478 }
| void ramp_hv | ( | void | ) |
00610 { 00611 int delta; 00612 00613 /* only process ramping when HV is on and not tripped */ 00614 if (!(user_data.status & STATUS_ILIMIT)) { 00615 00616 if (chn_bits & DEMAND_CHANGED) { 00617 /* start ramping */ 00618 00619 if (user_data.u_demand > u_actual && 00620 user_data.ramp_up > 0) { 00621 /* ramp up */ 00622 chn_bits |= RAMP_UP; 00623 chn_bits &= ~RAMP_DOWN; 00624 user_data.status |= STATUS_RAMP_UP; 00625 user_data.status &= ~STATUS_RAMP_DOWN; 00626 chn_bits &= ~DEMAND_CHANGED; 00627 } 00628 00629 if (user_data.u_demand < u_actual && 00630 user_data.ramp_down > 0) { 00631 /* ramp down */ 00632 chn_bits &= ~RAMP_UP; 00633 chn_bits |= RAMP_DOWN; 00634 user_data.status &= ~STATUS_RAMP_UP; 00635 user_data.status |= STATUS_RAMP_DOWN; 00636 chn_bits &= ~DEMAND_CHANGED; 00637 } 00638 00639 /* remember start time */ 00640 t_ramp = time(); 00641 } 00642 /* ramp up */ 00643 if (chn_bits & RAMP_UP) { 00644 delta = time() - t_ramp; // delta is milli-seconds since last ramp step 00645 if (delta > MINDEL) { 00646 u_actual += (float) user_data.ramp_up; 00647 // u_actual is now the new setting voltage 00648 if (u_actual >= user_data.u_demand) { 00649 // Set the final requested voltage. 00650 u_actual = user_data.u_demand; 00651 chn_bits &= ~RAMP_UP; 00652 user_data.status &= ~STATUS_RAMP_UP; 00653 } 00654 00655 set_hv(u_actual); 00656 t_ramp = time(); 00657 } 00658 } 00659 00660 /* ramp down */ 00661 if (chn_bits & RAMP_DOWN) { 00662 delta = time() - t_ramp; // delta is milli-seconds since last ramp step 00663 if (delta > MINDEL) { 00664 u_actual -= (float) user_data.ramp_down; 00665 // u_actual is now the new setting voltage 00666 if (u_actual <= user_data.u_demand) { 00667 // finish ramping 00668 // Set the final requested voltage. 00669 u_actual = user_data.u_demand; 00670 chn_bits &= ~RAMP_DOWN; 00671 user_data.status &= ~STATUS_RAMP_DOWN; 00672 } 00673 00674 set_hv(u_actual); 00675 t_ramp = time(); 00676 } 00677 } 00678 } 00679 }
| void read_hvi | ( | void | ) |
00527 { 00528 float hv, current; 00529 00530 sprintf (str, "T0"); 00531 send (user_data.gpib_adr, str); 00532 00533 tiwp = enter(user_data.gpib_adr, str, sizeof(str)); 00534 /* 00535 if (tiwp) { 00536 DISABLE_INTERRUPTS; 00537 sprintf (user_data.warning, str); 00538 ENABLE_INTERRUPTS; 00539 } 00540 */ 00541 00542 //-PAA For test 00543 // sprintf(str, "N V12.345K 987.54U"); 00544 00545 if (Ibypass) { 00546 DISABLE_INTERRUPTS; 00547 sprintf (user_data.warning, "Warning! Current Limit bypassed"); 00548 ENABLE_INTERRUPTS; 00549 return; 00550 } 00551 hv = str[8] - 48; 00552 hv += (str[7] - 48)*10; 00553 hv += (str[6] - 48)*100; 00554 hv += (str[4] - 48)*1000; 00555 hv += (str[3] - 48)*10000; 00556 00557 current = (str[17] - 48)/100; 00558 current += (str[16] - 48)/10; 00559 current += (str[14] - 48); 00560 current += (str[13] - 48)*10; 00561 current += (str[12] - 48)*100; 00562 00563 if (hv < 0) hv = 0; 00564 if (current < 0) current = 0; 00565 00566 // Catch false reading. if both are reading 0 00567 // there is certainly a readout error 00568 // // ((hv != 0) || (current != 0)) 00569 // First use the return string length 00570 00571 if (tiwp == 0) return; 00572 DISABLE_INTERRUPTS; 00573 user_data.u_meas = hv; 00574 user_data.i_meas = current; 00575 ENABLE_INTERRUPTS; 00576 00577 // Publish locally new readback voltage for ramping 00578 u_actual = hv; 00579 00580 if ( current >= user_data.i_limit ) { 00581 user_data.status |= STATUS_ILIMIT; 00582 } else { 00583 user_data.status &= ~STATUS_ILIMIT; 00584 } 00585 00586 if ( current > ((1.1 * hv/TPC_R) + IOFF) ) { 00587 sprintf (user_data.warning, "Warning High I (%6.3f)", current); 00588 DISABLE_INTERRUPTS; 00589 user_data.status |= STATUS_HICUR; 00590 user_data.status &= ~STATUS_LOWCUR; 00591 ENABLE_INTERRUPTS; 00592 } else if ( current < ((0.9 * hv/TPC_R) +IOFF) ) { 00593 sprintf (user_data.warning, "Warn-Low I (%6.3f)", current); 00594 DISABLE_INTERRUPTS; 00595 user_data.status |= STATUS_LOWCUR; 00596 user_data.status &= ~STATUS_HICUR; 00597 ENABLE_INTERRUPTS; 00598 } else { 00599 sprintf (user_data.warning, "current OK"); 00600 DISABLE_INTERRUPTS; 00601 user_data.status &= ~STATUS_HICUR; 00602 user_data.status &= ~STATUS_LOWCUR; 00603 ENABLE_INTERRUPTS; 00604 } 00605 }
| unsigned char send | ( | unsigned char | adr, | |
| char * | str | |||
| ) |
00374 { 00375 int i; //, len; 00376 char s; 00377 00378 /*---- address cycle ----*/ 00379 00380 // GPIB_REN = 0; 00381 GPIB_ATN = 0; // assert attention 00382 send_byte(0x3F); // unlisten 00383 send_byte(0x5F); // untalk 00384 send_byte(0x20 | adr); // listen device 00385 send_byte(0x40 | 21); // talk 21 00386 GPIB_ATN = 1; // remove attention 00387 00388 /*---- data cycles ----*/ 00389 // len = strlen(str); 00390 for (i = 0; str[i] > 0; i++) { 00391 s = send_byte(str[i]); 00392 GPIB_REN = 1; 00393 if (s == 0) return 0; 00394 } 00395 00396 GPIB_EOI = 0; 00397 send_byte(0x0A); // NL 00398 GPIB_EOI = 1; 00399 GPIB_REN = 1; 00400 00401 return i; 00402 }
| unsigned char send_byte | ( | unsigned char | b | ) |
00328 { 00329 unsigned int i; 00330 00331 // yield(); 00332 00333 /* wait for NRFD go high */ 00334 for (i = 0; i < 1000; i++) 00335 if (GPIB_NRFD == 1) 00336 break; 00337 00338 if (GPIB_NRFD == 0) 00339 return 0; 00340 00341 GPIB_DATA = ~b; // negate 00342 delay_us(10); // setup time, let signals settle 00343 GPIB_DAV = 0; 00344 00345 /* wait for NDAC go high */ 00346 for (i = 0; i < 1000; i++) { 00347 delay_us(10); 00348 if (GPIB_NDAC == 1) 00349 break; 00350 } 00351 00352 if (GPIB_NDAC == 0) { 00353 GPIB_DAV = 1; 00354 GPIB_DATA = 0xFF; 00355 return 0; // timeout 00356 } 00357 00358 GPIB_DAV = 1; 00359 GPIB_DATA = 0xFF; // prepare for input 00360 00361 /* wait for NRFD go high */ 00362 for (i = 0; i < 1000; i++) 00363 if (GPIB_NRFD == 1) 00364 break; 00365 00366 if (GPIB_NRFD == 0) 00367 return 0; 00368 00369 return 1; 00370 }
| void set_current_limit | ( | float | value | ) |
| void set_hv | ( | float | value | ) |
00509 { 00510 if (value > user_data.u_limit) // check for limit 00511 { 00512 value = user_data.u_limit; 00513 user_data.status |= STATUS_VLIMIT; 00514 } 00515 else 00516 { 00517 user_data.status &= ~STATUS_VLIMIT; 00518 } 00519 00520 sprintf (str, "P%06.3fKG", value/1000); 00521 send (user_data.gpib_adr, str); 00522 }
| void set_voltage_limit | ( | float | value | ) |
| unsigned char user_func | ( | unsigned char * | data_in, | |
| unsigned char * | data_out | |||
| ) |
| void user_init | ( | unsigned char | init | ) |
00183 { 00184 char xdata i; 00185 /* Format the SVN and store this code SVN revision into the system */ 00186 for (i = 0; i < 4; i++) { 00187 if (svn_rev_code[6 + i] < 48) { 00188 svn_rev_code[6 + i] = '0'; 00189 } 00190 } 00191 sys_info.svn_revision = (svn_rev_code[6] - '0') * 1000 + 00192 (svn_rev_code[7] - '0') * 100 + 00193 (svn_rev_code[8] - '0') * 10 + 00194 (svn_rev_code[9] - '0'); 00195 00196 // P0MDIN = 0xFF; // default 0xFF all digital pins 00197 // P1MDIN = 0xFF; 00198 // P2MDIN = 0xFF; 00199 00200 P0MDOUT = 0x18; // Default OD 485TX, TXD 00201 P1MDOUT = 0x00; // OD 00202 P2MDOUT = 0xFF; // OD 00203 00204 P0 = 0x03; // default 0xFF 00205 P1 = 0xFF; 00206 P2 = 0xFF; 00207 00208 /* set initial state of lines */ 00209 GPIB_DATA = 0xFF; 00210 GPIB_EOI = 1; 00211 GPIB_DAV = 1; 00212 GPIB_NRFD = 1; 00213 GPIB_NDAC = 1; 00214 GPIB_IFC = 1; 00215 GPIB_SRQ = 1; 00216 GPIB_ATN = 1; 00217 GPIB_REN = 1; 00218 00219 BUF_CLE = 0; // Enable buffers 00220 BUF_DATAE = 0; 00221 00222 /* initialize GPIB */ 00223 GPIB_IFC = 0; 00224 delay_ms (1); 00225 GPIB_IFC = 1; 00226 00227 GPIB_ATN = 0; 00228 send_byte (0x14); // DCL 00229 GPIB_ATN = 1; 00230 00231 user_data.gpib_adr = GPIB_ADDR_0; 00232 00233 sprintf (str, "OE2"); // prohibit overvoltage setting 00234 send (user_data.gpib_adr, str); 00235 sprintf (str, "OC0"); // hv supply will *not* shutdown if current overload 00236 send (user_data.gpib_adr, str); 00237 sprintf (str, "SE0"); // enables SRQ in response to overvoltage detection 00238 send (user_data.gpib_adr, str); 00239 sprintf (str, "SC0"); // enables SRQ in response to overcurrent detection 00240 send (user_data.gpib_adr, str); 00241 00242 user_data.status = 0; 00243 if (init) { 00244 user_data.ramp_up = 10; 00245 user_data.ramp_down = 10; 00246 user_data.u_limit = MAX_VOLTAGE; 00247 user_data.i_limit = MAX_CURRENT; 00248 } 00249 sprintf (user_data.warning, "current OK"); 00250 00251 set_voltage_limit(user_data.u_limit); 00252 set_current_limit(user_data.i_limit); 00253 00254 read_hvi(); // check to see if hv is already on 00255 00256 if ( user_data.u_meas < 10 ) // bertan hv must be off 00257 { 00258 user_data.u_demand = 0; 00259 u_actual = 0; 00260 set_hv(0); 00261 } 00262 else // bertan hv must already be on 00263 { 00264 user_data.u_demand = user_data.u_meas; // restore to status quo 00265 u_actual = user_data.u_meas; 00266 } 00267 00268 #ifdef RTC_410 00269 // Init RTC on 410 00270 SmaRTCInit(); 00271 #endif 00272 }
| void user_loop | ( | void | ) |
00683 { 00684 /* set voltage limit if changed */ 00685 if (chn_bits & HV_LIMIT_CHANGED) { 00686 set_voltage_limit(user_data.u_limit); 00687 chn_bits &= ~HV_LIMIT_CHANGED; 00688 } 00689 00690 /* set current limit if changed */ 00691 if (chn_bits & CUR_LIMIT_CHANGED) { 00692 set_current_limit(user_data.i_limit); 00693 chn_bits &= ~CUR_LIMIT_CHANGED; 00694 } 00695 00696 // Read Voltage and Current 00697 read_hvi(); 00698 00699 // Yield to other activities (MSCB) 00700 // yield(); 00701 00702 // Do ramping if necessary 00703 ramp_hv(); 00704 00705 #ifdef RTC_410 00706 // RTC stuff 00707 ltime = SmaRTCRead(); 00708 user_data.mytime = ltime; 00709 ascTime(mydate, ltime); 00710 sprintf(user_data.date, "%s", mydate); 00711 #endif 00712 00713 // Slow it down 00714 delay_ms (MINDEL); 00715 00716 // Loop timing 00717 led_blink(0, 1, 50); 00718 }
| void user_write | ( | unsigned char | index | ) |
00279 { 00280 if (index == 1) { 00281 /* indicate new demand voltage */ 00282 chn_bits |= DEMAND_CHANGED; 00283 } 00284 00285 /* Bypass limit */ 00286 if (index == 0) { 00287 if (user_data.status == CUR_LIMIT_BYPASS) 00288 Ibypass = (Ibypass == 1) ? 0 : 1; 00289 } 00290 00291 /* check voltage limit */ 00292 if (index == 6) { 00293 if (user_data.u_limit > MAX_VOLTAGE) { 00294 user_data.u_limit = MAX_VOLTAGE; 00295 } 00296 chn_bits |= HV_LIMIT_CHANGED; 00297 } 00298 00299 /* check current limit */ 00300 if (index == 7) { 00301 if (user_data.i_limit > MAX_CURRENT) { 00302 user_data.i_limit = MAX_CURRENT; 00303 } 00304 chn_bits |= CUR_LIMIT_CHANGED; 00305 } 00306 }
| unsigned char idata _n_sub_addr = 1 |
| char xdata * buf |
| unsigned char idata chn_bits = 0 |
| char date[24] |
| unsigned char gpib_adr |
| float i_limit |
| float i_meas |
| int Ibypass = 0 |
| unsigned long mytime |
| char code node_name[] = "CCBERTAN410" |
| unsigned int ramp_down |
| unsigned int ramp_up |
| unsigned char status |
| char xdata str[32] |
| char xdata svn_rev_code[] = "$Rev: 1399 $" |
| unsigned long xdata t_ramp |
| unsigned char xdata tiwp |
| float xdata u_actual |
| float u_demand |
| float u_limit |
| float u_meas |
| struct { ... } user_data |
| MSCB_INFO_VAR code vars[] |
Initial value:
{
1, UNIT_BYTE, 0, 0, 0, "Status", &user_data.status,
4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "Udemand", &user_data.u_demand,
4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "Umeas", &user_data.u_meas,
4, UNIT_AMPERE, PRFX_MICRO, 0, MSCBF_FLOAT, "Imeas", &user_data.i_meas,
2, UNIT_VOLT, 0, 0, 0, "RampUp", &user_data.ramp_up,
2, UNIT_VOLT, 0, 0, 0, "RampDown",&user_data.ramp_down,
4, UNIT_VOLT, 0, 0, MSCBF_FLOAT, "Ulimit", &user_data.u_limit,
4, UNIT_AMPERE, PRFX_MICRO, 0, MSCBF_FLOAT, "Ilimit", &user_data.i_limit,
32, UNIT_STRING, 0, 0, 0, "warning", &user_data.warning,
1, UNIT_BYTE, 0, 0, MSCBF_HIDDEN, "GPIB Adr",&user_data.gpib_adr,
0
}
| char warning[32] |
1.4.7