You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Digispark ATtiny85调用analogRead()读取低电压时OLED死机问题

问题分析与解决方案

核心问题

  1. 引脚功能冲突:ATtiny85的PB0(对应A0)同时是I2C的SDA引脚(用于OLED通信)和ADC0输入引脚。你在程序中同时使用该引脚进行ADC读取和OLED的I2C通信,会导致硬件模式冲突:当执行analogRead(A0)时,引脚被切换为ADC输入模式,直接中断OLED的I2C通信,引发死机。
  2. ADC配置被覆盖:Arduino的analogRead()函数会完全重置ADMUX寄存器,你在setup中手动设置的1.1V内部参考电压和ADC通道配置会被覆盖,导致实际ADC工作状态不符合预期。

解决方案

1. 更换无冲突的ADC引脚

选择ATtiny85上不与I2C引脚(PB0=SDA、PB2=SCL)冲突的ADC通道:

  • A2(PB4,对应ADC2)
  • A3(PB3,对应ADC3)

将被测电压的分压电路连接到上述引脚之一,比如A3。

2. 正确配置ADC参考电压

使用Arduino官方的analogReference()函数设置参考电压,避免手动修改寄存器被analogRead()覆盖:

analogReference(INTERNAL1V1); // 设置ADC参考为内部1.1V

3. 修改代码适配新引脚

以下是调整后的完整代码(以A3为例):

#include <Wire.h>
#include <Tiny4kOLED.h>

void setup() {
  // 设置ADC参考电压为内部1.1V
  analogReference(INTERNAL1V1);
  
  oled.begin();
  oled.setFont(FONT8X16);
  oled.clear();
  oled.on();
  oled.switchRenderFrame();
}

void loop() {
  updateDisplay();
  delay(50);
}

void updateDisplay() {
  oled.clear();
  // 读取A3引脚的ADC值
  int sensorValue = analogRead(A3);
  
  // 计算实际电压:(sensorValue * 1100) / 1023 得到毫伏值
  long mVolt = (sensorValue * 1100L) / 1023;
  float volt = mVolt / 1000.0;

  oled.setCursor(0, 0);
  oled.print(F("Cable Volts: "));
  oled.print(volt, 2); // 保留两位小数显示
  
  oled.switchFrame();
}

额外说明

  • 如果必须使用A0引脚,需要在每次ADC读取后手动恢复I2C引脚的功能,但这种方法容易出错,不推荐。
  • 确保分压电路的输出电压不超过ADC参考电压(1.1V),否则会导致ADC读数饱和。

内容的提问来源于stack exchange,提问作者Jake Passolt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 16:57:29