yaboPP电子
项目

PWM数模拟转换与SAM4S Xplate Pro

2016年4月19日通过罗伯特Keim

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

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

支持信息

必需的硬件/软件

上一篇文章

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

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

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

低通滤波是通过I / O1板上的RC滤波器实现的。它恰好发生,该RC滤波器的输入连接到SAM4S微控制器上的PWM引脚,此外,RC滤波器由漂亮的小丝网卷曲绘图,Atmel补充。截止频率约为2340 Hz。

I/O1板不包括低通滤波器的输入和输出信号的单个头,所以我们需要找到另一种方法来连接探头。如果相关信号连接到奇数引脚,20引脚EXT头将是方便的,但幸运的是,它们都是偶数引脚,而偶数引脚是不可访问的:

幸运的是,其中一个信号可以在其他地方提供。低通滤波器输出连接到引脚PB1,其在SAM4S开发板上标记为“备用/备用信号”的通孔中的端子9也可用。这就是上述照片显示在备用/备用号9中提出的探头之一的原因。没有方便地访问低通滤波器输入节点,因此我将跳线焊接到I / O1 EXT标头上的引脚8,如下:

我的设置唯一的烦恼是跳线。If you don’t like soldering or don’t have an iron at your disposal, here is an alternative: The low-pass filter input on the I/O1 board is connected to the negative (i.e., inverted) output from PWM channel 1. On the PROTO1 board (shown in the above photo), you can easily probe the negative output from PWM channel 0, because it is right there on the prototyping header:

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

最后,如果你没有I/O1板,你可以使用PROTO1板,一个面包板,或某种临时的直接焊接实现得到一个低通滤波器连接到一个PWM信号。如果您使用PROTO1板,将它插入EXT2,这样您就不必修改代码(EXT1和EXT2有不同的PWM信号—通道0用于EXT1,通道1用于EXT2)。这是I/O1板上使用的低通电路:

准确性和脉动

这是PWM数码转换的基本代码框架:

#include #define PWM1L_DAC IOPORT_CREATE_PIN(PIOA, 20) #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.ul_period等于pwm_period_ticks来配置PWM频率。PWM波形(PWM_FREQ)的频率不会影响标称DAC输出电压,但它确实影响了纹波的量 - 如所讨论的那样低通滤波器将PWM信号转换为模拟电压,由于低通滤波器可以更有效地抑制信号中的非直流成分,因此PWM频率越高纹波越小。唯一影响DAC额定电压的两个因素是PWM波形的占空比和幅度(即逻辑高电压减去逻辑低电压)。振幅不在我们的控制范围内,所以一切都取决于占空比。我们计算ul_duty(它是脉冲的持续时间,而不是占空比)如下:

pwm1_config.ul_duty =(DAC_VOLTAGE *测量_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_ {high} -v_ {low} \右)\ times ome \ cycle \ oled)+ v_ {low} \]

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

左(\ \ [DAC电压= \ \离开(3 \ \ v - 100 mV \) \ times30.5 \ % \右)+ 100 mV \ mV = 985 \ \]

这几乎就是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信号进行缓冲,使逻辑高电压和逻辑低电压更接近VCC和地面。但是缓冲芯片与高阶低通滤波器相同的类别 - 如果您超出基本PWM-Plus-RC-Filter实现,您也可以使用外部DAC。因此,我们将简单地修改计算,以解释PWM信号的实际高电压。这似乎是作弊,但它实际上是一个很好的设计技术:如果您使用一个开关系统,请根据一些基本测量修改代码是有意义的。如果您正在使用大量生产的原型系统,因此对原型的体验基础性能假设是有意义的。当然,高电压和低电压可能从一个单元到另一个单元显着变化;但再一次,他们可能不是。在任何情况下,基于V的计算都没有很多点CC因为在一般情况下,微控制器的输出级不会一直驱动信号到VCC或者一直到地面。

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

#define测量_vhigh 3 #define测量_vlow 0.1。..pwm1_config.ul_duty =((dac_voltage  -  lobed_vlow)/(测量_vhigh  -  meterm_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 DACS遭受严重的限制。除了上面讨论的误差和纹波以及讨论的长期沉降时间低通滤波器将PWM信号转换为模拟电压,可用分辨率随着PWM频率的增加而降低 - 虽然PWM使用16位计数器,较高的频率降低该计数器的可用宽度,因为周期和脉冲宽度由与同一计数器相同的寄存器确定。例如,如果PWM计数器以100重置,因为它必须从1 MHz时钟产生100μs时段,占空比寄存器不能超过100,导致分辨率少于7位(因为27= 128)。底线:如果您能容容忍限制,PWM DAC是一种简单,低成本的解决方案,但大多数时间都以正常的DAC更好,无论是外部还是集成到微控制器中。

为自己提供这个项目!BOM。