📄 cfunc.mod
字号:
/* $Id: cfunc.mod,v 1.3 2004/07/09 18:37:58 pnenzi Exp $ *//*.......1.........2.........3.........4.........5.........6.........7.........8================================================================================FILE triangle/cfunc.modCopyright 1991Georgia Tech Research Corporation, Atlanta, Ga. 30332All Rights ReservedPROJECT A-8503-405 AUTHORS 12 Apr 1991 Harry LiMODIFICATIONS 2 Oct 1991 Jeffrey P. Murray SUMMARY This file contains the model-specific routines used to functionally describe the triangle (controlled trianglewave oscillator) code model.INTERFACES FILE ROUTINE CALLED CMmacros.h cm_message_send(); CM.c void *cm_analog_alloc() void *cm_analog_get_ptr() int cm_analog_set_temp_bkpt()REFERENCED FILES Inputs from and outputs to ARGS structure. NON-STANDARD FEATURES NONE===============================================================================*//*=== INCLUDE FILES ====================*/#include "triangle.h" /*=== CONSTANTS ========================*//*=== MACROS ===========================*/ /*=== LOCAL VARIABLES & TYPEDEFS =======*/ /*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ /*==============================================================================FUNCTION void cm_triangle()AUTHORS 12 Apr 1991 Harry LiMODIFICATIONS 2 Oct 1991 Jeffrey P. MurraySUMMARY This function implements the triangle (controlled trianglewave oscillator) code model.INTERFACES FILE ROUTINE CALLED CMmacros.h cm_message_send(); CM.c void *cm_analog_alloc() void *cm_analog_get_ptr() int cm_analog_set_temp_bkpt()RETURNED VALUE Returns inputs and outputs via ARGS structure.GLOBAL VARIABLES NONENON-STANDARD FEATURES NONE==============================================================================*/#include <stdlib.h>/*=== CM_TRIANGLE ROUTINE ===*//****************************************************** ** I /\ <- output_high ** I / \ ** I / \ ** I / \ ** I / \ ** I / \ ** I / \ ** I / \ ** I / \ ** I/------------------------------------------ ** \ / ** \ / ** \ / ** \ / ** \ / ** \ / ** \ / ** \/ <- output_low ** ******************************************************/void cm_triangle(ARGS) /* structure holding parms, inputs, outputs, etc. */{ int i; /* generic loop counter index */ int cntl_size; /* size of the control array */ int freq_size; /* size of the frequency array */ int int_cycle; /* the number of cycles rounded to the nearest int */ double *x; /* pointer holds the values of the control array */ double *y; /* pointer holds the values of the freq array */ double cntl_input; /* control input */ /*double out;*/ /* output */ double dout_din; /* partial out wrt to control input */ double output_low; /* lowest point of the wave */ double output_hi; /* highest point of the wave */ double dphase; /* percent into the current phase of the cycle */ double *phase; /* instantaneous phase value */ double *phase1; /* pointer to the previous phase value */ double freq=0.0; /* actual frequency of the wave */ double d_cycle; /* duty cycle */ double *t1; /* pointer which stores time1 */ double *t2; /* pointer which stores time2 */ double *t_end; /* pointer which stores t_start */ double time1; /* time of high peak */ double time2; /* time of low peak */ double t_start; /* time of the beginning of each cycle */ Mif_Complex_t ac_gain; /**** Retrieve frequently used parameters... ****/ cntl_size = PARAM_SIZE(cntl_array); freq_size = PARAM_SIZE(freq_array); output_low = PARAM(out_low); output_hi = PARAM(out_high); d_cycle = PARAM(duty_cycle); if(cntl_size != freq_size){ cm_message_send(triangle_array_error); return; } /* Allocate memory */ if(INIT==1){ phase = cm_analog_alloc(INT1,sizeof(double)); t1 = cm_analog_alloc(T1,sizeof(double)); t2 = cm_analog_alloc(T2,sizeof(double)); t_end = cm_analog_alloc(T3,sizeof(double)); } if(ANALYSIS == MIF_DC){ /* initialize time values */ t1 = cm_analog_get_ptr(T1,0); t2 = cm_analog_get_ptr(T2,0); t_end = cm_analog_get_ptr(T3,0); *t1 = -1; *t2 = -1; *t_end = 0; OUTPUT(out) = output_low; PARTIAL(out,cntl_in) = 0; }else if(ANALYSIS == MIF_TRAN){ /* Retrieve previous values and set equal to corresponding variables */ phase = cm_analog_get_ptr(INT1,0); phase1 = cm_analog_get_ptr(INT1,1); t1 = cm_analog_get_ptr(T1,1); t2 = cm_analog_get_ptr(T2,1); t_end = cm_analog_get_ptr(T3,1); time1 = *t1; time2 = *t2; t_start = *t_end; /* Allocate storage for breakpoint domain & freq. range values */ x = (double *) calloc(cntl_size, sizeof(double)); if (x == '\0') { cm_message_send(triangle_allocation_error); return; } y = (double *) calloc(freq_size, sizeof(double)); if (y == '\0') { cm_message_send(triangle_allocation_error); return; } /* Retrieve x and y values. */ for (i=0; i<cntl_size; i++) { *(x+i) = PARAM(cntl_array[i]); *(y+i) = PARAM(freq_array[i]); } /* Retrieve cntl_input value. */ cntl_input = INPUT(cntl_in); /* Determine segment boundaries within which cntl_input resides */ /*** cntl_input below lowest cntl_voltage ***/ if (cntl_input <= *x) { dout_din = (*(y+1) - *y)/(*(x+1) - *x); freq = *y + (cntl_input - *x) * dout_din; if(freq <= 0){ cm_message_send(triangle_freq_clamp); freq = 1e-16; } /* freq = *y; */ } else /*** cntl_input above highest cntl_voltage ***/ if (cntl_input >= *(x+cntl_size-1)){ dout_din = (*(y+cntl_size-1) - *(y+cntl_size-2)) / (*(x+cntl_size-1) - *(x+cntl_size-2)); freq = *(y+cntl_size-1) + (cntl_input - *(x+cntl_size-1)) * dout_din; /* freq = *(y+cntl_size-1); */ } else { /*** cntl_input within bounds of end midpoints... must determine position progressively & then calculate required output. ***/ for (i=0; i<cntl_size-1; i++) { if ((cntl_input < *(x+i+1)) && (cntl_input >= *(x+i))){ /* Interpolate to the correct frequency value */ freq = ((cntl_input - *(x+i))/(*(x+i+1) - *(x+i)))* (*(y+i+1)-*(y+i)) + *(y+i); } } }/* Instantaneous phase is the old phase + frequency/(delta time) int_cycle is the integer value for the number cycles. */ *phase = *phase1 + freq*(TIME - T(1)); int_cycle = *phase1; dphase = *phase1 - int_cycle; /* if the current time is greater than time1, but less than time2, calculate time2 and set the temporary breakpoint. */ if((time1 <= TIME) && (TIME <= time2)){ time2 = T(1) + (1 - dphase)/freq; if(TIME < time2){ cm_analog_set_temp_bkpt(time2); } /* store the time that the next cycle is scheduled to begin */ t_start = time2; /* set output value */ OUTPUT(out) = output_hi - ((TIME - time1)/(time2 - time1))* (output_hi - output_low); }else{ /* otherwise, calculate time1 and time2 and set their respective breakpoints */ if(dphase > d_cycle){ dphase = dphase - 1.0; } time1 = T(1) + (d_cycle - dphase)/freq; time2 = T(1) + (1 - dphase)/freq; if((TIME < time1) || (T(1) == 0)){ cm_analog_set_temp_bkpt(time1); } cm_analog_set_temp_bkpt(time2); /* set output value */ OUTPUT(out) = output_low + ((TIME - t_start)/(time1 - t_start))* (output_hi - output_low); } PARTIAL(out,cntl_in) = 0.0; /* set the time values for storage */ t1 = cm_analog_get_ptr(T1,0); t2 = cm_analog_get_ptr(T2,0); t_end = cm_analog_get_ptr(T3,0); *t1 = time1; *t2 = time2; *t_end = t_start; } else { /* Output AC Gain */ /* This model has no AC capabilities */ ac_gain.real = 0.0; ac_gain.imag= 0.0; AC_GAIN(out,cntl_in) = ac_gain; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -