【问题标题】:Atmel AVR ADMUX Register Not Taking Assigned ValueAtmel AVR ADMUX 寄存器未分配值
【发布时间】:2019-06-24 04:39:57
【问题描述】:

我有以下枚举和结构:

typedef enum reference{
    AREF = 0, //External on AREF pin
    AVCC = true << REFS0, //Analogue supply voltage
    I11 = true << REFS1, //Internal 1.1V reference
    I256 = true << REFS1 | true <<REFS0 //Internal 2.56 reference
} Reference;

typedef enum channel{
    ADC0 = 0,
    ADC1 = true << MUX0,
    ADC2 = true << MUX1,
    ADC3 = true << MUX0 | true << MUX1,
    ADC4 = true << MUX2,
    ADC5 = true << MUX2 | true << MUX0,
    ADC6 = true << MUX2 | true << MUX1,
    ADC7 = true << MUX2 | true << MUX1 | true << MUX0
    //If higher channels are needed continue using MUXn for n = 0-> 4 in a binary count.
} Channel;

typedef enum leftadjust{
    LADisabled = 0,
    LAEnabled = true << ADLAR
} LeftAdjust;

//Enums for ADCSRA
typedef enum adcenable{
    ADCDisabled = 0,
    ADCEnabled = true << ADEN
} ADCEnable;

typedef enum adcautotriggerenable{
    AutoTriggerDisabled = 0,
    AutoTriggerEnabled = true << ADATE
} ADCAutoTriggerEnable;

typedef enum adcinterruptenable{
    ADCIntteruptDisabled = 0,
    ADCInterruptEnabled = true << ADIE,
} ADCInterruptEnable;

typedef enum adcclockdivider{
    CDHalf = 0,
    CDQuarter = true << ADPS1,
    CDEighth = true << ADPS1 | true << ADPS0,
    CDSixteenth = true << ADPS2,
    CDThirtySecond = true << ADPS2 | true << ADPS0,
    CDSixtyFourth = true << ADPS2 | true << ADPS1,
    CDOneTwoEighth = true << ADPS2 | true << ADPS1| true << ADPS0
} ADCClockDivider;

///structs
typedef struct ADCSettings{
    Reference ref;
    LeftAdjust leftAdjust;
    Channel channel;
    ADCAutoTriggerEnable autoTrigger;
    ADCInterruptEnable interruptEnable;
    ADCClockDivider clockDivider;
    } ADCSettings;

这个构造函数:

ADCSettings* NewADCSettings()
{
    return (ADCSettings*)malloc(sizeof(ADCSettings));
}

然后这个函数来设置我的 ADC:

void InitialiseADC(ADCSettings* settings)
{
    /*
        13CCs for a conversion. 50ns/cc therefore 0 clock division conversion time is 13 * 50ns =650ns.
        for 50us; 50us/950ns = 77.
        We have 16,32,64 and 128, 64 gives a time of 61us which is in range.
    */
    ADMUX = (settings->ref | settings ->leftAdjust | settings->channel);
    //ADMUX = true << REFS0 | true << MUX1 | true << MUX0; //REFSn sets voltage ref source, MUXn sets channel

    DIDR0 = true << ADC3D; //DIDR is digital input disable (makes a pin analogue)
    ADCSRA = true << ADEN | settings ->autoTrigger | settings ->interruptEnable | settings ->leftAdjust | settings->clockDivider;
    //ADCSRA = true << ADEN | true << ADPS2 | true << ADPS1; //ADPS1 & ADPS2 gives 64 scale

}

如您所见,我正在重构它以尝试使其成为一个不错的库函数,而不仅仅是按照我需要的方式进行设置。注释掉的行工作得很好。

当我运行它时,我认为应该将 ADMUX 分配给 67 但它取而代之的是 64 的值,如果我没记错的话,它只是设置了 REFS0 而不是 MUX0也不是MUX1

寄存器是 8 位的,所以它应该能够保存一个高达 255 的值。

为了完整起见,这是我的main.c

#include "misc/utilities.h"
#include <avr/io.h>
#include <util/delay.h>
#include <stdbool.h>
#include "USART/USART.h"
#include "ADC/ADC.h"

int main()
{
    ADCSettings* settings = NewADCSettings();
    settings->autoTrigger = false;
    settings->channel=ADC3;
    settings->clockDivider=CDSixtyFourth;
    settings->interruptEnable=false;
    settings->leftAdjust=false;
    settings->ref=AVCC;
    InitialiseADC(settings);
    while (true) 
    {
        int adcReading = GetADCConversion();
        Tx_Line(IntToString(adcReading));
        _delay_ms(100);
    }
}

USART 库和实用程序库之前已经使用过,所以我很确定它们没问题。

任何想法我哪里出错了?

【问题讨论】:

  • REFS0 的值是多少(以及您用作移位量的其他常量)?此外,我真的不喜欢 bool 常量的移动。请改用1U
  • REFS0 在avr/io.h 中定义:#define REFS0 6
  • 您真的在您的系统上正确实施了malloc 吗?你永远不会检查它的返回值。你确定它有效吗?
  • mallocstdlib.h 中,在 ADC.c 中导入,其中包含 ADC 函数
  • 摆脱它怎么样?静态分配settings。反正我看不出有什么好的理由不这样做。

标签: c avr cpu-registers atmel adc


【解决方案1】:

结果证明我的 ADC 设置完全没有问题。

寄存器的问题似乎只是模拟器更新监视窗口中的值的延迟。

我没有通过值的原因是因为我忘记从库中运行我的 InitialiseUART() 命令。

故事的寓意,确保您初始化所有外围设备。


来自 cmets 的其他建议:

  1. 不要在小型 uC 上使用动态内存分配。
  2. 不要依赖枚举的数值,使用#define

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多