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

📄 waves.c

📁 rt采集卡dos下dm6430驱动源代码
💻 C
字号:
/***************************************************************************

	FILE NAME: WAVES.C

	FILE DESCRIPTION: WAVES (Waveform Generator)

    Sample program that demonstrates how to generate and send waveforms
	to the analog output using interrupts.

	This program generates waveforms on the analog output.

	The program works by creating a lookup table that contains a digitized
	version of a selected waveform (square, sine, ramp). The user timer
	is configured to generate interrupts at precise intervals. Every time
	an interrupt occurs a value is read from the lookup table and written
	to the analog output, the index into the lookup table is incremented and
	if it exceeds the length of the waveform it is reset to the beggining of
	the table. This cycle repeats until a key is struck on the keyboard.

	Users who are interested in using their DACs to generate waveforms should
	examine the procedure used for building the lookup table. This procedures
	allow the user to specify the maximum and minimum values as well as the
	number of complete waveforms per second (rate) to be generated. For
	square wave generation, the user can also specify the duty cycle (% high).
	For further details see the comments just prior to the BuildSquareWave
	part of the procedure.

	PROJECT NAME: WAVES (Part of DM6430 DOS Driver)

	DRIVER VERSION: 1.1

	COMPILER: Borland C++ 3.1

	TARGET: Real-Mode DOS

	Copyright 2003 RTD Embedded Technologies

***************************************************************************/

#include <conio.h>
#include <dos.h>
#include <math.h>

#include "drvr6430.h"
#include "dio5812.h"
#include "pcutil.h"

/***************************************************************************
  Defines

  Change these constants to alter the program parameters.
****************************************************************************/

#define BASE_ADDRESS 768						// Base address of DM6430.
#define IRQ_CHANNEL  10							// Interrupt channel.
#define DAC_SLOPE    (65536.0/20.0)  	   // Number Bits divided by DAC Range.
#define DAC_OFFSET   0 	            		// Offset of the output line signal.
#define RATE         1000              	// Clock rate in 'Hz'.

#define SQUARE_WAVE  1                		// For BuildWaveForm().
#define SINE_WAVE    2
#define RAMP_WAVE    3

#define PI           3.14159


// Global definitions
//--------------------

typedef struct WaveStructure           // Structure for waves
	{
	  int WaveLength;
	  int WaveArray[5000];
	};

struct WaveStructure    WaveForm;      // Store built wave
unsigned int            WCnt;          // Wave counter


/***************************************************************************

  NewISR()

  The NewISR() function is called whenever an interrupt is generated on the
  specified IRQ. It outputs a value from the wave array to the DAC then
  increments the index WI.  If WI exceeds the size of the wave array it
  is reset to zero.

  Do not try to access any functions that use DOS calls (disk access, screen
  writes, read keyboard, etc) and do not use floating point operations in
  this function. DOS and the Floating Point Emulator are not reentrant and
  will cause unexpected happenings if used inside an interrupt.

  Before exiting the function passes the End of Interrupt (EOI) command
  to the 8259 interrupt controller. Don't forget the EOI command; it is
  required even if your ISR does nothing.
****************************************************************************/

#ifdef __cplusplus
 void interrupt NewISR(...)            // C++ style interrupt function
#else
 void interrupt NewISR(void)           // C style interrupt function
#endif
{
  LoadDAC6430(WaveForm.WaveArray[WCnt]);      // Send analog output data

  if (++WCnt >= WaveForm.WaveLength){  // If wave data ends it sets
	 WCnt = 0;                          // the wave counter to 0 again
  }
  ClearIRQ16430();							// Clear IRQ on DM6430.
  EndOfIT(IRQ_CHANNEL);                // VERY IMPORTANT !!!
													// 'End of Interrupt' command.
} //NewISR


/*****************************************************************************
 BuildWaveForm()

 The BuildWaveForm() function builds DAC lookup table. The type of the wave-
 form depends on the 'WaveType' variable. For maximum efficiency, a digitized
 version of a waveform is calculated once at the beginning of the program and
 stored in an array.
*****************************************************************************/

void BuildWaveForm( struct WaveStructure *Wave, unsigned int WaveType,
						  float High, float Low, float WaveRate, int OnDuty)
// 'Wave' points to the data structure to fill.
// 'WaveType' determines the type of the waveform: Square, Sine or Ramp.
// 'High' is the maximum values of the waveform in [V].
// 'Low' is the minimum values of the waveform in [V].
// 'WaveRate' defines the frequency of the waveform in [Hz].
// 'OnDuty' defines the percent of square wave when it is high.
{
  int i, j;
  unsigned int DigitalHigh;
  unsigned int DigitalLow;

  gotoxy(10, 12);

  switch (WaveType) {
	 case SQUARE_WAVE: {
		cprintf("Building square waveform, please be patient.");

		DigitalHigh = (High * DAC_SLOPE) + DAC_OFFSET;
		DigitalLow  = (Low * DAC_SLOPE) + DAC_OFFSET;

		Wave->WaveLength = RATE / WaveRate;
		j = Wave->WaveLength * (OnDuty / 100.0);

		for (i = 0; i < j; i++)                    // Generating the High level
		  Wave->WaveArray[i] = DigitalHigh;

		for (i = j; i < Wave->WaveLength; i++)     // Generating the Low level
		  Wave->WaveArray[i] = DigitalLow;
		break;
	 } //case: BuildSquareWave

	 case SINE_WAVE: {
		unsigned int WaveOffset;                 // Offset of the sine wave
		unsigned int PeakHeight;                 // Amplitude of the sine wave

		cprintf("Building sine waveform, please be patient.");

		PeakHeight = ( fabs(High - Low) / 2) * DAC_SLOPE;
		WaveOffset = ( fabs(High + Low) / 2) * DAC_SLOPE + DAC_OFFSET;

		Wave->WaveLength = RATE / WaveRate;

		for (i = 0; i < Wave->WaveLength; i++) {   // Building waveform
		  Wave->WaveArray[i] = PeakHeight *
									  sin((i * 2 * PI) / Wave->WaveLength) +
									  WaveOffset;
		} //for
		break;
	 } //case: BuildSineWave

	 case RAMP_WAVE: {
		unsigned int PeakToPeak;                 // Size of Ramp

		cprintf("Building ramp waveform, please be patient.");

		DigitalHigh = ( High * DAC_SLOPE) + DAC_OFFSET;
		DigitalLow = ( Low * DAC_SLOPE) + DAC_OFFSET;

		PeakToPeak = DigitalHigh - DigitalLow;
		Wave->WaveLength = RATE / WaveRate;

		for (i = 0; i < Wave->WaveLength; i++)    // Build a single ramp
		 Wave->WaveArray[i] = DigitalLow + i *
									 (PeakToPeak / Wave->WaveLength);
		break;
	 } //case: BuildRampWave
  } //switch

  gotoxy(1,12); clreol();
} //BuildWaveForm


/***************************************************************************
  SetProgramScreen()

  The SetProgramScreen() function initializes the screen.
****************************************************************************/

void SetProgramScreen(void)
{
  clrscr();

  // Print header and footer.
  gotoxy( 1, 1); cprintf(TitleString6430());
  gotoxy(40, 1); cprintf("Generating Waveforms on Analog Output");
  gotoxy( 1,25); cprintf("Press any key to exit. . .");

  window(1, 3, 80, 23);
  gotoxy(15, 8); cprintf("Output DAC Channel : ");
} //SetProgramScreen

int main(void)
{
  float ActualRate0;					// Actual clock rate returned from timer 0.

  SetProgramScreen();
  BuildWaveForm(&WaveForm,             // Stores wave
					 SINE_WAVE,             // Type (Square/Sine/Ramp)
					 5.0, -5.0,             // Max and min values in [V]
					 10,                    // Frequency in [Hz]
					 50);                   // Percentage of High (only for Square)

  WCnt = 0;                            // Clear wave counter.

  SetBaseAddress(BASE_ADDRESS);			// Set board base address.
  InitBoard6430();                     // Initialize board.

  ActualRate0 = SetUserClock6430(0, 8000000.0, 20000.0);	// Initialize User Clock0.
  SetUserClock6430(1, ActualRate0, RATE); 		    		// Initialize User Clock1.

  SetIRQ16430(13,IRQ_CHANNEL);         // Set Board IRQ1 Source User TC out 1
													// Set IRQ Channel

  InitHostIT(NewISR,IRQ_CHANNEL);      // Set the Interrupt Service Routine
													// and enable the appropriate IRQ
													// channel.
  ClearIRQ16430();							// Clear IRQ on DM6430.

  while ( !kbhit() ) {                 // Run until any key pressed.
	 gotoxy(37, 8); cprintf("%8d  ", WaveForm.WaveArray[WCnt]);
													// Display the current wave data.
  } //while
  getch();                             // Get the pressed character.

  SetIRQ16430(13,0);   				      // Disable board interrupt.
  RestoreHostIT(IRQ_CHANNEL);          // Restores the IT vector and disable
													// the appropriate IRQ channel.

  DoneTimer6430();                     // Reset timer.

  window(1,1,80,25);                   // Reset original screen coordinates,
  clrscr();                            // and clear the screen.
  return 0;
} //main

⌨️ 快捷键说明

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