gpt4 book ai didi

c - avr中处理多个中断

转载 作者:行者123 更新时间:2023-11-30 16:27:26 24 4
gpt4 key购买 nike

我是 AVR 编程新手,如果问题微不足道,我很抱歉。

使用:

  1. 操作系统:Windows7
  2. IDE:Atmel 工作室
  3. uC = m328p

引脚:

  1. ADC 信号 - ADC0/PC0
  2. LED_值 - (PB0 - PB7)
  3. LED_START - PD1
  4. LED_LIGHT - PD0
  5. 按钮 - PD2

目标:当您按下按钮时,它会打开 LED_START 并且需要开始转换。AVR 获得中断并开始 ADC 转换。基本上程序有两个中断。我知道INT0中断具有最高优先级。

我不知道该怎么对付他们。我尝试了一些方法,例如添加全局变量“start”并更改它。而且,当我仅设置 LED START 时,它会打开并保持该状态,直到 LED_values 达到特定值,然后 LED START 自行关闭。

所以请你告诉我如何处理两个中断,以便实现既定目标,并解释我做错了什么。

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

#define F_CPU 1000000UL
#define BIT_IS_SET(byte, bit) (byte & (1 << bit))
#define BIT_IS_CLEAR(byte, bit) (!(byte & (1 << bit)))

typedef enum{false, true} bool;

bool previousState = false;
bool start = false;

char num;

void setup();
void loop();
void ADC_init();
void EI_init(); // External Interrupt

int main(void)
{
setup();
loop();
}

void setup(){
DDRC &= ~(0x1); // LDR Input
DDRB = 0xFF; //LEDs value Output
DDRD |= 0x3; //LED light LED start Output
DDRD &= ~(1 << PIND2); //Button Input
}

void loop(){
PORTD |= (1 << PIND2);
EI_init();
ADC_init();
sei();
if(start){
ADCSRA |= (1 << ADSC);
}
while(1){}

}

void ADC_init(){
ADMUX = 0x60;
ADCSRA = 0x8B;
ADCSRB = 0x0;
ADCH = 0x0;
}

ISR(ADC_vect) {
PORTB = ADCH; // assign contents of ADC high register to Port D pins
int b = (int)ADCH;
if(b > 180) { //100
PORTD = 0x1;
}else{
PORTD &= ~(0x1);
}
_delay_ms(100);
ADCSRA |= (1 << ADSC); // start next ADC
}

void EI_init(){
EIMSK |= (1 << INT0); // Interrupt enabled
EICRA |= (1 << ISC00); // any state change
}

ISR(INT0_vect){
if(BIT_IS_CLEAR(PORTD,PIND2)){
start = true;
}else{
start = false;
}
}

这是方案:scheme

最佳答案

首先,您应该使 start volatile ,因为它被主循环和中断使用。 volatile 关键字告诉编译器该变量可能会被其控制之外的事物修改,因此它无法优化对该变量的任何读取或写入:

volatile bool start = false;

其次,您可能想要删除循环末尾编写的这一行:

while(1){}

该行很糟糕,因为它会导致您的程序进入无限循环,并且不执行任何操作。我认为您实际上希望在 loop 函数中编写的代码多次运行。

其次,当您检测到 start 标志已设置后,您可能需要将其设置为 0,否则它将永远为 1。

第三,在 INT0 ISR 中将 start 设置为 false 可能是一个坏主意,因为在主循环有机会观察到它为 true 并处理事件之前,它可能会设置为 false。我想这实际上取决于您想要做什么。您可以尝试在您的问题中添加详细信息,了解您正在尝试使用 AVR 解决什么问题。请参阅What is the XY problem? .

您的代码可能还存在其他问题需要调试。你能想出一些方法让这件事变得更简单吗?也许您可以减少正在使用的中断数量。要进行调试,您可以尝试闪烁一些 LED 来确定程序的哪些部分正在执行。

关于c - avr中处理多个中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52740329/

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