Skip to main content
Engineering LibreTexts

3.2: The Program

  • Page ID
    25691
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    The program is presented in chunks, below, in the sequence you might write it. First comes the main skeleton.

    #include <stdio.h>
    #include <math.h>
    
    #define VOLTAGE_DIVIDER       1
    #define EMITTER               2
    #define COLLECTOR_FEEDBACK    3
    #define VBE .7
    
    int main( void )
    {
          int choice;
    
          give_directions();
          choice = get_choice();
    
          switch( choice )
          {
                case VOLTAGE_DIVIDER:
                      voltage_divider();
                      break;
    
                case EMITTER:
                      emitter();
                      break;
    
                case COLLECTOR_FEEDBACK:
                      collector_feedback();
                      break;
    
                default:    /* tell user they’re not so bright... */
                      printf(“No such choice!\n”);
                      break;
          }
    }
    

    The first two functions might look something like this (don’t forget to add their prototypes later):

    void give_directions( void )
    {
          printf(“DC Bias Q Point calculator\n\n”);
          printf(“These are your bias choices:\n”);
          printf(“1. Voltage Divider\n”);
          printf(“2. Two Supply Emitter\n”);
          printf(“3. Collector Feedback\n”);
    }
    
    int get_choice( void )
    {
          int ch;
    
          printf(“Enter your choice number:”);
          scanf(“%d”, &ch);
          return( ch );
    }
    

    Now it’s time to write the bias functions. Here is how the voltage_divider() function might look:

    void voltage_divider( void )
    {
          double vcc, vth, r1, r2, rth, re, rc, beta, ic, icsat, vce;
    
          printf(“Enter collector supply in volts”);
          scanf(“%lf”, &vcc);
          printf(“Enter current gain (beta or hfe)”);
          scanf(“%lf”, &beta);
          printf(“Please enter all resistors in ohms\n”);
          printf(“Enter upper divider resistor”);
          scanf(“%lf”, &r1);
          printf(“Enter lower divider resistor”);
          scanf(“%lf”, &r2);
          printf(“Enter collector resistor”);
          scanf(“%lf”, &rc);
          printf(“Enter emitter resistor”);
          scanf(“%lf”, &re);
    
          vth = vcc*r2/(r1+r2);
          rth = r1*r2/(r1+r2);
          ic = (vth-VBE)/(re+rth/beta);
          icsat = vcc/(rc+re);
    
          if( ic >= icsat )
          {
                printf(“Circuit is in saturation!\n”);
                printf(“Ic = %lf amps and Vce = 0 volts\n”, icsat );
          }
          else
          {
                vce = vcc-ic*(re+rc);
                printf(“Ic = %lf amps and Vce = %lf volts\n”, ic, vce );
           }
    }
    

    The other two bias functions would be similar to this. A few points to note: In order to obtain the absolute value, consider using the fabs() function (floating point absolute). Another approach to the program would be make the vce, icsat, and ic variables globals and move the printout section to main() because the final comparison and printout will be the identical in all three functions. (It is also possible to have the functions return the values via pointers, avoiding the need for globals.)

    Complete the other two bias functions, build, and test the program. Use the following values: Trial #1, Two supply emitter bias, Vcc = 20 V, Vee = −10 V, Rb = 2 k\(\Omega\), Re = 1 k\(\Omega\), Rc = 1.5 k\(\Omega\), beta = 100. Trial #2, Collector feedback bias, Vcc = 30 V, Rc = 10 k\(\Omega\), Re = 1 k\(\Omega\), Rb = 100 k\(\Omega\), beta = 100. To avoid compiler warnings, you will need to place function prototypes before main(). You could place these in a separate header file, but there are too few to bother with. To create the prototypes, simply copy and paste the function declarations and add a trailing semi-colon. For example:

    #define VBE .7
    
    void give_directions( void );
    int get_choice( void );
    /* and so forth */
    
    void main( void )
    {
          ...
    

    Without the prototypes, the compiler won’t “know” what the functions take as arguments nor what sort of variables they return (if any). Thus, the compiler can’t do type checking and will warn you about this. Also, the compiler will assume default argument and return types of int, so when the compiler sees the function code, it will complain that the types don’t match the default. This might seem like a pain at first, but it is a cross-checking mechanism that can prevent many software bugs.


    This page titled 3.2: The Program is shared under a CC BY-NC-SA 4.0 license and was authored, remixed, and/or curated by James M. Fiore via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.