20位编码器入门指南:从原理到实战避坑

1次阅读
没有评论

共计 1170 个字符,预计需要花费 3 分钟才能阅读完成。

image.webp

为什么需要 20 位编码?

在嵌入式开发中,ADC 信号采集是一个常见需求。以温度传感器为例,8 位编码只能提供 256 个离散值,对应 0.5℃的分辨率;16 位编码虽然提升到 65536 个值,但在高精度场合(如医疗设备)仍显不足。20 位编码器可提供 1,048,576 个量化等级,分辨率达到 0.0001℃,满足精密测量需求。

20 位编码器入门指南:从原理到实战避坑

核心原理

二进制权重与量化误差

20 位编码的核心是二进制权重分配,其量化误差公式为:

E_q = V_ref / (2^20 - 1)

其中 V_ref 为参考电压。例如当 V_ref=5V 时,理论最小分辨率为 4.77μV。

代码实现

SPI 接口配置(STM32F4 系列)

// SPI1 初始化(时钟极性 CPOL=1, 相位 CPHA=1)void SPI1_Init(void) {
    RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;  // 使能 SPI1 时钟
    SPI1->CR1 = SPI_CR1_CPOL | SPI_CR1_CPHA  // 模式 3
              | SPI_CR1_BR_2  // 波特率 =f_pclk/64
              | SPI_CR1_MSTR; // 主机模式
    SPI1->CR1 |= SPI_CR1_SPE; // 使能 SPI
}

使用 union 处理高低位

typedef union {
    uint32_t full_data;
    struct {
        uint16_t low_word;
        uint16_t high_word;
    } parts;
} EncoderData;

// 读取 20 位数据(有效位在 bit19-bit0)EncoderData read_encoder(void) {
    EncoderData data;
    data.parts.high_word = SPI1->DR & 0x0FFF; // 取高 12 位
    data.parts.low_word = SPI1->DR & 0xFFFF;  // 取低 16 位
    return data;
}

硬件设计要点

  1. 电源滤波
  2. 在 ADC 参考电压引脚添加 10μF 钽电容 +100nF 陶瓷电容
  3. 模拟电源与数字电源间使用磁珠隔离

  4. SPI 布线

  5. 时钟线长度不超过 15cm
  6. 使用双绞线或屏蔽线传输

测试方法

示波器捕获时序

  1. 连接 CH1 到 SPI_CLK,CH2 到 SPI_MISO
  2. 设置触发模式为 CLK 下降沿
  3. 测量 CS 下降沿到第一个时钟沿的延迟(应 >100ns)

避坑指南

  • 电源噪声
    当 LSB 位频繁跳变时,检查电源纹波是否超过 10mVpp

  • 端序问题
    ARM 架构默认小端序,与网络传输的大端序需转换:

    uint32_t swap_endian(uint32_t x) {return ((x >> 24) & 0xff) | ((x << 8) & 0xff0000) 
               | ((x >> 8) & 0xff00) | ((x << 24) & 0xff000000);
    }

思考题延伸

过采样技术可通过 4^n 倍采样提升 n 位有效分辨率。例如:
– 4 倍采样→+ 1 位
– 16 倍采样→+ 2 位

实际应用中,需要权衡采样速度与分辨率提升的收益。

正文完
 0
评论(没有评论)