class ADC – 模拟信号转换为数字信号

Usage

import pyb

adc = pyb.ADC(pin)              # create an analog object from a pin
                                # 根据一个引脚对象, 创建一个模拟(ADC)对象 
val = adc.read()                # read an analog value 
                                # 读取模拟值

adc = pyb.ADCAll(resolution)    # create an ADCAll object
                                # 创建一个ADCAll 对象
val = adc.read_channel(channel) # read the given channel
                                # 从给定channel读取值
val = adc.read_core_temp()      # read MCU temperature
                                # 读取芯片温度
val = adc.read_core_vbat()      # read MCU VBAT 
                                # 读取电源电压
val = adc.read_core_vref()      # read MCU VREF 
                                # 电压基准 指输入的模拟电压的最大值

Constructors

class pyb.ADC(pin)

创建一个ADC对象并于特定引脚(Pin)关联, 之后可以在此引脚读取模拟值.

Methods

adc.read()

从模拟引脚读取值, 然后返回改值.

返回的值, 区值范围在 0-4095之间.

adc.read_timed(buf, timer)

因为在定时器运行的时候, 不可以申请新的内存空间, 所以可以创建一个缓冲池(buffer) 来存放

按照一定的速率(根据定时器产生)将读取的模拟值信号存入缓存中(buffer)

buf 可选的数据类型有两种

  • bytearray
  • array.array

根据选择的数据类型的不同, 模拟值的位数也不同

Buffer位数大小 模拟值存储位数
>=16-bit 12-bit
8-bit 8-bit

timer

timer的参数类型一共有两种, 一种是传入一个timer对象, 另外是传入一个数值(预期的取样频率)

定时器对象

定时器对象. 在定时器触发的时候, 取一次样.

传入此timer对象的时候, timer对象必须要已经初始化的, 而且按照预期的频率在运行.

运行示例

adc = pyb.ADC('P6')                 # create an ADC on pin P6
                                    # 在P6创建一个ADC对象
tim = pyb.Timer(6, freq=10)         # create a timer running at 10Hz
                                    # 创建timer6, 以10HZ的频率运行
buf = bytearray(100)                # create a buffer to store the samples
                                    # 创建一个缓冲池, 用于存放取样的值
adc.read_timed(buf, tim)            # sample 100 values, taking 10s
                                    # 在10s的时候, 100个取样的值, 刚好填满缓冲池

特定频率

adc = pyb.ADC('P6')                 # create an ADC on pin P6
                                    # 在引脚P6创建一个ADC对象
buf = bytearray(100)                # create a buffer of 100 bytes
                                    # 创建一个100字节的缓冲池
adc.read_timed(buf, 10)             # read analog values into buf at 10Hz
                                    # this will take 10 seconds to finish
                                      # 从模拟口以10HZ的频率读取数据, 10s数据读取完成
                                    # 语句结束
for val in buf:                     # For循环所有的数值
    print(val)                      # 打印出来

class ADCAll Object

将所有的ADC引脚都设定位模拟输入模式.

原始的单片机的温度, 基准电压, 电源电压可以在ADC频道 16, 17, 18上获取到. 获取的值需要做一定的拉伸变换.

芯片上的温度传感器在获取温度绝对值上准确度不高, 适合用于检测温度的相对变化.

read_core_vbat() 读取备用电源电压(一般为1.21v)

read_core_vref参照电压, 参考值为3.3v

假定ADCAll对象被下列语句实例化

adc = pyb.ADCAll(12)

3.3V的供电电压, 可以被计算出来

v33 = 3.3 * 1.21 / adc.read_core_vref()

如果3.3V的供电电压对于adc.read_core_vbat() 是正确的, 则供电电压为有效.

如果供电电压, 低于3.3V, 例如用一个没电的电池来给OpenMV供电的时候, 稳定器会失效, 电压不能稳定在3.3V, 将会导致错误的数据采样.

To produce a value which will remain valid under these circumstances use the following:

vback = adc.read_core_vbat() * 1.21 / adc.read_core_vref()

It is possible to access these values without incurring the side effects of ADCAll:

def adcread(chan):                              # 16 temp 17 vbat 18 vref
    assert chan >= 16 and chan <= 18, 'Invalid ADC channel'
    start = pyb.millis()
    timeout = 100
    stm.mem32[stm.RCC + stm.RCC_APB2ENR] |= 0x100 # enable ADC1 clock.0x4100
    stm.mem32[stm.ADC1 + stm.ADC_CR2] = 1       # Turn on ADC
    stm.mem32[stm.ADC1 + stm.ADC_CR1] = 0       # 12 bit
    if chan == 17:
        stm.mem32[stm.ADC1 + stm.ADC_SMPR1] = 0x200000 # 15 cycles
        stm.mem32[stm.ADC + 4] = 1 << 23
    elif chan == 18:
        stm.mem32[stm.ADC1 + stm.ADC_SMPR1] = 0x1000000
        stm.mem32[stm.ADC + 4] = 0xc00000
    else:
        stm.mem32[stm.ADC1 + stm.ADC_SMPR1] = 0x40000
        stm.mem32[stm.ADC + 4] = 1 << 23
    stm.mem32[stm.ADC1 + stm.ADC_SQR3] = chan
    stm.mem32[stm.ADC1 + stm.ADC_CR2] = 1 | (1 << 30) | (1 << 10) # start conversion
    while not stm.mem32[stm.ADC1 + stm.ADC_SR] & 2: # wait for EOC
        if pyb.elapsed_millis(start) > timeout:
            raise OSError('ADC timout')
    data = stm.mem32[stm.ADC1 + stm.ADC_DR]     # clear down EOC
    stm.mem32[stm.ADC1 + stm.ADC_CR2] = 0       # Turn off ADC
    return data

def v33():
    return 4096 * 1.21 / adcread(17)

def vbat():
    return  1.21 * 2 * adcread(18) / adcread(17)  # 2:1 divider on Vbat channel

def vref():
    return 3.3 * adcread(17) / 4096

def temperature():
    return 25 + 400 * (3.3 * adcread(16) / 4096 - 0.76)
Copyright 杭州云江科技有限公司 2017 all right reserved,powered by Gitbook该文件修订时间: 2018-04-02 09:53:12

results matching ""

    No results matching ""