Mizar32/ADC
ADC 代表模数转换器。在现实世界中,光或声音等信号的值通常可以通过模拟方式测量,但为了让微控制器处理这些值,必须将其转换为数字信息。ADC 执行这项工作,并嵌入到所有现代微控制器中。
因此,ADC 电路是感知外部世界最常见的方式,但它并不那么智能。它只能在某个时间点测量电压水平,并且您需要另一块硬件(传感器)才能将您的模拟值转换为电压,以便与 ADC 配合使用并成为数字信息。一些常见的模拟传感器类型包括光、声音、温度、湿度、各种气体、电力传感器以及许多其他传感器。
ADC 电路所做的是不时从模拟信号中采样。每个样本都被转换为一个数字,该数字代表模拟信号波形的某个时间点的值。
举个常见的例子,CD 包含音乐的数字样本,这些样本是音频(实际上是连续波形)的模数转换结果,采样率为 44.1Khz。这意味着每秒 44,100 次,它的音频波形会被采样成一个 16 位分辨率的数字:一个 0 到 65,535 之间的数字。为什么是 65,535?因为每个样本都用 16 位表示,每位可以取两个值中的一个(0 和 1),这将为您提供 216 = 65,536 个不同的可能值,这些值就是 0 到 65535 之间的所有数字。
在任何模数转换中,我们都有这两个重要的参数,频率或采样率以及数字(样本本身),其具有固定的位分辨率。分辨率是采样数据的精度。
Mizar32 的 ADC 以 8 位或 10 位分辨率进行采样,这提供了 256 或 1024 个不同的可能值。这比音频 CD 的高保真度精度低,但对于测量温度、压力、光强度以及大多数其他物理信号来说已经足够精确了。
为了更好地解释分辨率的概念,我们输入波形中表示的每个采样点的值将存储在固定长度的变量中。如果该变量使用八位,则意味着它可以保存从 0 到 255(28 = 256)的值。如果该变量使用 10 位,则意味着它可以保存从 0 到 1023(210 = 1024)的值。在 10 位分辨率的情况下,数字 0 代表最低电压,数字 1023 代表最高电压。
AVR32 中使用的 ADC 类型是逐次逼近寄存器 (SAR) ADC,它会不断将它正在采样的信号与其当前最佳估计值进行比较,直到它获得最接近的值,并在 10 位分辨率的情况下在 10 个时钟周期内找到样本的正确数字值。
这种电路的另一个优点是使用输出缓冲器,它允许由 ADC 供电的电路在 ADC 正在处理下一个样本时读取数字数据。
Mizar32 具有一个模数转换器,它在多达八个输入之间进行多路复用,即 ADC0 到 ADC7。
ADC 通道可以在硬件中设置为执行 8 位或 10 位转换,输入电压范围为 0V 到 VDDANA(BUS1,引脚 9),它通过 R3(一个 0 欧姆电阻)与 Mizar32 主板上的 3.3V 相连。
信号 | GPIO | 总线引脚 | eLua 名称 | PicoLisp | 备注 |
---|---|---|---|---|---|
ADC0 | PA21 | BUS5 引脚 5 | pio.PA_21 |
'PA_21 |
|
ADC1 | PA22 | BUS5 引脚 6 | pio.PA_22 |
'PA_22 |
|
ADC2 | PA23 | BUS5 引脚 7 | pio.PA_23 |
'PA_23 |
|
ADC3 | PA24 | BUS2 引脚 3 | pio.PA_24 |
'PA_24 |
(1) |
ADC4 | PA25 | BUS6 引脚 4 | pio.PA_25 |
'PA_25 |
|
ADC5 | PA26 | BUS6 引脚 5 | pio.PA_26 |
'PA_26 |
|
ADC6 | PA27 | BUS6 引脚 6 | pio.PA_27 |
'PA_27 |
|
ADC7 | PA28 | BUS6 引脚 7 | pio.PA_28 |
'PA_28 |
(1) ADC3 与以太网中断共享总线引脚,当不存在以太网附加板时,可以将其用作 ADC 输入。
Alcor6L 的 ADC
模块用于配置和读取 ADC 输入。至少需要两次函数调用:一次启动转换,另一次读取结果值,这些值范围从 0(在 0V 时)到 1023(在 3.3V 时)。
在 eLua 中
-- Repeatedly measure and print the value on ADC channel 0
adc_channel = 0 -- Measure the first ADC channel
while true do
adc.sample( adc_channel, 1 ) -- start conversion of one sample
print( adc.getsample ( adc_channel ) ) -- read the result and print it
end
在 PicoLisp 中
# Repeatedly measure and print the value on ADC channel 0
(setq adc-channel 0) # Measure the first ADC channel
(loop
(adc-sample adc-channel 1) # start conversion of one sample
(prinl (adc-getsample adc-channel)) ) # read the result and print it
如果 ADC 引脚未用作 ADC 输入,则可以通过调用 PIO 子系统中的 setdir
函数将其用作通用 PIO 引脚。例如,要将 BUS5 引脚 7(ADC5)用作 PIO 输出而不是 ADC 输入,您可以使用以下代码
语言 | 代码 |
---|---|
eLua | pio.pin.setdir(pio.OUTPUT, pio.PA_24)
|
PicoLisp | (pio-pin-setdir *pio-output* 'PA_24)
|
请注意,ADC 的 setclock
函数在 AVR32 上未针对任何 Alcor6L 语言实现。请参阅 问题 #25。
- 有关 eLua 的所有
adc.*()
函数的详细信息,请参阅 eLua 手册的 ADC 部分; - 有关 Atmel AT32UC3A 数据手册的详细信息,请参阅 第 33 章:模数转换器 (ADC)。