上面的内容我们说了数字输出型驱动电路和数字输出型驱动电路,数字量是一种布尔类型的变量,它只有两种状态,这里我们来聊聊模拟量。

对于一个灯来说,我们通过数字量可以描述它的两种状态——开和关,开灯即亮,关灯即灭。在这个基础上,我想去实现对灯的亮度进行控制,这里所说的“亮度”就是一种模拟量。

对于热水和冷水来说,我们通过数字量可以描述的是热和凉两个状态,但如果我想有个相对精确的数值来描述,那这个数值一定就是温度,这里所说的“温度”就是一种模拟量。

数字量反应的有无,表述的是0和1的关系;而模拟量表述的则是在0和1之间的一种“程度”。

我想控制一个灯的亮度怎么办,很简单!调节灯的电压就可以实现,电压越大灯就越亮,反之亦然如此。那么我们如何控制单片机输出一个模拟量,就像实现控制一个LED的亮度;又或者是如何控制单片机读取一个模拟量,比如说读取温度值。

数字量Digital,模拟量Analog,变换Change。

先记住上面的这一行内容!

这里我以Arduino UNO/Nano/Micro(它们三个的单片机一样)举例,它的主控制芯片是Atmega 328P单片机,具备8位模拟输出和10位AD采集,这里我们先来聊聊8位模拟输出。

模拟量的产生由很多方法,对于Arduino来说PWM就是它的方法。

要说PWM啊,我们先来聊两个概念——频率和占空比!

频率这个词大家应该都不会陌生,是指单位时间内完成周期性变化的次数,这个单位时间我们大多默认的就是1秒钟。比如说我在1秒钟执行了20次,那么我就可以说频率是20Hz,频率=1/单位时间。

占空比这个概念呢,大家可能会陌生一些。我先做个假设,假如单片机的一个引脚输出20Hz的频率,那么产生1Hz的频率需要的时间是多久呢?答案是1s/20=0.05s=50ms!

也就是说,我控制单片机的引脚每50ms完成一次高低电平的变化,实现这个引脚在1s的时间内可以产生20次高低电平的变化,这就是控制单片机的引脚输出20Hz的频率。

我在20ms的时间内,保持引脚处于高电平10ms,处于低电平10ms,那么此时的占空比就是50%;如果我保持引脚处于高电平5ms,处于低电平15ms,那么此时的占空比就是25%,所以占空比就是在一次周期性的电平变化中,所处于高电平的时间与周期时间的比值。

PWM产生的是方波信号(还正弦波、三角波等等,后续我们再聊),Arduino的PWM精度是8位,所以输出的PWM值为0~255(28),默认的频率是490Hz(基本认为是500Hz),这里给大家一个参考资料。图太多了,不想画,人家做的挺好的!

那么PWM如何实现模拟量输出呢?简单来说,PWM如何实现对LED亮度控制!我们之前聊到,通过调节加载LED两侧的电压就可以实现对LED的亮度进行控制,那么PWM实现的是对单片机IO电压的控制吗?

是的,可以这样理解。

不是的,实现并不是这样的实现的。

对于Arduino来说,0~255的输出值,对应的就是0~100%的占空比,订阅就是0~5V的电压值。

如果Arduino的PWM输出值是153,那么此时的占空比就是60%,即在2ms(500Hz)的情况下,高电平占1.2ms,低电平占0.8s,这个引脚对应的电压值就是3V,这就是PWM模拟输出。

PWM的弊端在于,它是通过延时来实现模拟输出的,因为使用的是延时,决定了它的频率不会太高。Arduino内置的延时函数最小是μs,1s = 1000ms=1000 000μs,而且只能取整数。也就是说Arduino使用延时最多只能输出50%的占空比、频率为500KHz的方波。

所以说,对于模拟输出、对于LED的亮度控制,实质上是一种”欺骗“!

我们通过数字引脚输出模拟信号的方式,就是数字信号向模拟信号的变换,用英文来说就是Digital Analog Change,简称DAC数模转换输出。

关于DAC的内容,更多时候我们可以借助一些芯片来实现,这部分我们后续再聊!