【发布时间】: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吗?你永远不会检查它的返回值。你确定它有效吗? -
malloc在stdlib.h中,在ADC.c中导入,其中包含 ADC 函数 -
摆脱它怎么样?静态分配
settings。反正我看不出有什么好的理由不这样做。
标签: c avr cpu-registers atmel adc