雷竞技注册
项目

PWM数字-模拟转换与SAM4S Xplained Pro

2016年4月19日经过罗伯特·凯

在本文中,我们将使用SAM4S Xplined Pro开发平台来获得一些实践经验,并使用PWM DAC。

在本文中,我们将使用SAM4S Xplined Pro开发平台来获得PWM DAC的一些实践体验。

支持信息

所需的硬件/软件

前一篇文章

引脚、信号和探针,哦,天哪

在上一篇文章中,我们通过Atmel软件框架(ASF)巩固了对SAM4S PWM硬件的控制。现在我们准备让PWM硬件做一些有用的事情-即,产生一个可编程模拟电压的帮助无非是RC低通滤波器。我们需要做的第一件事是解决硬件设置的细节问题。我们将使用示波器测量来观察和分析PWM和DAC波形,所以这个设置的一个重要部分是如何方便地探测相关信号。

如果你有I/O1扩展板,你可以复制我的硬件设置:

低通滤波由I/O1板上的RC滤波器实现。碰巧RC滤波器的输入连接到SAM4S微控制器上的PWM引脚,此外,RC滤波器由一个漂亮的小丝网Bode图补充-很好的触摸,Atmel。截止频率约为2340hz。

I / O1板不包括用于低通滤波器的输入和输出信号的单个标题,因此我们需要找到另一种连接探针的方法。如果相关信号已连接到奇数销钉,则20引脚EXT标题将是方便的,但随着运气将其均匀,它们都是偶数,并且不可访问的偶数引脚:

幸运的是,这些信号中有一个在其他地方可用。低通滤波器输出连接到引脚PB1,该引脚也可从SAM4S开发板上标有“SPARE/ALTERNATE SIGNALS”的通孔排的端子9上使用。这就是为什么上面的照片显示一个探测器驻留在备用的/备用的数字9中。由于无法方便地访问低通滤波器输入节点,所以我在I/O1 EXT头的8引脚焊接了一根跳线,如下所示:

唯一让我烦恼的是跳线。如果你不喜欢焊接或没有铁在你的处置,这里有一个替代:低通滤波器输入的I/O1板连接到负(即倒转)输出PWM通道1。在PROTO1板上(如图所示),你可以很容易地探测PWM通道0的负输出,因为它就在原型头上:

因此而不是探测低通滤波器的实际输入,只需在Proto1板上探测PWM0-然后修改代码,使PWM通道0和1均已启用,并且始终产生相同的PWM信号(相同的时钟源,相同的时期,相同的占空比等)。

最后,如果您没有I / O1板,可以使用PROTO1板,面包板或某种陪审团操纵的直接焊接实现,以获得连接到PWM信号之一的低通滤波器。如果使用PROTO1板,请将其插入到ext2中,以便不必修改代码(ext1,ext2为ext1和ext2具有不同的PWM信号通道0)。这是I / O1板上使用的低通电路:

准确性和脉动

下面是PWM数模转换的基本代码框架:

#include  #define PWM1L_DAC IOPORT_CREATE_PIN(PIOA, 20) #define PWM_CLOCKSOURCE_FREQ 10000000 #define PWM_CLOCKSOURCE_FREQ 100000 #define PWM_PERIOD_TICKS PWM_CLOCKSOURCE_FREQ/PWM_FREQ #define MEASURED_VHIGH 3 float DAC_voltage = 1;pwm_channel_t PWM1_config;Int main (void){//时钟配置和初始化sysclk_init();/*禁用看门狗定时器和配置/初始化端口引脚连接到纳入SAM4S Xplained开发平台的各种组件,例如,NAND闪存,OLED接口,led, SW0按钮。* / board_init ();//连接外围设备B到引脚A20 pio_configure_pin(PWM1L_DAC, pio_type_pio_peripher_b);//为PWM硬件开启外围时钟pmc_enable_peripher_clk (ID_PWM);//关闭PWM通道,直到正确配置pwm_channel_disable(PWM, PWM_CHANNEL_1);//PWM时钟配置pwm_clock_t PWMDAC_clock_config = {.ul_clka = PWM_CLOCKSOURCE_FREQ, .ul_clkb = 0, .ul_mck = sysclk_get_cpu_hz()};//应用时钟配置pwm_init(PWM, &PWMDAC_clock_config);//选择通道1 PWM1_config. conf。频道= PWM_CHANNEL_1; //select clock A PWM1_config.ul_prescaler = PWM_CMR_CPRE_CLKA; /*The low-pass filter is connected to the inverted output for PWM channel 1, so to get an active-high signal we invert again by setting the polarity to low.*/ PWM1_config.polarity = PWM_LOW; //left-aligned mode PWM1_config.alignment = PWM_ALIGN_LEFT; PWM1_config.ul_period = PWM_PERIOD_TICKS; PWM1_config.ul_duty = (DAC_voltage * MEASURED_VCC) / PWM_PERIOD_TICKS; //apply the channel configuration pwm_channel_init(PWM, &PWM1_config); //configuration is complete, so enable the channel pwm_channel_enable(PWM, PWM_CHANNEL_1); while(1); }

如您所见,我们使用预处理器指令来定义

  1. 驱动PWM硬件的时钟的频率(即时钟A),
  2. PWM波形的频率,
  3. 以时钟A滴答为单位的PWM波形的周期,和
  4. 测量的数字电源电压。

然后我们有一个浮点变量,DAC_VOLTAGE.,为所需输出电压。我们通过设置PWM1_config来配置PWM频率。ul_period = PWM_PERIOD_TICKS。PWM波形的频率(PWM_FREQ)并不影响DAC的额定输出电压,但它会影响波纹的数量,正如在后面讨论的那样低通滤波器将PWM信号输入模拟电压,由于低通滤波器可以更有效地抑制信号中的非直流成分,因此PWM频率越高纹波越小。唯一影响DAC额定电压的两个因素是PWM波形的占空比和幅度(即逻辑高电压减去逻辑低电压)。振幅不在我们的控制范围内,所以一切都取决于占空比。我们计算ul_duty(它是脉冲持续时间,而非占空比)如下:

PWM1_config。ul_duty = (DAC_voltage * MEASURED_VCC) / PWM_PERIOD_TICKS;

这个小小的计算简单地确保了ul_duty与ul_period的比值与所需DAC电压与PWM幅度的比值相同。这里我们假设测量的电源电压与振幅相同,我们很快就会看到这是我们的主要误差来源。

这里是一个范围捕捉的设置上面显示(PWM频率= 100 kHz,DAC_VOLTAGE.= 1,PWM幅度= 3.28 V):

阳光测量显示在右侧。频率正如预期,占空比与理论值一致:(1 V)/(3.28 V)= 0.305。主要差异是幅度。PWM波形从约100 mV到3 V,而不是0 V至3.28 V.现在这是一个重要的细节:当逻辑低电压不在0 V时,DAC电压不再计算为(PWM幅度)×(占空比)。相反,我们需要使用

左(\ \ [DAC电压= \ \离开(V_{高}-V_{低}\)\ *职责\周期\右)+ V_{低}\]

因此,在当前条件下预期的DAC电压为

\ [DAC \电压= \左(\左(3 \ V-100 \ MV \右)\ time30.5 \%\右)+100 \ mv = 985 \ mv \]

这几乎就是DAC电压的平均值。因此请记住,您不能简单地将scope的“CH1 Vamp”乘以“CH1 +Dut”来确定预期的输出电压;你需要把这个乘法的结果加到PWM信号的实际逻辑低电压上。在任何情况下,由于假定的逻辑高电压和逻辑低电压之间的差异和真实的逻辑高电压和低电压之间的差异,平均DAC电压有大约20 mV的误差。至于纹波,我们看到的是150毫伏的峰值。(示波器在测量时遇到了麻烦,因为在PWM波形的逻辑转换时同时出现了噪声尖峰。这是两个范围通道之间的串扰的结果;它们实际上并不存在于DAC信号中。)有150mv的纹波和20mv的误差,到目前为止,我的一般结论是,我们有一个DAC;它并不令人印象深刻,但如果这种性能对您的应用程序来说足够,那么它比外部DAC更便宜、更简单。

这是范围捕获DAC_VOLTAGE.= 0.5,1.5和2.5:

改进

我们可以做些什么来使这个PWM DAC一点点平庸?我们的两个主要问题是涟漪和错误。纹波相当容易减少:如上所述,我们只是提高PWM波形的频率。错误更有问题;最佳解决方案是缓冲PWM信号,以便逻辑高和逻辑 - 低电压更靠近V.CC.和地面。但是缓冲芯片属于与高阶低通滤波器相同的类别—如果您超出了基本的pmm + rc滤波器的实现,您还可以使用外部DAC。因此,我们将简单地修改我们的计算来解释PWM信号的实际高电压和低电压,而不是一个缓冲区。这看起来像是作弊,但实际上这是一种很好的设计技术:如果您使用的是一次性系统,那么根据一些基本度量来修改代码是有意义的。如果你正在使用的原型系统将会大量生产,那么基于你的原型经验进行性能假设是很有意义的。当然,每个单元的高电压和低电压可能会有很大的不同;但话又说回来,他们可能不会。无论如何,用V来计算是没有多大意义的CC.因为在一般情况下,微控制器的输出级不会一直驱动信号到VCC.或者一直到地面。

所以让我们根据上面给出的逻辑高和逻辑低测量值来修改代码,即V= 3 V和v= 100 mV。

#define MEASURED_VLOW 0.1…PWM1_config。ul_duty = ((DAC_voltage - MEASURED_VLOW) / (MEASURED_VHIGH - MEASURED_VLOW)) * PWM_PERIOD_TICKS;

这是结果DAC_VOLTAGE.= 1.

嘿,误差为零!成功!等等,这是结果DAC_VOLTAGE.= 0.5且DAC_VOLTAGE.= 2.5。

叹息。因此,即使PWM占空比的变化也会导致高电压和低电压的足够变化,从而导致显著的误差。这提出了一个更复杂的方案的想法,在这个方案中,根据占空比的不同,计算使用不同的高电压和低电压,但在我投入大量时间之前,我会使用外部DAC。

至少我们知道我们可以改善涟漪。让我们将PWM时钟源频率增加到120 MHz,PWM频率为10 MHz。这是范围捕获DAC_VOLTAGE.= 1. PWM探头断开为第二次捕获,以便我们可以看到DAC波形的情况下没有串扰的情况(尽管似乎仍然存在一些噪声耦合到DAC信号中)。

较高的频率将纹波降低到可忽略的水平,但高电压和低电压已经变化足以引入大量误差(回想一下,当我们使用较低的频率时,误差为零DAC_VOLTAGE.= 1)。

结论

您可以使用以下链接下载源和项目文件:

PWM_DAC_with_SAM4S.zip

我们已经看到PWM dac有严重的局限性。除了上面讨论的误差和纹波和长时间的沉淀低通滤波器将PWM信号输入模拟电压,可用的分辨率随着PWM频率的增加而降低——尽管PWM使用16位计数器,更高的频率会减少计数器的可用宽度,因为周期和脉冲宽度都是由与相同计数器比较的寄存器决定的。例如,如果PWM计数器复位为100,因为它必须从1 MHz时钟产生100µs的周期,占空比寄存器不能超过100,导致分辨率小于7位(因为27.= 128)。底线:如果你能容忍限制,PWM DAC是一个简单的,低成本的解决方案,但大多数时候,你最好使用一个普通的DAC,无论是外部的或集成到微控制器。

你自己试试这个项目吧!得到bom。