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

📄 dmastrm.c

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

	FILE NAME: DMASTRM.C

	FILE DESCRIPTION: DMASTRM (Direct Memory Acces with the PC's DMA chip)

	 Sample program that demonstrates how to use DMA transfer.

	 This program stores acquired data into a buffer at a designated rate
	 using DMA transfers. When the requested number of samples have been
	 transferred to the buffer, the data will be graphed on the screen.

	PROJECT NAME: DMASTRM (Part of DM6430 DOS Driver)

	DRIVER VERSION: 1.1

	COMPILER: Borland C++ 3.1

	TARGET: Real-Mode DOS

	Copyright 2003 RTD Embedded Technologies

***************************************************************************/
#include <alloc.h>
#include <conio.h>
#include <dos.h>
#include <mem.h>
#include <stdio.h>
#include "drvr6430.h"
#include "dio5812.h"
#include "dmautil.h"
#include "pcutil.h"
#include "vgraph.h"

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

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

#define DMA_BUF_SIZE   10000l	   		// The size of the DMA buffer (32768 max).
#define BASE_ADDRESS   768             // Base address.


#define CHANNEL         0              // A/D channel.
#define GAIN            0              // Gain.
#define SE_DIFF         0              // Single ended.
#define RATE     100000.0              // Sampling rate.
#define ADDMAChannel	   7              // DMA Channel.
#define IRQ_CHANNEL    10              // IRQ Channel.

// To set DMA Mode Register
#define MODE_REGISTER (DMA_DEMAND_TRANSFER | DMA_WRITE | DMA_INCREMENT_COUNTER)


volatile int Transfers = 0;
volatile Error = 0, Busy = 0;
volatile int i = 0;
unsigned long NumberofBytes;
int far * DMAPtr1;
int far * DMAPtr2;
unsigned int DMAPage[2], DMAPageOffset[2];




/****************************************************************************
  NewISR()

  The NewISR function is called whenever an interrupt is generated on the
  specified IRQ. It simply checks the busy flag to see if the last transfer
  was completed, swaps the buffers to transfer to disk, increments the
  "Transfers" variable and clears the DMA done flag.

  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
{
  if (Busy == 1) Error = 1;           // Make sure write to disk is done

  ClearADDMADone6430();
  if(i==0){
	  i = 1;
	SetDMAController(ADDMAChannel, MODE_REGISTER, DMAPage[i], DMAPageOffset[i], NumberofBytes);  // Set DMA Controller.
  }
  else{
	  i = 0;
	SetDMAController(ADDMAChannel, MODE_REGISTER, DMAPage[i], DMAPageOffset[i], NumberofBytes);  // Set DMA Controller.
  }
  EnableDMA(ADDMAChannel);             // Enable DMA.
  Transfers++;
  ClearIRQ16430();							// Clear IRQ on DM6430.
  EndOfIT(IRQ_CHANNEL);                // VERY IMPORTANT !!!

}




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

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

void SetProgramScreen(void)
{
	clrscr();

	// Print header and footer.
	gotoxy(1,1);   cprintf(TitleString6430());
	gotoxy(50, 1); cprintf("DMA Example");
	gotoxy(1, 25); cprintf("Press enter key to start. . .   ");

	gotoxy(30, 8); cprintf("Transfers =");
} //SetProgramScreen




int main(void){

	FILE* DataFile;
	unsigned long ClockRate;
	int Test;
	float Range;
	float Slope;
	unsigned NumberOfPoints;
	double Actual_PACER_RATE;

	clrscr();

	NumberofBytes = (long)(DMA_BUF_SIZE) * 2L;

	// Allocating first memory buffer for DMA.
	DMAPtr1 = allocdmabuffer(NumberofBytes, ADDMAChannel, &DMAPage[0], &DMAPageOffset[0]);
	if (DMAPtr1 == NULL)  {
		cprintf("Buffer 1 allocation has failed.");
		getch();
		return 1;
	} //if
	_fmemset(DMAPtr1, 0x00, NumberofBytes );		// Set buffer to all 0.

	// Allocating second memory buffer for DMA.
	DMAPtr2 = allocdmabuffer(NumberofBytes, ADDMAChannel, &DMAPage[1], &DMAPageOffset[1]);
	if (DMAPtr2 == NULL)  {
		cprintf("Buffer 2 allocation has failed.");
		getch();
		return 1;
	} //if
	_fmemset(DMAPtr2, 0x00, NumberofBytes );		// Set buffer to all 0.

	SetProgramScreen();
	Test = 0;


	SetBaseAddress(BASE_ADDRESS);       // Set BaseAddress

	InitBoard6430();                    // Initialize board.
	Actual_PACER_RATE = SetPacerClock6430(RATE);	// Program the pacer clock.
	SetChannelGain6430(CHANNEL, GAIN, SE_DIFF); // Set channel and gain.
	SetTriggerRepeat6430(0);            // Single Cycle.
	SetStartTrigger6430(0);             // Start Trigger = Software.
	SetStopTrigger6430(0);              // Stop Trigger = Software.
	SetConversionSelect6430(1);         // Conversion = Pacer Clock.

		// Set up data file and write header.
	ClockRate = Actual_PACER_RATE;	// Clock rate.
	Range = 20;								// A/D input range.
	Slope = (20.0/65536.0);				// A/D volt per bit.
	NumberOfPoints = DMA_BUF_SIZE;	// Number of samples in 1 buffer.
	DataFile = fopen("DMASTRM.DAT", "wb");		// Open data file.
	fwrite(&ClockRate, sizeof(ClockRate), 1, DataFile);
	fwrite(&Range, sizeof(Range), 1, DataFile);
	fwrite(&Slope, sizeof(Slope), 1, DataFile);
	fwrite(&NumberOfPoints, sizeof(NumberOfPoints), 1, DataFile);


	SetADDMA6430(ADDMAChannel, 0); 		// Program the board for DMA.
	SetDMAController(ADDMAChannel, MODE_REGISTER, DMAPage[0], DMAPageOffset[0], NumberofBytes);  // Set DMA Controller.

	SetIRQ16430(5, IRQ_CHANNEL);        // Set Board IRQ1 Source = DMA Done.
	ClearIRQ16430();							// Clear IRQ on DM6430.
	InitHostIT(NewISR,IRQ_CHANNEL);     // Set the Interrupt Service Routine.
													// Set IRQ Channel.
	ClearADFIFO6430();                  // Clear FIFO.
	EnableDMA(ADDMAChannel); 	         // Enable DMA in CPU.

	getch();
	gotoxy(1, 25); cprintf("Press enter key to stop. . .   ");

	StartConversion6430();              // Start the measurement.

	while (!kbhit()){
		if (Error == 1){                 // Check error flag.
			cprintf("Buffer Overflow %d",Transfers);
			goto exiterror;
		}
		if (Test != Transfers){				// If interrupted, write to disk.
			Busy = 1;							// Set busy flag.
			if (i==0){
				fwrite(DMAPtr2, sizeof(int), NumberOfPoints, DataFile);
			}
			else{
				fwrite(DMAPtr1, sizeof(int), NumberOfPoints, DataFile);
			}
			Test ++;								// Increment "Test" variable.
			gotoxy(45,8); cprintf("%d",Transfers);
			Busy = 0;							// Reset busy flag.
		}
	}
	getch();
exiterror:

	gotoxy(1, 25); cprintf("Press enter key to graph. . .   ");
	DisableDMA(ADDMAChannel);           // Disable DMA channel in CPU.
	ClearADDMADone6430();                // Clear DMA done flag on board.
	RestoreHostIT(IRQ_CHANNEL);          // Restores the IT vector and disable.
	SetIRQ16430(0,0);				          // Disable board IRQ.
	fclose(DataFile);                    // Close Data file.
	freedmabuffer(DMAPtr1);              // free DMA Buffer 1.
	freedmabuffer(DMAPtr2);              // free DMA Buffer 2.
	getch();
	vgraph("DMASTRM.DAT");               // Graph data.
	clrscr();                            // Clear screen.
	return 0;
} //main

⌨️ 快捷键说明

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