gpt4 book ai didi

Handling several AVR Interrupt Vectors(处理几个AVR中断向量)

转载 作者:bug小助手 更新时间:2023-10-25 15:32:58 28 4
gpt4 key购买 nike



I am trying to handle two AVR interrupt vectors ISR(PCINT1_vect) and ISR(PCINT0_vect). However,
only one of them are executed.

我正在尝试处理两个AVR中断向量ISR(PCINT1_VECT)和ISR(PCINT0_VECT)。然而,他们中只有一人被处决。


Which ISR is executed is dependent upon if function "SonarSensor_init0(void)" or "SonarSensor_init1(void)" is called upon first in the code.

执行哪一个ISR取决于代码中第一个调用函数“SonarSensor_init0(Void)”还是“SonarSensor_init1(Void)”。


Am I handling multiple ISRs in the wrong way?

我是否以错误的方式处理多个ISR?


I am by the way using Atmega328PB.

顺便说一下,我正在使用Atmega 328PB。


    #define F_CPU 16000000UL
#define USART_BAUDRATE 9600
#define UBRR_value (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>

uint16_t distance1;
uint16_t distance2;


void SonarSensor_init0(void);
void SonarSensor_init1(void);


int main(void)

{

SonarSensor_init0();
SonarSensor_init1();


while(1)
{
sei();

PORTC |= (1 << PINC4);
_delay_us(10); // 10 us trigger. Echo pin is pulled high by control circuit of sonar sensor.
PORTC &= ~(1<<PINC4);


sei();

PORTB |= (1 << PINB0);
_delay_us(10); // 10 us trigger. Echo pin is pulled high by control circuit of sonar sensor.
PORTB &= ~(1<<PINB0);
}
}


void SonarSensor_init1(void)

{




DDRC = 0xFF; // Port C all output.
DDRC &= ~(1<<DDC5);

PORTC |= (1<<PORTC5); // Enable pull up on C5 (echo)
PORTC &= ~(1<<PINC4); // Init C4 as low (trigger)

PRR &= ~(1<<PRTIM1); // To activate timer1 module
TCNT1 = 0; // Initial timer value
TCCR1B |= (1<<CS12); // Timer without prescaler. Since default clock for atmega328p is 1Mhz period is 1uS
TCCR1B |= (1<<ICES1); // First capture on rising edge

PCICR = (1<<PCIE1); // Enable PCINT[14:8] we use pin C5 which is PCINT13
PCMSK1 = (1<<PCINT13); // Enable C5 interrupt



//sei(); // Enable global interrrupt


}


void SonarSensor_init0(void)
{


DDRB = 0xFF; // Port B all output.
DDRB &= ~(1<<DDB1);

PORTB |= (1<<PORTB1); // Enable pull up on B1 (echo)
PORTB &= ~(1<<PINB0); // Init B0 as low (trigger)

PRR &= ~(1<<PRTIM0); // To activate timer0 module
TCNT0 = 0; // Initial timer value
TCCR0B |= (1<<CS00); // Timer without prescaler. Since default clock for atmega328p is 1Mhz period is 1uS


PCICR = (1<<PCIE0); // Enable PCINT[0:7] we use pin B1 which is PCINT1
PCMSK0 = (1<<PCINT1); // Enable B1 interrupt


//sei(); // Enable global interrrupt

}


ISR(PCINT1_vect) {

if ( (PINC & (1 << PINC5)) == (1 << PINC5)) // Checks if echo is high
{
TCNT1 = 0;
PORTB |= (1 << PINB5); // Toggles Debug Led
}

else
{
distance2 = TCNT1/3; // Save Timer value
PORTB &= ~(1 << PINB5); // Toggles Debug led
cli(); // Disable global interrupt;


}
}


ISR(PCINT0_vect) {

if ( (PINB & (1 << PINB1)) == (1 << PINB1)) // Checks if echo is high
{
TCNT0 = 0;
PORTB |= (1 << PINB5); // Toggles debug led
}

else
{
distance1 = TCNT0; // Save Timer value
PORTB &= ~(1 << PINB5); // Toggles debug led
cli();

}
}

更多回答
优秀答案推荐

It's probably caused by the fact that you have these two conflicting lines in your functions:

这可能是因为您的函数中有这两条相互冲突的线:


PCICR = (1<<PCIE1);

PCICR = (1<<PCIE0);

When the first line runs, it sets all the bits in PCICR to a particular value. When the second line runs, it sets all of them to a different value, disabling the interrupt that was enabled by the first one. Maybe you should be using |= instead of = so it only modifies the one bit it cares about.

当第一行运行时,它将PCICR中的所有位设置为特定值。当第二行运行时,它会将它们全部设置为不同的值,从而禁用第一行启用的中断。也许您应该使用|=而不是=,这样它只修改它关心的一位。


更多回答

I should be ashamed of myself. I don't even know basic bitwise operation in c. The code works now. You are a life saver. I've been struggling with this 3 hours, and was looking for completely other solutions.

我应该为自己感到羞耻。我甚至不知道c中基本的按位运算。代码现在可以工作了。你真是个救命稻草。我已经挣扎了3个小时,一直在寻找完全不同的解决方案。

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com