我的主要目的是为了取得<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,并非我给它们的数值,说明该状态口不能写值。试过几遍皆如此。是否存在打开这个端口的开关呢? 在哪儿呢?

解决方案 »

  1.   

    8254和8253类似,inport(0x43)是无操作的,也就是说是禁止读的!只能往里写命令!这接口书里面应该有的!可以看一下电子工业出版的(微机原理与接口技术)写的关于8253的内容!
      

  2.   

    的确,如你所言,该控制字不能读,只能写。
    但下面程序却没有任何结果,扬声器没发出任何声音。//让扬声器发出声音
    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());
      

  3.   

    unsigned lo,hi;
     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这几句,当程序执行完了之后,声音才出来。
      

  4.   

    Windows下怎么办,必须写驱动吗?
      

  5.   

    读回命令是写入控制口的,但读取状态字是从对应计数器的端口读出的。
    如:对某个计数器进行状态锁存,读出的(从计数器端口)的低六位就是写入该
    计数器的控制字,D7位是该计数器输出值OUT的状态,OUT为高电平则D7为1,
    D6位反映预置寄存器中的计数值是否写入了减1计数器,当向计数器通道写入控制字
    和计数值后,D6为1,只有当预置寄存器中的计数值写入了减1计数器,则D6=0
    所以在状态字D6=1时,读取计数值是无意义的
      

  6.   

    不用讨论读回命令了吧!
    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这几句时,当程序执行完了之后,声音才出来。而加了这几句之后,声音也没怎么听见?