我有一个中断服务例程,其中包含变量count
和变量state
,当count
达到某个值时会发生变化。
我希望我的代码要做的是在ISR的if语句中由state
的值确定的特定时间段内更改并维护count
。
e.g。我希望变量state
在10个计数中等于1;
我希望state
在5个计数中等于0。
有点类似于改变PWM的占空比。
我遇到的问题是变量state
在ISR结尾或if语句结束时重置为零,我不确定。
在搜索答案之后,我发现它可能与gcc编译器的优化有关,但除了声明我已经完成的volatile
变量之外,我找不到解决这个问题的方法。 / p>
感谢任何帮助。
我的代码:
#include <avr/io.h>
#include <avr/interrupt.h>
volatile int count = 0;
volatile int state = 0;
int main(void)
{
cli();
DDRB |= (1 << PB2);
TCCR0B |= (1 << CS02)|(0 << CS01)|(1 << CS00);
TIMSK |= (1 << TOIE0);
sei();
while(1) {
...
}
}
ISR(TIM0_OVF_vect)
{
cli();
// user code here
count = count + 1;
if ((count > 5) && (state < 1) && !(PORTB & (1 << PB2))) {
state = 1;
count = 0;
}
else if ((count > 10) && (state > 0) && (PORTB & (1 << PB2))) {
state = 0;
count = 0;
}
sei();
}
答案 0 :(得分:0)
首先,你的cli()对你的ISR没有任何影响。当一个中断发生时,I标志自动清除并在ISR结束时恢复 - 所以sei()也是不必要的。然而,当在一个ISR服务中间某处插入sei()以让其他ISR中断它时,有理性的情况。虽然建立如此复杂的ISR系统并非初学者水平。
第二:如果你设置一个条件结构,基本条件应该由双算子链接。评价(计数> 5)&amp; (状态&lt; 1)无法预测,正确写入(计数&gt; 5)&amp;&amp; (州&lt; 1)。显然对于&#39;或&#39; -ing ||使用。
答案 1 :(得分:0)
如果您正在模仿PWM,if
语句的条件看起来很可疑。
为什么要测试端口B的引脚?只有在以正确频率按下引脚(按钮)时,才会输入if
语句的正文。
您的意思是将引脚设置在端口B上吗?那你想要
count = count + 1;
if ((count > 5) && (state < 1)) {
PORTB &= ~(1 << PB2); // clears PB2
state = 1;
count = 0;
}
else if ((count > 10) && (state > 0)) {
PORTB |= 1 << PB2; // sets PB2
state = 0;
count = 0;
}