【问题标题】:ATmega328p analog to digital conversion not respondingATmega328p 模数转换无响应
【发布时间】:2021-05-03 13:38:36
【问题描述】:

以下代码不会更新初始 adcValue。 LED 在不同的程序中正常工作,并且在给定初始 adcValue 的情况下它们也可以正常工作。他们不响应电位器调整。延迟只是为了让它变慢,没有它也行不通。

#define F_CPU   1000000UL

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

double adcValue = 700;

void startConversion()
{
    ADCSRA |= (1 << ADSC);
}        
void setupADC()
{
    // AVcc with external capacitor as reference, ADC5 as input
    ADMUX = (1 << REFS0) | (1 << MUX0) | (1 << MUX2);
    // Enabling ADC, acticating interrupts, setting prescaler to 8
    ADCSRA = (1 << ADEN) | (1 << ADIE) | (1 << ADPS0) | (1 << ADPS1) ;
    //disabling digital input buffer
    DIDR0 = (1 << ADC5D);       
    startConversion();
}            
ISR(ADC_vect)
{       
    adcValue = ADC;     
}    
int main(void)
{
    DDRB = 0b00111111;          
    setupADC();     
    sei();          
    while(1)
    {
        _delay_ms(500);
        if( adcValue < 400)
        {
            PORTB = 0b00000000;
        } 
        else if ( adcValue < 800)
        {
            PORTB = 0b00000011;
        } 
        else 
        {
            PORTB = 0b00000111;
        }

    startConversion();
}

}

解决方案:

现在可以了

volatile double adcValue = 700;

【问题讨论】:

  • adcValue 需要是可变的。它正在 ISR 中更新。
  • 它也需要是整数,因为 AVR 没有 FPU。这不是个人电脑。
  • @yhyrcanus 是的,它有效
  • ADC 具有 uint16_t 类型,因此在这种情况下,adcValue 和 double 是不必要的,并且无论如何在此平台上都是不明智的。
  • 如果您想回答自己的问题,请添加答案而不是编辑问题。然而,一个好的答案可以解释为什么该解决方案有效。错误修复不是 SO 的职责。 embedded.com/introduction-to-the-volatile-keyword

标签: c embedded avr adc


【解决方案1】:

adcValue 正在优化,因为编译器没有“看到” ISR 中的变量更改(它无法判断 ISR 是否会被调用)。因此,它只会被一个常量替换。解决此问题的方法是将其标记为volatile,这会告诉编译器不要对变量进行任何假设,并阻止编译器对其进行优化。

现在,除此之外,adcValue 是一个双精度类型。通常,您希望避免在没有 FPU 的设备中使用浮点(尤其是双精度)变量。具体来说,整数和浮点类型之间的转换需要很多周期。就像,大约数百个周期。您可能不希望在您的 ISR 中使用它。

如果您确实需要将变量设为浮点数,我建议您在 ISR 之外进行转换。您将有两个变量,static volatile uint16_t wAdcValue,在您需要浮点数的地方,您将分配float fAdcValue = (float) wAdcValue; 请注意,任何浮点操作都需要更多的处理和闪存使用来处理它。

【讨论】:

    猜你喜欢
    • 2015-01-20
    • 2018-05-11
    • 2017-01-30
    • 2021-09-03
    • 2011-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多