📄 pm515i.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 + -