我的主要目的是为了取得<1ms的时间间隔,这个问题我曾经在贵网站提问过多次,可是没有得到好的答案,现在终于有所发现。根据这本1993年学苑出版社出版的《Programmer's Bible》一书所介绍,并且查阅《微机接口原理》的书,我们可以对系统时钟芯片8254的状态口地址0x43读写状态,对计时器T0,T1,T2的端口地址0x40,0x41,0x42读写计数值,那么就可得到最小单位为1/1193180秒的时间间隔。这样我如果要取得<1ms的时间间隔,只需算出计数值,然后取得中断信号。现在我想在DOS下实现第一步:往0x43写状态,用的是TC,
outport (0x43,0xXX);
rc=inport(0x43);
结果rc=255,并非我给它们的数值,说明该状态口不能写值。试过几遍皆如此。是否存在打开这个端口的开关呢? 在哪儿呢?
outport (0x43,0xXX);
rc=inport(0x43);
结果rc=255,并非我给它们的数值,说明该状态口不能写值。试过几遍皆如此。是否存在打开这个端口的开关呢? 在哪儿呢?
但下面程序却没有任何结果,扬声器没发出任何声音。//让扬声器发出声音
count=1193180/2000;
lo=count & 0xFF;
//modf(count/256,h);
hi=(count & 0xFF00)>>8;
cout<<"count="<<count<<"\n";
cout<<"lo="<<lo<<"\n";
cout<<"hi="<<hi<<"\n";
/*cout<<"count/256="<<count/256<<"\n"; */
//outportb (0x43,0x38);//rc=inportb(0x43);
do{
outportb(0x43,0xb6); //write T2
outportb(0x42,lo);
outportb(0x42,hi);
}while(!kbhit());
unsigned n_port,o_port;
unsigned long count;
//double *h;count=1193180/1000;
lo=count & 0xFF;
//modf(count/256,h);
hi=(count & 0xFF00)>>8;
cout<<"count="<<count<<"\n";
cout<<"lo="<<lo<<"\n";
cout<<"hi="<<hi<<"\n";
/*cout<<"count/256="<<count/256<<"\n"; */
//outportb (0x43,0x38);
o_port=inportb(0x61); //不好意思,忘了加这几句
n_port=o_port | 0x03;
outportb(0x61,n_port);
printf("the old port is :%xH\n",o_port);
printf("the new port is :%xH\n",n_port);
//rc=inportb(0x43);
do{
outportb(0x43,0xb6); //write T2
outportb(0x42,lo);
outportb(0x42,hi);
}while(!kbhit());
o_port=inportb(0x61); //#1
n_port=o_port & 0x0; //#2
outportb(0x61,n_port); //#3
但是若不加#1,#2,#3这几句,当程序执行完了之后,声音才出来。
如:对某个计数器进行状态锁存,读出的(从计数器端口)的低六位就是写入该
计数器的控制字,D7位是该计数器输出值OUT的状态,OUT为高电平则D7为1,
D6位反映预置寄存器中的计数值是否写入了减1计数器,当向计数器通道写入控制字
和计数值后,D6为1,只有当预置寄存器中的计数值写入了减1计数器,则D6=0
所以在状态字D6=1时,读取计数值是无意义的
driver develop.com上的朋友qizhi告诉我:关于PC机系统的82C54/53的使用有几个问题需要考虑:
1:标准PC的82C54的定时/计数器0用于向系统的日时钟发出定时中断。所以,如果你的机器是标准配置的PC机,该82C54你肯定不能用,否则会危急系统;同时,也不能修改其定时计数初值。其标准的输出为18.2Hz.如果其它的PC机配置我还不直到。
2:标准PC的82C54的定时/计数器1用于系统的RAM刷新。但是新的PC中该通道似乎不用了,或许可以考虑此通道。
3:标准PC的82C54的定时/计数器2用于给扬声器提供发声控制。另外,你回读8254控制字(非状态字!)的方法不对,且在我的记忆中,控制字似乎也不是每位都可读的。另外,8253、8254、82C53、82C54等还可能有细微的区别,详细的需要仔细查找其DATASHEET(PDF格式)来分析。另外,对控制口(0x43)操作时需要注意,该口同时操作3个定时/计数器,所以其数据非常关键。你的提问中数据以0xXX示出,说明你可能对此问题有所忽视。
判断8254是否可用/程序是否对,可以在DOS下,对其2号通道操作,因为结果可以直接从扬声器得到。确认了82C54可操作后,再确认是否可以借助其通道1/0(假如可用)来产生1mS以下的中断。对此你们有何建议?回到上面的程序,为什么不加#1,#2,#3这几句时,当程序执行完了之后,声音才出来。而加了这几句之后,声音也没怎么听见?