调试wince驱动时候,有时候碰到us级别的时序要求的短延时,使用硬件定时器显得麻烦.一般我会用一个短延时delay().今天碰到了离奇事情.
实现一个短延时,用宏,内联函数或者函数都可以实现.下面是一个例子.
#define delay(us) do{/
int t;/
for(;us;us--){/
for(t=TIME_US;t;t--);/
}/
}while(0)
你能想象的出上面代码有什么问题?我使用pb的编译器编译完开始使用上面的延时函数实现一些IO的驱动.竟然发现IO不听我控制!这就像碰到了一些明显违背常理的事情,从而让你开始怀疑1+1不等于2一样糟糕!没有办法,我只好开始做一些基本的IO测试.我让一个IO输出10次方波.结果示波器上只有3次噪声一样的东西!感谢我的示波器,我将波形放大(就是改变周期,呵呵)后看出了端倪.原来是延时时间不够!
因为cpu指令一般有高达数百兆的速度(如果考虑流水线,实际运行速度更快),而IO不会有那么快的响应速度.所以,软件上改变IO频率太快,硬件IO是没有办法跟上的!所以IO状态变化间需要延时.
开始,我以为只是延时函数(宏)延时的时间不够.我改变了上面那个t的初值,更离奇的事情发生了.改变延时后,IO的情况没有一点好转和变化!还是出现一样的噪声!
折腾磨蹭了许久.我突然想到,是不是代码被编译器给优化了?因为直观感觉到像那样的'无用处'的代码是容易成为被优化的对象.这样就会导致实际的延时总达不到预想效果.对付优化,我的手段不是很多,本能的先在变量前面加了volatile.结果成功了!IO重新受到我控制了.(还好成功了,否则我就要展开对编译器的深入透视了,目前可没有时间啊.)