[求助]每次读FC的数据,都是不同的,怎样做成延时程序呢?

FC是一个自计数的寄存器,可以用来做成比较准确的延时,具体有谁做过吗?如果第一次读到的数据FF,怎样判断寄存器的计数溢出了呢?谢谢,希望有做过的人贴一小段程序上来,非常感谢。

也遇到此类问题,无法达到50us的精度,导致读数不确定,时序有问题了!


us = // 微秒数 mTime = (UCHAR)( ( 50 * us ) / (ULONG)( 50 * 3.84 ) ); /* 计算硬件计时数, 3.84uS */ CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte ); /* 读取硬件循环计数寄存器 */ mTime += mByte; /* 加上起始值为计数终值 */ while ( mByte != mTime ) CH365mReadIoByte( mIndex, & dllIoBaseAddr[ mIndex ] -> mCh365IoTime, &mByte ); /* 等待计数结束 */


&nbsp是什么,


怎么有乱码的& nbsp


这是以前写的,有的时候不准确 void CH365_SPI_Delay() { LONGLONG QPart1;//,QPart2; // double dfMinus, dfTim; double dfTim=0;

QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart; // »ñµÃ³õʼֵ do { CH365ReadIoByte(&testAddr,&testRead); //dfTim ++; QueryPerformanceCounter(&litmp); dfTim = ((double)(litmp.QuadPart-QPart1)) / dfFreq; }while(dfTim<0.00004990); // if (dfTim<0.000049) { //intf("df=%f\n",dfTim); } }

int main(int argc, char* argv[]) { unsigned long testData; HANDLE dev; BOOL isTrue; QueryPerformanceFrequency(&litmp); dfFreq = (double)litmp.QuadPart; // »ñµÃ¼ÆÊýÆ÷µÄʱÖÓƵÂÊ //CH365ReadIoByte(&testAddr,&testRead);

printf("Now Let's Start to Check The PCI Device\n"); dev = CH365OpenDevice(false,false); if(dev <= 0) { printf("Sorry! Can't Find The Exact Device\n"); exit(0); } //for(int i=0;i<100;i++) CH365_SPI_Delay(); //return 0; }


用计算硬件计时数好像也准确,大家有什么好的方法或者经验吗?

void CH365_SPI_Delay() { LONGLONG QPart1;//,QPart2; // double dfMinus, dfTim; double dfTim=0; UCHAR us = 50;// ΢ÃëÊý UCHAR mTime; UCHAR mByte; QueryPerformanceCounter(&litmp); QPart1 = litmp.QuadPart; mTime = (UCHAR)((50 * us)/(ULONG)(50 *3.84)); /* ¼ÆËãÓ²¼þ¼ÆʱÊý,3.84uS */ CH365ReadIoByte(& m_IOBase->mCh365IoTime,&mByte ); /* ¶ÁÈ¡Ó²¼þÑ­»·¼ÆÊý¼Ä´æÆ÷ */ mTime +=mByte; /* ¼ÓÉÏÆðʼֵΪ¼ÆÊýÖÕÖµ */ /* QueryPerformanceCounter(&litmp); dfTim = ((double)(litmp.QuadPart-QPart1)) / dfFreq;// »ñµÃ¶ÔÓ¦µÄʱ¼äÖµ£¬µ¥Î»ÎªÃë printf("d11f=%f\n",dfTim); */ while (mByte != mTime) CH365ReadIoByte(& m_IOBase->mCh365IoTime, &mByte); /* µÈ´ý¼ÆÊý½áÊø */ QueryPerformanceCounter(&litmp); dfTim = ((double)(litmp.QuadPart-QPart1)) / dfFreq;// »ñµÃ¶ÔÓ¦µÄʱ¼äÖµ£¬µ¥Î»ÎªÃë printf("d22f=%f\n",dfTim); return; }


店小二的答案好像有点问题,如果第一次读的数据是:0xff或者比较德的数,延时就完全不准了。我写的程序如下,请大家评判。 void CCh365::DelayUs(unsigned int us) { unsigned char i,j; i=unsigned char(us); CH365mReadIoByte(Device_Number,&mIoBase->mCh365IoPort[0xfc],&mByte); j=mByte; i=i+j; if(i>=j) { again: CH365mReadIoByte(Device_Number,&mIoBase->mCh365IoPort[0xfc],&mByte); if(mByte goto again; } else { again1: CH365mReadIoByte(Device_Number,&mIoBase->mCh365IoPort[0xfc],&mByte); if((mBytej)) goto again1; } }


海天,我也是刚开始做PCI驱动,比较菜鸟,留个联系方式,以后也可以交流交流!


顶一下,也没有人有这方面的经验啊?


jixiaohu的两个程序, 第一个没有看懂,好象没有很硬件相结合 第二个没有参考价值,那样是不能比较的. 我仍然坚持店小二的做法,不要加任何指令,或者改变变量的类型. 你的数据读出来有误可能是其他的问题.


jixiaohu:我也是第一次做pci的驱动,我觉得店小二的做法问题在于,当WINDOWS其他的线程把(mByte= mTime)的时刻错过去的时候,这个本来只是微秒的延时就变成1毫秒+微秒的延时了。YIN你不这么觉得吗?而我写的程序是一个范围,即使错过1个2个,时间也就错过4微秒或者8微秒,不会误差1毫秒,我的电子信箱是:LCLXY@263.NET,大家可以交流。


一次io操作的时间是0.2-0.5us吧 ,这样好象是不会错过哪个值 的


测试下来好像相差很大,在用户程序中调用CH365mReadIoByte和应用程序中调用CH365mReadIoByte,会不会有什么不一样呢? 也就驱动级别的和App级别会不会不一样?一次io操作的时间不一样? 麻烦大家讨论一下!


但是WINDOWS是一个多任务的操作系统,它的时间是分片给所有的线程的,如果不是这样,那应该SLEEP也是很准的,但SLEEP实际上只有10毫秒的精度.如果是DOS下,我丝毫也不怀疑会错过.但WINDOWS下,简单的延时程序都有长有短,读IO操作怎么就能保证一定在0.2-0.5us读完呢?


经验证正确的程序如下: void CCh365::DelayUs(unsigned int us) { unsigned char i,j; i=unsigned char(us); CH365mReadIoByte(Device_Number,&mIoBase->mCh365IoPort[0xfc],&mByte); j=mByte; i=i+j; if(i>=j) { again: CH365mReadIoByte(Device_Number,&mIoBase->mCh365IoPort[0xfc],&mByte); if(mBytegoto again; } else { again1: CH365mReadIoByte(Device_Number,&mIoBase->mCh365IoPort[0xfc],&mByte); if((mByte=j)) goto again1; } } 跟第7楼比在倒数第4行多了一个等于号,如果没有等于号,有的时候延时不到4微秒就过去了.


只有登录才能回复,可以选择微信账号登录