c - AVR Timer and Hardware interrupts
问题描述
I try to activate a timer at the first detection on falling edge of hardware interrupt detection and to deactivate the timer after 8 runs. But when I stop the timer, the hardware interrupt triggers again and starts the timer immediately.
In the image you can ignore the blue signal. The purple signal is timer1 toggling the pin. Green is hardware interrupt toggling the pin.
All it has to do is trigger at the first falling edge, then toggling a pin in a period of time.
My question is: why does hardware interrupts trigger twice?
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
volatile int cnt = 0;
uint8_t data[8];
int main(void)
{
// TIMER 1
DDRB |= (1 << PORTB0); // Set LED as output
DDRB |= (1 << PORTB1); // Set LED as output
DDRB |= (1 << PORTB2); // Set LED as output
DDRD &= ~(1 << PORTD2); // Set LED as INPUT
PORTD |= (1 << PORTD2); // PULLUP resistor
TCCR1B |= (1 << WGM12); // Configure timer 1 for CTC mode
TIMSK1 &= ~(1 << OCIE1A); // Disable CTC interrupt
//TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt
OCR1A = 1200; // Set CTC compare value to 15873Hz at 16MHz AVR clock, with a prescaler of 1
//TCNT0 = 0;
TCCR1B |= ((1 << CS10)); // Start timer at Fcpu/1
// Interrupt
EICRA |= (1 << ISC01) | (1 << ISC11); //ENABLE INT0 and INT1 ON falling EDGE
EIMSK |= (1 << INT0); //ENABLE INT0
EIMSK |= (1 << INT1); //ENABLE INT0
sei(); // Enable global interrupts
while (1)
{
}
}
ISR(TIMER1_COMPA_vect)
{
cnt = cnt + 1;
PORTB ^= (1 << PORTB0); // D8
if (cnt > 7)
{
TIMSK1 &= ~(1 << OCIE1A); // stop CTC interrupt
EIMSK |= (1 << INT0); //Enable INT0
EIMSK |= (1 << INT1); //Enable INT0
return;
}
}
ISR(INT0_vect) //External interrupt_zero ISR
{
EIMSK &= ~(1 << INT0); //Disable INT0
PORTB ^= (1 << PORTB2); // Toggle the LED
TCNT1 = 0;
cnt = 0;
TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt
}
ISR(INT1_vect) //External interrupt_zero ISR
{
PORTB ^= (1 << PORTB2); // Toggle the LED
EIMSK &= ~(1 << INT1); //Disable INT0
TCNT1 = 0;
cnt = 0;
TIMSK1 |= (1 << OCIE1A); // Enable CTC interrupt
}
解决方案
即使您禁用它,下降沿也会设置中断标志。这称为“未决”中断。一旦启用中断,就会调用其服务程序(假设满足所有其他启用条件)。
您需要在启用中断之前清除此挂起标志。
推荐阅读
- angular - 同时在 chrome 和 IE11 中支持 Angular Element 的问题
- java - Spark:使用分隔符进行拆分不适用于逗号
- java - 无法使用 java 在 Linux 中解压缩 Web 服务响应
- angular - console.log 不显示使用 PUT 方法编辑的输入
- java - 微调器中的 setError 消息时出错。如何seterror spinner?
- vue.js - 在组件内部使用时未定义 Dropzone
- javascript - 有和没有异步等待的firebase数据库事务有什么区别?
- laravel - Lravel 5.6 : 使用邮件门面发送的电子邮件只有 hotmail 和 Outlook 地址才会变成垃圾邮件
- linux - 具有多个主目录的本地用户
- php - PHP 和 DB 连接替换为 mysql 中的 mysqli