我想测量脉冲持续时间,但我需要测量4个信号,因此我不能使用定时器捕获中断,因为只有1个引脚ICP1提供该选项(或可以?)。所以我尝试实现类似arduino pulseIn的东西,区别在于我使用的是计时器(arduino有一些其他的实现,但非常相似)。
实际问题是pulseIn没有返回任何东西,只是继续在无限循环中工作。
使用ATmega16。 现在仅在PB2上进行测试。
unsigned long pulseIn()
{
unsigned long duration = 0;
DDRB = 0x00;
/* Initiate timer and wait for the end of previous pulse*/
initTime1();
while(getPortBPin(2) == 1);
/* Wait for current pulse begin */
while(getPortBPin(2) != 1);
/* Time before previous pulse ended */
TCNT1 = 0;
overflowCounter = 0;
/* Wait for current pulse end */
while(getPortBPin(2) == 1);
/* Closk freq is 2 MHz = 1/2 us per tick */
duration = (TCNT1+overflowCounter*65536)/2;
overflowCounter = 0;
stopTimer1();
return duration;
}
void initTime1()
{
/* Noise filtering */
TCCR1B = (1 << ICNC1);
/* Set prescaling factor to 8 */
TCCR1B |= (1 << CS11);
/* Enable overflow interruption */
TIMSK = (1 << TOIE1);
/* Clear counter */
TCNT1 = 0;
}
void stopTimer1()
{
TCCR1B = 0;
TIMSK = 0;
TCNT1 = 0;
}
uint8_t getPortBPin(uint8_t pin)
{
if(pin < 0 || pin > 8)
{
return 0;
}
return (uint8_t)((PINB >> pin) & 0x01);
}
更新
这是我的抗议计划。信号来自发电机。频率为1kHz,宽度为50%。 mplmplitude是5伏特。
更新
抱歉,这是一个愚蠢的错误。它工作正常。我调试的东西没有按预期工作。答案 0 :(得分:1)
我无法找到代码中的问题所在。但这里有一些我可以遵循的调试步骤:
1)引脚总是读什么?逻辑1
或0
,可能脉冲电压不够高,因此AVR无法感知它。
2)duration = (TCNT1+overflowCounter*65536 - timestamp)/2;
中的乘法占用了大量CPU时间,可能需要比脉冲更多的时间,因此在AVR进入最后while
循环之前脉冲变低。当然,这取决于脉冲是连续的还是只有一个脉冲。此外,我不知道你为什么使用timestamp
,因为你已经清除了overflowcounter
。我想这行应该删除。
<强>更新强>
为了测量四个信号脉冲,我建议使用PORTB更改中断,当中断发生时,你可以屏蔽端口以查看哪个信号已经改变并计算它的持续时间。