PWM:使用Arduino开发板仿真模拟引脚

PWM信号

使用可以在Arduino板上使用的数字和模拟引脚,您可以接收或发送电信号以控制或从电子项目中获取数据。 此外,在这种类型的印版中还有其他非常有趣的信号,这些信号是 PWM 可以模拟模拟信号而无需实际模拟。 也就是说,它们是数字引脚,其作用方式与模拟信号类似(不同)。

当您不仅要使用数字高和低信号(即1或0,ON和OFF),而且想进一步说明时,这些类型的信号非常实用。 稍微复杂一些的信号。 例如,可以调节 直流马达,或螺线管等灯的光强度。

模拟与数字系统

模拟与数字信号

电子电路可以分为两个大家族或大类: 数字和模拟。 在谈论数字电子时,我们使用具有离散值的量,即由低或高电压电信号表示的二进制系统来解释要处理的那些位的状态。 另一方面,当涉及到模拟电路时,将使用具有连续值的数量。

在数字系统内可以依次找到 组合型和顺序型。 也就是说,前者是那些系统的输出仅取决于输入状态的系统。 另一方面,在顺序存储器中,包括存储元件,并且输出将取决于输入的当前状态和存储的先前状态。

对于类似物,没有这两个大的组或变体,因为在这里它们是连续的信号,将始终取决于 拉塞纳尔 当前系统。 例如,在扬声器中,提供给扬声器的信号将取决于您要再现的声音。 麦克风也一样,麦克风会根据所接收的声音生成模拟信号。 当然,您还可以通过我们在本博客中描述的许多其他传感器看到它并与模拟信号一起使用(因此必须创建一个公式,以便以后可以在Arduino IDE草图中计算或调节值) )...

这些特点之一使它们各有各的 的优点和缺点,几乎所有内容都一样。 例如,数字信号通常更便宜,更快,更容易开发,信息可以更容易存储,准确性更高,可以编程,不易受噪声影响等。 但是,确实可以使用模拟信号处理更复杂的信号。

通过 例子,数字型霍尔效应传感器只能检测附近磁场的存在或不存在。 取而代之的是,模拟霍尔效应传感器不仅可以做到这一点,而且还可以通过在其输出端生成的模拟信号来确定所述磁场的密度。 知道如何很好地解释电压更高或更低的信号,就可以轻松知道该幅度。 您还可以使用模拟系统定量测量其他性质的示例,例如温度,时间,压力,距离,声音等。

模拟与数字信号

话虽这么说, 模拟信号 它是随时间连续变化的电压或电流。 如果以图表形式显示,则模拟信号将是单频正弦波。

至于 数字信号,是相对于时间逐步变化的电压。 也就是说,如果在图表上表示,它将是一个步进信号,它不会连续变化,而是以步进或离散增量变化。

您应该知道,存在从模拟信号到数字信号的电路,反之亦然。 这些 转换器 它们被称为DAC(数模转换器)和ADC(模数转换器)。 它们在我们今天使用的许多设备(例如电视,计算机等)中非常常见。 有了它们,您可以将这些设备使用的数字信号转换为电子电平,以与其他外围设备或以模拟方式工作的部件一起使用。

通过 例子,具有与声卡一起使用的模拟信号的扬声器或麦克风,或具有用于模拟监视器端口的著名RAMDAC芯片的数字图形卡...在Arduino中,这种类型的转换器还用于多个项目,我们将看到...

什么是PWM?

图形占空比

虽然 PWM(脉冲宽度调制)或脉冲宽度调制, 由于具有数字底座,其信号形状类似于某种“方形”的模拟信号。 正如我之前已经评论过的,它允许通过数字脉冲来改变信号以模拟模拟系统。 实际上,如果您看一下名称,它已经通过数字脉冲的宽度为您提供了提示。

这对 Arduino的 因为您可以将许多自动化或电子组件添加到您的项目中,并且 无法提供真实的模拟信号,但他们使用此PWM进行操作。 他们也不能使用离散的模拟信号,也就是说,电压跳变类似于数字信号。 他们可以做的是使用数字输出-Vcc或数字类型的Vcc生成此特殊信号...

因此,PWM是一种“技巧”,Arduino和其他系统可以通过它与此类信号进行互操作, 它们不是完全模拟,也不是常规数字。 为了使其成为可能,它们会始终保持数字输出在特定时间处于活动状态或处于关闭状态,这取决于始终的兴趣。 这与脉冲宽度相同的数字时钟或二进制代码信号相去甚远。

在使用Arduino的项目中,您可以检查这种类型的PWM信号,该信号在一段时间内保持恒定的脉冲触发频率,但是 这些脉冲的宽度是变化的。 实际上,当信号相对于整个周期保持高电平时,它称为占空比。 因此,占空比以%给出。

请记住,在PWM中,您不会像在多个电压值之间的模拟信号那样工作,并且在两个电压值之间会波动。 在PWM的情况下,它是数字形式的方波信号, 最大值为Vcc。 例如,如果使用3V电源,则可以提供3V或0V脉冲,但不能提供1V或任何其他中间值,这在真实模拟中会发生。 在这种情况下,变化的是脉冲宽度,我们可以在高Vcc值下保持30%的脉冲宽度,或者将60%的脉冲宽度赋予更大的功率,依此类推。

但是要小心,因为如果设备支持Vcc限制并且超出了PWM,则可能会损坏它。 因此,始终有必要尊重制造商提供的数据表的值。 另外,在某些设备(例如直流电动机)中, 接力,电磁铁等在工作周期后撤除电压可能意味着电感性负载可能会造成损坏。 这就是为什么 保护措施 及时。

Arduino上的PWM

Arduino I2C总线

现在您知道它是如何工作的,让我们看一下Arduino世界中PWM的具体情况...

PWM:Arduino上的引脚排列

在Arduino板上,您可以找到几个实现硬件PWM的引脚。 您可以在PCB本身上识别它们,因为它们具有 符号〜(小头) 以及引脚编号。 它也可以通过Arduino代码中的软件来完成,但是这会使微控制器工作繁重,而当它可以通过本机和硬件完成时,这是荒谬的。

  • Arduino UNO,迷你和纳米-您在引脚6、8、3、5、6和9上有10个11位PWM输出,这些输出将在数字的前面。
  • Arduino的兆丰-在此功能最强大的Arduino板上,您具有15个8位PWM输出。 它们位于引脚2到13和44到46上。
  • Arduino到期:在这种情况下,有13个8位PWM输出。 它们位于引脚2至13上,另外还有两个其他由12位分辨率的DAC离散化的模拟输出。

当谈到8位或12位分辨率等时,在这类PWM输出中,您指的是有足够的回旋余地。 和 8位具有256级 两者之间可以有所不同,并且12位最高可达4096级。

计时器控制

对于硬件PWM控制,Arduino 将使用计时器 为了它。 每个当前的定时器可以提供2或3个PWM输出。 每个输出的比较寄存器对该系统进行了补充,以便当时间达到寄存器的值时,将更改输出的状态或值以停止那些占空比。 尽管有两个输出由同一个定时器控制,但尽管它们共享相同的频率,但它们都可以具有不同的占空比。

对于与每个PWM引脚关联的定时器,它会有所不同 取决于Arduino开发板的类型 你有:

  • Arduino UNO,迷你和纳米:
    • 定时器0-5和6
    • 定时器1-9和10
    • 定时器2-3和11
  • Arduino的兆丰:
    • 定时器0-4和13
    • 定时器1-11和12
    • 定时器2-9和10
    • 计时器3-2、3和5
    • 计时器4-6、7和8
    • 计时器5-44、45和46

预分频寄存器将把时间除以一个整数,而定时器则将剩下的时间控制每个相关的PWM输出。 修改注册表值可以更改频率。 这 频率 根据计时器和盘子的不同,它们也会有所不同:

  • Arduino UNO,迷你和纳米:
    • 定时器0:允许预分频1、8、64、256和1024。频率为62.5 Khz。
    • 定时器1:预设为1、8、64、256和1024。频率为31.25 Khz。
    • Timer2:与Timer1相同,只是它在先前的计数基础上增加了32和128的预分频比。
  • Arduino的兆丰:
    • 定时器0、1、2:与上述相同。
    • Timer3、4和5:频率为31.25 Khz,并预先分频为1、8、64、256和1024。

不兼容和冲突

计时器 与输出关联的不仅是该功能,也被其他人使用。 因此,如果它们被另一功能使用,则必须在一个或另一个之间进行选择,不能同时使用这两个功能。 例如,以下是您在项目中可能发现的一些不兼容性:

  • 伺服库:使用伺服电机时,它会大量使用计时器,因此可能会产生冲突。 专门将Timer1用于UNO,Nano和Mini,即,在该库中使用草图时,不能使用引脚9和10。 在兆丰,这将取决于伺服器的数量...
  • SPI:如果Arduino板上使用SPI通信,则引脚11用于MOSI功能。 这就是为什么不能使用PWM引脚的原因。
  • 音色:此功能使用Timer2进行操作。 因此,如果使用它,则会使针脚3和11(对于Mega针脚来说是9和10)变得无用。

使用Arduino进行动手测试

带LED的Arduino PWM原理图

如果您想现场了解PWM在Arduino上的工作原理,那么您最好的办法就是连接一个 电压表或万用表 (用于测量电压)在您选择使用的PWM引脚与Arduino板的接地引脚或GND之间。 这样,借助此PWM技巧,您可以在测量设备的屏幕上看到数字输出的电压变化情况。

您可以将电压表/万用表替换为LED,以查看直流电动机或所需的任何其他元件的光强度如何变化。 我在图表中使用带更多指示灯的Fritzing简化了它,但是您知道它也可以代表万用表的技巧...

如果使用LED,请记住阴极和GND处的电阻。

源代码 为了控制Arduino开发板微控制器以使所有功能正常工作,您应该将其插入Arduino IDE(在这种情况下,我使用了PWM引脚6 Arduino UNO):

const int analogOutPin = 6;
byte outputValue = 0;  
 
void setup()
{  
   Serial.begin(9600);        
   pinMode(ledPIN , OUTPUT); 
 
   bitSet(DDRB, 5);       // LED o voltímetro
   bitSet(PCICR, PCIE0);       
   bitSet(PCMSK0, PCINT3);     
}
 
void loop() 
{
   if (Serial.available()>0)  
   {
      if(outputValue >= '0' && outputValue <= '9')
      {
         outputValue = Serial.read();   // Leemos la opción
         outputValue -= '0';      // Restamos '0' para convertir a un número
         outputValue *= 25;      // Multiplicamos x25 para pasar a una escala 0 a 250
         analogWrite(ledPIN , outputValue);
      }
   }
}  
 
ISR(PCINT0_vect)
{
   if(bitRead(PINB, 3))
   { 
      bitSet(PORTB, 5);   // LED on 
   }
   else
   { 
      bitClear(PORTB, 5); // LED off  
   } 
} 
我建议你玩的价值观,看看 灯或电压表上的结果。 该程序可以接收0到9的值,因此您可以看到所有变化情况。 欲了解更多信息,我建议你 Arduino课程 我们可以免费下载...

发表评论,留下您的评论

发表您的评论

您的电子邮件地址将不会被发表。 必填字段标有 *

*

*

  1. 负责数据:MiguelÁngelGatón
  2. 数据用途:控制垃圾邮件,注释管理。
  3. 合法性:您的同意
  4. 数据通讯:除非有法律义务,否则不会将数据传达给第三方。
  5. 数据存储:Occentus Networks(EU)托管的数据库
  6. 权利:您可以随时限制,恢复和删除您的信息。

  1.   何塞

    大家好首先,我要感谢您为最新的解释付出的时间。
    我想问你一个问题。 我正在尝试在Arguino Mega的proteus 8模拟器上运行代码。 我将电压表连接到引脚6,Proteus连接到串行端口,但是我不知道如何或如何改变以输出不同的电压。 我必须对代码进行些微调整才能使其编译。 非常感谢您的帮助