⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dac1_fgen1.c

📁 用C8051F单片机的DAC作函数发生器
💻 C
📖 第 1 页 / 共 2 页
字号:
            break;
         } // end if
      
      }// end for
      
      // call the associated function
      f = (void *) function_table[i].function_ptr;
      f();         
      
      EA = 1;                               // re-enable interrupts
        
   } // end while(1)

} // end main

//-----------------------------------------------------------------------------
// Init Routines
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// SYSCLK_Init
//-----------------------------------------------------------------------------
//
// This routine initializes the system clock to use a 22.1184MHz crystal
// as its clock source.
//
void SYSCLK_Init (void)
{
   int i;                           // delay counter

   OSCXCN = 0x67;                   // start external oscillator with
                                    // 22.1184MHz crystal

   for (i=0; i < 256; i++) ;        // Wait for osc. to start up
   
   while (!(OSCXCN & 0x80)) ;       // Wait for crystal osc. to settle

   OSCICN = 0x88;                   // select external oscillator as SYSCLK
                                    // source and enable missing clock
                                    // detector

}

//-----------------------------------------------------------------------------
// PORT_Init
//-----------------------------------------------------------------------------
//
// Configure the Crossbar and GPIO ports
//
void PORT_Init (void)
{
   XBR0     = 0x04;                 // Enable UART0
   XBR1     = 0x00;
   XBR2     = 0x40;                 // Enable crossbar and weak pull-up
   P0MDOUT |= 0x01;                 // Set TX0 pin to push-pull
}

//-----------------------------------------------------------------------------
// Timer4_Init
//-----------------------------------------------------------------------------
// This routine initializes Timer4 in auto-reload mode to generate interrupts
// at intervals specified in <counts>.
//
void Timer4_Init (int counts)
{
   T4CON = 0;                       // STOP timer; set to auto-reload mode
   CKCON |= 0x40;                   // T4M = '1'; Timer4 counts SYSCLKs
   RCAP4 = -counts;                 // set reload value
   T4 = RCAP4;
   EIE2 |= 0x04;                    // enable Timer4 interrupts
   T4CON |= 0x04;                   // start Timer4
}

//-----------------------------------------------------------------------------
// UART0_Init
//-----------------------------------------------------------------------------
//
// Configure the UART0 using Timer1, for <baudrate> and 8-N-1.
//
void UART0_Init (void)
{
   SCON0   = 0x50;                  // SCON0: mode 1, 8-bit UART, enable RX
   TMOD    = 0x20;                  // TMOD: timer 1, mode 2, 8-bit reload
   TH1    = -(SYSCLK/BAUDRATE/16);  // set Timer1 reload value for baudrate
   TR1    = 1;                      // start Timer1
   CKCON |= 0x10;                   // Timer1 uses SYSCLK as time base
   PCON  |= 0x80;                   // SMOD0 = 1
   TI0    = 1;                      // Indicate TX0 ready
}

//-----------------------------------------------------------------------------
// Print_Command_List
//-----------------------------------------------------------------------------
//
// Prints the command list to the standard output.
//
void Print_Command_List (void)
{
printf ("\n\
 SQ - Square Wave\n\
 SI - Sine Wave\n\
 TR - Triangle Wave\n\
 SA - Saw Tooth Wave\n\
 OF - Output OFF\n\
 ?? - Help\n\n");

}

//-----------------------------------------------------------------------------
// Sine
//-----------------------------------------------------------------------------
//
// Sets output to a sine wave.
//
void Sine (void)
{
   output_waveform = SINE;
   // print this message: *** OUTPUT IS NOW A SINE WAVE
   printf ("%sSINE WAVE%s",string0,string1); 
   Print_Command_List();

}

//-----------------------------------------------------------------------------
// Square
//-----------------------------------------------------------------------------
//
// Sets output to a square wave.
//
void Square (void)
{
   output_waveform = SQUARE;
   // print this message: *** OUTPUT IS NOW A SQUARE WAVE
   printf ("%sSQUARE WAVE%s",string0,string1);
   Print_Command_List();

}

//-----------------------------------------------------------------------------
// Triangle
//-----------------------------------------------------------------------------
//
// Sets output to a triangle wave.
//
void Triangle (void)
{
   output_waveform = TRIANGLE;
   // print this message: *** OUTPUT IS NOW A TRIANGLE WAVE
   printf ("%sTRIANGLE WAVE%s",string0,string1);
   Print_Command_List();

}

//-----------------------------------------------------------------------------
// Saw
//-----------------------------------------------------------------------------
//
// Sets output to a saw tooth wave.
//
void Saw (void)
{
   output_waveform = SAW;
   // print this message: *** OUTPUT IS NOW A SAW TOOTH WAVE
   printf ("%sSAW TOOTH WAVE",string0,string1);
   Print_Command_List();
}

//-----------------------------------------------------------------------------
// Off
//-----------------------------------------------------------------------------
//
// Sets output to zero volts DC.
//
void Off (void)
{
   printf ("\n\n*** OUTPUT OFF",string1);
   output_waveform = OFF;
   Print_Command_List();

}

//-----------------------------------------------------------------------------
// Help
//-----------------------------------------------------------------------------
//
// Prints the command list.
//
void Help (void)
{
   Print_Command_List();
}

//-----------------------------------------------------------------------------
// Error
//-----------------------------------------------------------------------------
//
//  Indicates that an invalid command was entered at the command prompt.
//
void Error(void)
{
   printf ("   ***INVALID INPUT = %s\n", input_str);

}

//*****************************************************************************
// Interrupt Handlers
//*****************************************************************************

//-----------------------------------------------------------------------------
// Timer4_ISR -- Wave Generator
//-----------------------------------------------------------------------------
//
// This ISR is called on Timer4 overflows.  Timer4 is set to auto-reload mode
// and is used to schedule the DAC output sample rate in this example.
// Note that the value that is written to DAC1 during this ISR call is
// actually transferred to DAC1 at the next Timer4 overflow.
//
void Timer4_ISR (void) interrupt 16 using 3
{
   
   static unsigned phase_acc = 0;  // holds phase accumulator
   
   int temp1;                      // the temporary value that passes 
                                   // through 3 stages before being written 
                                   // to DAC1

   int code *table_ptr;            // pointer to the lookup table
   
   lng temporary_long;             // holds the result of a 16-bit multiply

   T4CON &= ~0x80;                 // clear T4 overflow flag
	
   table_ptr = SINE_TABLE;         
   
   phase_acc += phase_add;         // increment phase accumulator 
                                   
  
   // set the value of <temp1> to the next output of DAC1 at full-scale
   // amplitude; the  rails are +32767, -32768 
   switch (output_waveform){
   
      case SINE:
         
         // read the table value
         temp1 = *(table_ptr + (phase_acc >> 8)); 
                    
         break;

      case SQUARE:
         
         // if in the first half-period, then high
         if ( (phase_acc & 0x8000) == 0 ) {
         
             temp1 = 32767;            
           
         } else {
             
             temp1 = -32768;
         }
         
         break;

      case TRIANGLE:
         
         // in first half-period, then  y = mx + b  
         if ( (phase_acc & 0x8000) == 0 ) {                
            
            temp1 = (phase_acc << 1) - 32768; 
                    
         // else, in the second half of period
         } else { 
            
            temp1 = -(phase_acc << 1) + 32767;
         }
         
         break;
         
      case SAW:
         
         temp1 = phase_acc - 32768;
         break;
      
      case OFF:
         
         temp1 = -32768;
         break;
      
      default:
         while(1);
   }

   // Adjust the Gain
   temporary_long.Long = (long) ((long)temp1 * (long)amplitude); 
   
   temp1 = temporary_long.Int[0];  // same as temporary_long >> 16

  
   // Add a DC bias to make the rails 0 to 65535
   // Note: the XOR with 0x8000 translates the bipolar quantity into 
   // a unipolar quantity.
   DAC1 = 0x8000 ^ temp1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -