atmega328p中断和定时器设置[C/C++]
我想设置一个中断和一个计数器/定时器。中断是外部的,从引脚读低逻辑。计时器应该每增加一个100美分并加起来为count
变量。 但是,我设置了中断,但它正常工作,设置定时器后,既不中断也不定时器工作。该代码是这样的:atmega328p中断和定时器设置[C/C++]
volatile boolean allowCount = false, timerFlag = false;
volatile unsigned int counter;
boolean pulseLow = false;
void setup(){
Serial.begin(9600);
// initialize external pin interrupt.
PCICR = 0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10); // set wanted flags (low logic level causes interrupt)
PCMSK1 = 0b00010000; // Enable Pin Change Interrupt for A4
// TODO Interrupt settings not working together
// initialize Timer1
cli(); // disable global interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
// set compare match register to desired timer count:
OCR1A = 0x18;
// turn on CTC mode:
TCCR1B |= (1 << WGM12);
// Set CS10 and CS12 bits for 64 prescaler:
TCCR1B |= (1 << CS10);
TCCR1B |= (1 << CS11);
// enable timer compare interrupt:
TIMSK1 |= (1 << OCIE1A);
}
void loop(){
if (allowCount == true)
{ timer100_uS();
if (counter > 50 && pulseLow == false){
DDRC |= (1 << DDC3); // sets bit DDC3 to 1 within register DDRC
//set pin 3(A3) ouput as sourcing Vcc(HIGH)
PORTC |= (1 << PORTC3);
timerReset();
pulseLow = true;
}
if (pulseLow == true){
timer100_uS();
if (counter >= 500){
//set pin3 of port C to LOW (A3);
PORTC &= ~(1 << PORTC3);
pulseLow = false
timerReset();
}
}
// external pin interrupt
ISR(PCINT1_vect){
if (allowCount == false)
allowCount = true;
}
// timer/counter interrupt
ISR (TIMER1_COMPA_vect)
{
if (timerFlag == true){
counter++;
}
}
void timer_100uS(void){
timerFlag = true;
cli();
}
void timerReset(void){
sei();
timerFlag = false;
counter = 0;
}
OCR0A的值来计算基于此公式与分频器64和16 MHz处理器为24(为0x18):
OCRn = [ (clock_speed/Prescaler_value) * Desired_time_in_Seconds ] - 1
如何设置不同的中断以便他们不重叠海誓山盟? 还是更好呢,是否可以设置定时器,使其不使用中断? 感谢您的阅读!
谢谢你的答案@old_timer,@klasyc。 比较晚,但我下面的设置解决它通过使用定时器0,而不是定时器1的设置:
// initialize external pin interrupt.
PCICR = 0b00000010; // 1. PCIE1: Pin Change Interrupt Enable 1
EICRA |= bit (ISC10); // set wanted flags (falling edge causes interrupt)
PCMSK1 = 0b00001000; // Enable Pin Change Interrupt for A3
TCCR0B = 0;
TCCR0A = 0;
//set CTC mode
TCCR0A = (1 << WGM01);
// set OCR0A value for 1 us counter (OCRxn = (freq/prescaler)*desired_value)-1
OCR0A = 15;
// set compare match counter
TIMSK0 |= (1 << OCIE0A);
//set prescaler
TCCR0B |= (1 << CS00);
和外循环:
ISR(TIMER0_COMPA_vect){
counter++;
}
正如我所见,您正在使用ATMega328与Arduino库。你的问题是Arduino库在内部使用定时器1来实现其内部目的。因此,如果您为定时器1添加自己的中断处理程序,则会覆盖定时器1的Arduino中断处理程序,从而中断该库。
如果你想留在Arduino的图书馆,利用图书馆也控制定时器:Arduino Timer1
*出于某种原因,格式化不能按预期工作,因此您可以改为阅读此答复。 是的,我使用的Arduino亲迷你16 MHz的 我不认为这是可能数到10我们定时器0和2, 因为他们是8个定时器,让预分频器为256 所以,定时器1似乎是唯一的选择。 如何检查所有寄存器?如果它太复杂,我宁愿将代码直接写入arduino芯片的avr中。 – flowian
检查Arduino [源代码](https://github.com/arduino/Arduino/blob/master/hardware/arduino/avr/cores/arduino/wiring.c#L241)后,似乎Arduino库尝试配置和使用所有计时器和唯一的“官方”方式是使用他们的图书馆功能。所以我根据这个事实改变了我的答案。从评论到你的问题:检查一个处理器寄存器只需将它的内容写入串行像普通变量:) – klasyc
只是不设置中断启用定时器控制寄存器是?然后轮询状态寄存器以查看计时器是否完成了你正在等待它做的任何事情。 –
你可以单独使用它们吗?只做一件事但不是两件事,中断是否适用于每种情况?外部中断的来源是什么(一个按钮或某个其他设备的信号)?如果一个按钮你如何处理反弹? –
@old_timer如何读取状态寄存器中的定时器/计数器值? counterValue = SREG? 外部中断读取零交叉模拟信号,它每次工作。 – flowian