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

📄 pm515i.c

📁 用于ad板de采样
💻 C
字号:
/*
此程序演示了PM515使用外触发信号启动AD并产生中断,
Ad转换结束也产生中断,
要想使此程序运行正常需要将PM515作如下设置:
将计数器0输入与OCLK相接,计数器0输出与EI相接
也就是将J3的11脚12脚短接,13脚14脚短接
*/

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

void interrupt (*oldvect)(void);/*用于保存原始中断处理函数*/
void interrupt pm515v(void);	/*当前中断处理函数*/

unsigned short i=0;
unsigned short vc[1000];	/*保存数据原始值*/


int   iIrq;


char eiflag=0;				/*外触发中断标志*/
char adiflag=0;				/*AD转换结束中断标志*/
char irqflag=0;				/*有中断标志*/

/*分别记录总中断次数,AD转换结束中断次数和外触发中断次数*/
int irqnum=0,adinum=0,einum=0;

long ztpm515readc(unsigned short baseaddr,short chn){
	long ret=0,l=0,h=0;
	long nch=0;
	nch=chn%3;
	l=inportb(baseaddr+0x8+nch);
	h=inportb(baseaddr+0x8+nch);
	ret=h*0x100+l;
	return ret;
}

long ztpm515setc(unsigned short baseaddr,short chn,short nstytle){
	long nch=0;
	nch=chn%3;
	outportb(baseaddr+0xb,0x30+(nstytle<<1)+(nch<<6));
	return nstytle;
}

long ztpm515writec(unsigned short baseaddr,short chn,long nvalue){
	long nch=0;
	nch=chn%3;
	outportb(baseaddr+0x8+nch,nvalue&0xff);
	outportb(baseaddr+0x8+nch,(nvalue>>8)&0xff);
	return 0;
}

//板卡基地址
unsigned short base=0x100;

void main()
{
 FILE *pFile;

 int   j=0;
 int   iHz;
 float v[1000];			/*保存转换后的电压值*/


 clrscr();

 pFile = fopen("Test.txt", "wra+");
 
 printf("\nPlease Input IRQ No:");
 scanf("%d", &iIrq);

 disable();
 oldvect=getvect(0x08 + iIrq);	/*保存原始中断5处理函数*/
 setvect(0x08 + iIrq, pm515v);	/*设定中断5处理函数*/
 inport(base+2);		/*清中断标志位*/
 outportb(0x21,0);		/*使能中断*/
 outportb(0x20,0x25);
 enable();

 outportb(base,0);		/*选择0通道*/

 /*选择外触发启动AD方式,使能中断*/
 outportb(base+1,0xe);
 /*关于base+1寄存器说明:
   bit0:判断Ad转换是否完成,只读
   bit1:外触发启动AD使能,1:外触发启动AD,0:软件启动AD,读写
   bit2:外触发信号产生中断,读写
   bit3:AD转换结束信号产生中断,读写*/

 /*将计数器0设置成方式3方波发生器*/
 ztpm515setc(base, 0, 3);
 /*分频系数设成10000,这样计数器0将产生100Hz的脉冲输出*/

 printf("\n\nPlease input sample Frequency:\n");
 scanf("%d", &iHz);

 //ztpm515writec(base, 0, 10000);
 ztpm515writec(base, 0, 1000000/iHz);

 /*使能OCLK输出*/
 outportb(base+5,1);
 /*关于base+5寄存器说明:
   bit0:读写,0:OCLK引脚没有脉冲输出,1:OCLK引脚有1M脉冲输出
   bit1:只读,0:没有产生中断;1:产生中断
   bit2:只读,0:没有产生外触发中断;1:产生外触发中断
   bit3:只读,0:没有产生AD转换结束中断;1:产生AD转换结束中断*/
   
 /*等待AD转换结束中断产生1000次*/
 while(adinum<1000)
 {
	/*等待1000次转换完成*/
	printf("einum:%d,adinum:%d,irqnum:%d\n",einum,adinum,irqnum);
 }

 /*打印1000个AD转换数据*/
 fprintf(pFile,"Seq\tSample\tVoltage\n");
 for(j=0;j<1000;j++)
 {
   v[j]=vc[j]*10.0/4095.0 - 5.0;	/*将数据转换为电压值*/
   printf("%10.3f",v[j]);

   fprintf(pFile,"%d\t%.3f\n", j, v[j]);
 }


 fclose(pFile);

 //getchar();
 outportb(base+1,0);		/*停止定时启动AD*/
 setvect(0x08 + iIrq, oldvect);		/*恢复原始中断处理函数*/

 printf("\n\nSample OK!\n");
}

unsigned short p=0;
void interrupt pm515v()		/*中断处理函数*/
{
 irqflag = (inportb(base+5)>>1)&7;
 if(irqflag)
	 irqnum++;
 
 /*提取外触发中断标志位*/
 eiflag=(irqflag>>1)&1;

 /*提取AD转换结束中断标志位*/
 adiflag=(irqflag>>2)&1;

 /*如果此次中断是AD转换结束中断则读取数据,同时复位中断*/
 if(adiflag)
 {
  vc[adinum++]= inport(base+2)&0xfff;
  outport(base+6,p);
 }

/*如果此次中断是外触发中断则将外触发中断次数加1,并且复位中断*/
 if(eiflag)
 {
  einum++;
  inport(base+2);
 }

 /*当AD转换结束中断产生1000次后停止中断*/
 if(adinum==1000)
 {
  outportb(base+1,0);		/*停止外触发启动AD*/
  setvect(0x08 + iIrq,oldvect);		/*恢复原始中断处理函数*/
 }
 
 outportb(0x20,0x25);		/*复位系统中断*/
}

⌨️ 快捷键说明

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