У меня есть следующие перечисления и структуры:
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));
}
, а затем эта функция для настройки моего АЦП:
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 и библиотека Utilities использовались ранее, поэтому я почти уверен, что они в порядке.
Есть идеи, где я ошибаюсь?