关于电路
项目

SAM4S XPLED PRO的脉冲宽度调制

2016年4月14日经过罗伯特·基姆(Robert Keim)

本文涵盖了您需要了解的所有内容,以通过Atmel的SAM4S XPLAINE PRO开发板生成脉冲宽度调制的信号。

本文涵盖了您需要了解的所有内容,以通过Atmel的SAM4S XPLAINE PRO开发板生成脉冲宽度调制的信号。

支持信息

需要硬件/软件

在PWM DAC之前,我们需要PWM

本文旨在建立在最近的两个细胞系列上,该系列探讨了通过低通滤波脉冲宽度调制信号来实现数字到分析转换的技术。beplay体育下载不了(点击在这里第1部分, 和在这里第2部分。)这些文章的总体结论是,PWM DAC值得考虑是否存在

  1. 您不能或真的不想使用具有集成DAC的外部DAC或微控制器,
  2. PWM硬件提供了适合您应用程序的DAC分辨率,
  3. 您的数字电源电压是准确且可预测的,并且
  4. 您可以使用基本的RC低通滤波器实现可接受的输出涟漪和安装时间。

我们已经涵盖了该主题的理论方面,现在是时候将理论付诸实践,然后看一些现实生活中的结果了。为此,我们将使用SAM4S XPLE PRO“评估套件”,这是Atmel用语用于我称之为“开发委员会”的东西。我们还将使用原始1I/O1扩展板,两者都包含在SAM4S XPLAINE PRO入门套件。实际上,对于这个项目,扩展板是一种方便,而不是必需的。如果您拥有的只是SAM4S板,则可以用面包板或其他东西进行低通电路。

在我们可以将PWM信号转换为数字控制的模拟电压之前,我们需要生成一个PWM信号,我认为,这并不像人们期望的那样简单。在我看来,ATMEL软件框架(ASF)的PWM部分的文献差,并且在您实际看到预期的PIN上的预期PWM波形之前​​,您需要获得各种小细节。因此,我们将把本文的其余部分投入到掌握PWM接口,在下一篇文章中,我们将合并DAC功能。

顺便说一句,在尝试使用ASF的PWM功能之前,请不要忘记将PWM ASF模块添加到项目中。在“逐步”部分中讨论了添加ASF模块的过程用ATMEL SAM4S XPLAINE PRO PROWER的项目开发介绍

将信号连接到销

SAM4S板上的微控制器支持四个独立的PWM通道;每个通道都有互补的输出,因此我们共同拥有多达八个PWM信号。这SAM4S XPLAINE PRO用户指南告诉我们,这些信号中的两个包含在标准扩展标头引脚中:

在这个项目中,我们不需要互补的信号,因此我们仅使用PIN7。如果您使用Proto1扩展板,则该引脚的标签方便地标记为“ PWM+”;如果没有,您可以轻松地在Ext1标头上找到第7号码。

如果我们查看ext1的引脚,我们会发现PIN 7给我们从PWM通道0的正(即未倒置)信号,而驱动此信号的端口引脚为PA23:

那么,我们如何告诉微控制器在引脚PA23上驱动PWM信号?为此,我们需要两件事:将名称分配给PIN的预处理器定义,以及呼叫pio_configure_pin()。在这一点上,我们有足够的信息为其中的第一个信息:

#define pwm_dac ioport_create_pin(Pioa,23)

IOPORT_CREATE_PIN宏使我们可以将名称“ PWM_DAC”附加到并行输入/输出控制器中的引脚23上。现在,我们必须配置PWM_DAC引脚,以使其用于外围功能,而不是通用i/o/o,i/o,此外,我们需要为正确的外围线配置它。每个引脚最多可以连接到四个外围信号;这些称为外围A,B,C和D。表39-2(第955页)SAM4S系列数据表告诉我们我们需要的四个:

现在,我们可以正确地调用pio_configure_pin():

pio_configure_pin(pwm_dac,pio_type_pio_periph_b);

PWM时钟

我们需要做的下一件事是配置将驱动PWM硬件的时钟。PWM模块支持从可编程分隔器(称为A和B)派生的两个时钟,但是我们只需要一个时钟,因此我们将禁用时钟B。PWM时钟是从微控制器的外围时钟派生的。我们不需要讨论时钟硬件的详细信息,因为ASF为我们处理低级配置;但是,如果您有兴趣,则可以参考第957页SAM4S系列数据表

时钟配置过程的第一步是启用PWM硬件的外围时钟:

pmc_enable_periph_clk(id_pwm);

现在,我们使用“ PWM_CLOCK_T”结构来设置时钟速度;该结构定义为“ pwm.h”标头文件中的如下:

/ **输入参数初始化PWM*/ typedef struct {/ **时钟a的频率in in Hz(设置0以将其关闭)*/ uint32_t ul_clka;/ ** Hz中时钟B的频率(设置为0以将其关闭)*/ uint32_t ul_clkb;/ ** hz中的主时钟的频率*/ uint32_t ul_mck;} pwm_clock_t;

这是一个示例配置:

pwm_clock_t pwmdac_clock_config = {.ul_clka = 1000000,.ul_clkb = 0,.ul_mck = sysclk_get_get_cpu_hz()};

在这里,我们将时钟设置为1 MHz;时钟B被禁用。我们通过调用sysclk_get_cpu_hz()来提供主时钟频率。要应用此配置,我们使用pwm_init()函数:

pwm_init(pwm,&pwmdac_clock_config);

PWM选项

我们已经接近了 - 我们只需要配置PWM频道本身,然后启用通道即可。ASF使PWM配置相当方便:类型“ PWM_CHANNEL_T”的结构使我们可以访问各种选项,然后我们将此结构的地址传递给PWM_CHANNEL_INIT()函数。首先,我将为您提供代码,然后我们将讨论详细信息。

pwm_channel_instance.channel = pwm_channel_0;pwm_channel_instance.ul_prescaler = pwm_cmr_cpre_clka;pwm_channel_instance.polarity = pwm_high;pwm_channel_instance.Alignment = pwm_align_left;pwm_channel_instance.ul_period = 20;pwm_channel_instance.ul_duty = 5;
  • PWM_CHANNEL_INSTANCE.CHANNEL:我们正在使用频道0。
  • pwm_channel_instance.ul_prescaler:我们需要选择时钟源;pwm_cmr_cpre_clka对应于时钟。
  • pwm_channel_instance.polarity:如果将其设置为pwm_high,则“ ul_duty”值定义了信号的逻辑高部分的宽度(换句话说,逻辑高是活动状态);如果设置为pwm_low,则“ ul_duty”值定义了信号的逻辑 - 低部分的宽度。
  • PWM_CHANNEL_INSTANCE. ARTIGNMEMT:有关左键模式与中心对准模式的详细信息,请参阅第960-961页SAM4S系列数据表。通常,您需要左对准模式;当您需要两个非重叠的PWM波形时,与中心对准模式很有用。这些设置之间最明显的区别是,从左对准模式变为中心对准模式将导致PWM周期和活跃状态脉冲宽度增加2倍。
  • PWM_CHANNEL_INSTANCE.UL_PERIOD:ASF文档将结构的该成员描述为“周期周期值”,这是您很容易地发现有关如何处理UL_Period的信息。这是一个实际上有帮助的描述:ul_period定义了PWM周期的持续时间在时钟刻度的单位中。在此示例中,我们选择了时钟A作为PWM通道的时钟源,并以1 MHz的频率配置了时钟A。因此,ul_period的单元为1 µs时钟滴答。上面给出的示例代码具有pwm_channel_instance.ul_period = 20,这意味着PWM周期为20×1 µs = 20 µs。
  • pwm_channel_instance.ul_duty:不要让成员标识符欺骗您:这不能定义占空比。占空比是活跃状态脉冲宽度除以该周期,通常表示为百分比。相比之下,ul_duty是脉冲的持续时间,再次以时钟滴答的形式使用。在上面的示例中,我们有pwm_channel_instance.ul_duty = 5;因此,活跃状态脉冲宽度将为5×1 µs = 5 µs,对应于(5 µs)/(20 µs)= 25%的占空比周期。
  • 现在,我们将配置应用到pwm_channel_init()的调用,之后我们准备使用pwm_channel_enable()启用通道。

结果

让我们看一下不同PWM配置的一些振动测量值。We’ll start with the configuration given in the above code excerpts: clock source = 1 MHz, polarity = PWM_HIGH, alignment = PWM_ALIGN_LEFT, ul_period = 20, ul_duty = 5. Note that the relevant timing characteristics are displayed on the right side of the scope captures.

如果我们保持一切相同,但是切换到极性= pwm_low,我们就会得到:

如果我们回到pwm_high,则更改为Alignment = pwm_align_center,我们会看到以下内容:

下一个波形返回到左对齐的模式,我将UL_DUTY增加到10:

在这里,我将UL_Period增加到30:

最后,如果我保持所有内容相同(ul_duty = 10,ul_period = 30),则是波形,但将时钟增加到10 MHz。

您可以使用以下链接下载源和项目文件,并且在链接之后给出了所有“ main.c”代码。在下一篇文章中,我们将使用新发现的PWM专业知识来探索PWM数字到Analog转换。beplay体育下载不了

pwm_with_sam4s_xplained_pro.zip

#include  #define pwm_dac ioport_create_pin(pioa,23)pwm_channel_t pwm_channel_instance;int main(void){//时钟配置和初始化sysclk_init();/*禁用看门狗计时器,并配置/初始化端口引脚连接到SAM4S XPLAINE开发平台中的各种组件,例如NAND闪光灯,OLED接口,LED,SW0 PUSHBUTTON。*/board_init();//将外围B连接到PIN A23 PIO_CONFIGURE_PIN(PWM_DAC,PIO_TYPE_PIO_PERIPH_B);//启用PWM硬件pmc_enable_periph_clk(id_pwm)的外围时钟;//禁用通道,直到正确配置PWM_CHANNEL_DISABLE(PWM,PWM_CHANNEL_0);// PWM时钟配置PWM_CLOCK_T PWMDAC_CLOCK_CONFIG = {.ul_clka = 1000000,.ul_clkb = 0,.ul_mck = sysclk_get_cpu_hz()};//应用时钟配置pwm_init(pwm,&pwmdac_clock_config);//请参阅文章以获取详细信息pwm_channel_instance.channel = pwm_channel_0;pwm_channel_instance.ul_prescaler = pwm_cmr_cpre_clka; pwm_channel_instance.polarity = PWM_HIGH; pwm_channel_instance.alignment = PWM_ALIGN_LEFT; pwm_channel_instance.ul_period = 20; pwm_channel_instance.ul_duty = 5; //apply the channel configuration pwm_channel_init(PWM, &pwm_channel_instance); //configuration is complete, so enable the channel pwm_channel_enable(PWM, PWM_CHANNEL_0); while(1); }

系列的下一篇文章:

为自己自己尝试一下!得到bom。

3条评论
  • s
    愚蠢的 2016年4月28日

    嗨,请原谅我的无知…
    是保留以下命令还是变量?
    如果保留,我可以在哪里找到更多信息?

    ioport_create_pin()
    pio_configure_pin()
    pmc_enable_periph_clk()
    pwm_init()
    pmc_enable_periph_clk()

    喜欢。 回复
    • C
      随身携带 2021年3月16日
      两者都不。这些不是保留的“关键字”,也不是变量。这些是函数调用,在包含语句中某个地方引用的库中定义。这是基本的“ C”语言编程,如果您有兴趣理解上面的代码示例,则可能只想上一门课程。但是,理解核心语言仍然没有教给您任何给定的“库”,这些给定的“库”可用于使用某些硬件。在这种情况下,您仍然需要了解库以及需要按什么顺序来制作的功能,以及必须将其传递给它们的内容才能使硬件完成您想要的工作。
      喜欢。 回复
  • k
    kajota 2018年12月28日

    我遇到的一个问题是,如果我打电话给pwm_channel_disable,PWM将不会出现。一旦我删除了这一点,PWM就会起作用,但是每次我都想禁用,然后重新启用PWM,我必须再次调用PWM_CHANNEL_INIT。我还没有足够的研究来弄清楚需要专门设置哪些寄存器。

    关于ul_period和ul_duty变量的部分非常有用。感谢您的描述。我知道我会挂了一段时间。

    喜欢。 回复