中级会员
- 积分
- 257
- 威望
- 146
- 贡献
- 67
- 兑换币
- 80
- 注册时间
- 2013-3-15
- 在线时间
- 22 小时
- 毕业学校
- USTC
|
是用输入捕捉功能测一个脉冲的宽度。其实就是超声波测距的那个HC-SR04,这个模块返回来的东西是一个持续若干毫秒的方波脉冲。我要用输入捕捉测量这个宽度。
注意用的是输入捕捉,不是像看到的很多例子的那个输入捕捉,那个应该称为外部中断,因为根本没有用真正意义上的输入捕捉。。
输入捕捉就是,当发生事件匹配时,由硬件把当前计数器的值(TCNT)保存到一个寄存器中(TCx),不是使能计数器设置累计变量什么的。
测脉宽就是这样,这里是用的是T0口:
1、设置为上升沿触发,使能中断;
2、上升沿到来后,(通过if判断知道到来的是上升沿),在中断服务程序中改为下降沿触发;
3、下降沿到来后,(通过if判断知道到来的是下降沿),在同一个中断服务程序中,把TC0的值存起来。wtemp=TC0;
这是wtemp就是脉宽。
框架程序如下:
us0Trig = 1;//这是触发信号,一个10us的脉冲
TCTL4_EDG0A=1;
TCTL4_EDG0B=0;//设置成rising edge触发
Delay_us(10);
us0Trig = 0;//触发信号发送完毕 trig send ok
TIE_C0I = 1;//使能中断
Delay_ms(100);//在这100ms里,完成测脉宽的工作。(中断函数执行两次,第一次上升沿,第二次下降沿)
中断程序如下:
void interrupt VectorNumber_Vtimch0 us0measure(void){
//第一个超声波的中断函数
TFLG1_C0F = 1;//clear flag清标志
if(TCTL4_EDG0A == 1){//如果刚才来到的是上升沿
//上升沿来到
TCTL4_EDG0A = 0;
TCTL4_EDG0B = 1;//falling就改成下降沿触发,等下一个下降沿的到来
TCNT = 0;//clear timer这是下面的第二个问题
//return;
}else{
//下降沿来到
//disable intt
wtemp = TC0;//保存TC0,这个就是Capture到的脉宽。
TIE_C0I = 0;
//sprintf(szBuffer,"MeasTC0:%d",wCntCaptured[bCntMeasured-1]);其实是测量几次取最小值,这里略去
}
//LCD_write_english_string(0,3,szBuffer);
return;
}
wtemp就是了。
出现了诡异的问题。本来用的好好的,可以在5110上显示距离。但是连上一大堆别的东西后就不行了。
然后把外围的东西都拔掉,还是有问题。
是这样的:如果用BDM供电,按下F5后,单击“Run”,非常好,可以准确测距。
如果用7805供电,出来的结果是一坨烂玩意。但是,所有的中断都执行了。
不会是供电的问题,因为:如果我用BDM供电,但是按系统板上的“复位”按钮,出来的又是一堆垃圾。
看起来,像是TCNT是乱飞的,或者,是没有在合适的地方清零。
而用7805,本质上是按复位按钮。所以姑且认为,唯一的区别是“单击调试工具上的复位(运行)”和“按下系统板上的复位”。
这他么怎么就不一样呢!!!求解答。
还有,我想知道匹配发生的时候,TCNT是什么状态?清零?还是接着跑(free running)?
数据手册上的意思好像是接着跑,但是如果接着跑,我上面的程序是永远不可能得到正确结果的,但是我曾经得到过。而且,没有发现给TCNT清零的方法。上面写的是:Write: Has no meaning or effect in the normal mode;
那这个计数器到底是怎么跑的呢。
还有,这个模块貌似只有一个timer,那如果有好几个InputCapture,如果是清零的话岂不要乱套。但是。。。
这到底是怎么回事呢?有没有同志研究过这个玩意儿?
|
|