我有一个Atmega328p,想通过按一下按钮打开数字输出,然后在2秒钟后自动关闭它。
我知道如何为按钮使用硬件中断,但是如何设置计时器中断以自动关闭数字输出呢?
更新:
我能够弄清楚。这是我的解决方案(仅显示相关功能):
static inline void initTimer1(void) {
TCCR1B |= (1 << WGM12); // CTC Mode, immediate
TCCR1B |= (1 << CS10) | (1 << CS12); // Clock speed: 16 MHz / 1024, ~= 15.6 ticks per ms
}
void set_valve_on_time(uint16_t on_time) {
OCR1A = on_time; // set output compare register for valve on time
}
void open_valve(uint8_t state) {
if (state > 0) {
PORTD |= (1 << PIND6); //turn on PD6, open valve
PORTD &= ~(1 << PIND7); //turn off PD7, turn off close valve in case it was on
if (state == 2) {
TCNT1 = 0;
TIFR1 |= (1 << OCF1A); // clear output compare match flag
TIMSK1 |= (1 << OCIE1A); // enable output compare interrupt
}
}
else {
PORTD &= ~(1 << PIND6); //turn off PD6, stop opening valve
}
}
ISR(TIMER1_COMPA_vect) {
TIMSK1 &= ~(1 << OCIE1A); // disable output compare interrupt
open_valve(0); //turn off close valve output
}
通过按下按钮(未显示)调用open_valve函数。我最难的时刻是弄清楚我需要TIFR1 |= (1 << OCF1A)
才能正常工作。我仍然不太清楚为什么,因为我认为ISR应该自动执行此操作。
答案 0 :(得分:0)
您必须大致遵循以下步骤:
如果您没有免费的16位计时器,我建议在CTC模式下使用1个计时器来生成(10)毫秒的时基,并在此ms事件处理中实现时间计数逻辑。