2015-05-15 136 views
1

我正在使用录音机和播放器项目。我想实现ADC(模拟到数字)和DAC(数字到模拟)转换器。该代码应该在Arduino中实现 - Atmega 2560(Atmel微控制器)。我试图实现ADC,我发现以下代码:如何使用Arduino-atmega2560微控制器实现8位DAC(数模转换)?

void setup() 
{ 
    Serial.begin (9600); 
    ADCSRA |= ((1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0)); 
    ADMUX |=(1<<REFS0); 
    ADCSRA |= (1<<ADEN); 
    ADCSRA |= (1<<ADSC); 
} 

int read_adc(int channel) 
{ 
    ADMUX &=0xE0; 
    ADMUX |= channel & 0x07l; 
    ADCSRB = channel & (1<<ADSC); 
    ADCSRA |= (1<<ADSC); 
    while (ADCSRA & (1<<ADSC)) 
    { 
     return ADCW; 
    } 
} 

void loop() 
{ 
    int w = read_adc(0); 
    Serial.write(w); 
} 

这里我将数字化信号发送到串口。我有两个问题: 1-如何修改此代码以用作8位ADC? 2-如何以与之前相同的方式实现DAC?我的意思是如何从串口读取数字信号,然后将其转换为像上述算法那样的模拟信号?

谢谢你的帮助。

+1

Arduino Mega 2560没有任何DAC外设。您将需要一些额外的硬件来实现它。这与ADC完全无关。 –

+0

您能否指定哪个版本的Arduino具有DAC外设? –

+0

我不确定有没有。但是你可以很容易地找到带有某种I2C DAC的兼容Arduino的接口板。 –

回答

0

如果你的主板不具备DAC那么你可以使用一个额外的DAC芯片,并简单地用GPIO端口接口它。我在一个使用CortexM0微控制器的GPIO和一个DAC产生直流电机模拟输出的项目中完成了这项工作。根据您的应用类型,您可能还需要一个opAmp来放大DAC输出。

3

的ATMega2560没有DAC外围,但是,如果你的带宽要求比较低的,则可以使用具有合适的外部模拟滤波的PWM输出,以产生一个可变的输出电压(成正比的脉冲宽度)。

越高PWM频率,带宽越高,但较低的分辨率,因此,有一个折衷。一个简单的低通RC滤波器就足够了。在某些情况下(例如LED或直流电机驱动器),根本不需要任何滤波,PWM在任何情况下都是驱动这种负载的更有效的方法。但对于音频应用,除非直接驱动Class D ampifier,否则通常需要过滤。

为了实现8位的DAC需要配置的PWM为256个计数的每次循环中,然后简单地从零到255的计数设定脉冲宽度。经过充分过滤后,将产生模拟电压。为了使滤波尽可能简单,PWM频率应尽可能高,滤波器截止频率至少设置为该频率的一半,并且更好地低于f/5或更高。这将决定你的音频带宽。对于讲话,3Khz是足够的(电话质量); AM收音机质量为4.5KHz,FM收音机/ HiFi质量为15KHz。

有许多上线资源的使用PWM的DAC和必要的滤波的文件;例如http://ltwiki.org/images/8/82/PWM_Filters.pdf

+1

板载DAC数量很少的MCU之所以会出现这种情况,是因为如本答案中所述的PWM方式通常足够且始终更具成本效益。如果您需要一个实际的DAC芯片,您可能正在进行一些相当先进的信号处理,对此,您无论如何都不会使用8位MCU/Arduino。 – Lundin

0

有许多DAC器件使用市场上的SPI总线输入工作,其分辨率从8位到16位(或更高)。我已经看过所有的替代品,恕我直言,价格和分辨率之间的最佳折衷方案是MCP4xxx系列。

Adafruit有一个MCP4921分线板,可随时提供12位单通道。 I've chosen to use the MCP4822提供12位双通道分辨率。 MCP48xx系列还具有内部参考电压,可确保在可变电源电压下具有稳定的输出电压。这比使用外部Vref的MCP49xx系列更不灵活。

由于AVR(Arduino)电源上的数字噪声通常超过20mV,因此使用12位以上的分辨率(1mv LSB)似乎不会获得更高的精度。此外,16位DAC比MCP4xxx系列的成本更高。

如果你需要一个DC输出能力,是有意义的使用运算放大器来缓冲DAC。另外,如果AC是你需要的(音频),那么有cheap headphone amplifiers可用,作为一个缓冲区做了很好的工作。

如果您需要使用AVR SPI总线作为数据源(例如uSD卡)并且源速度很慢,那么您可以使用中断驱动DAC,而不会干扰主SPI接口。

下面是一个在ATmega1284p平台上实现的模拟接口快照,我碰巧得到了它。

Goldilocks Analogue Schematic

DAC.h code可以在SourceForge在AVRfreeRTOS找到。