文档
LM358 运放应用电路设计与ADC采样代码例程
说明:LM358是纯模拟器件,本身没有代码接口。以下代码例程展示LM358在各种应用电路中配合MCU的ADC/GPIO进行信号采集与处理的完整方案。
一、电流采样放大电路 + ADC读取(Arduino)
电路说明
LM358构成差分放大器,将采样电阻(0.1Ω)上的微小电压放大后送入ADC。
负载电流 → 采样电阻(0.1Ω) → LM358差分放大(×50) → MCU ADC
// 使用LM358放大后的电流采样
#define CURRENT_PIN A0 // LM358输出接A0
#define SHUNT_RES 0.1 // 采样电阻 0.1Ω
#define GAIN 50.0 // LM358放大倍数
#define VREF 5.0 // 参考电压
#define ADC_RES 1024.0 // 10位ADC
void setup() {
Serial.begin(115200);
analogReference(DEFAULT); // 5V参考电压
}
void loop() {
int raw = analogRead(CURRENT_PIN);
float voltage = (raw / ADC_RES) * VREF; // LM358输出电压
float shuntVoltage = voltage / GAIN; // 采样电阻两端电压
float current = shuntVoltage / SHUNT_RES; // 实际电流
Serial.print("ADC原始值: "); Serial.print(raw);
Serial.print(" | 运放输出: "); Serial.print(voltage, 4);
Serial.print("V | 电流: "); Serial.print(current, 3);
Serial.println("A");
delay(500);
}
二、热电偶/温度传感器信号调理 + ADC读取
// LM358搭建同相放大器,将热电偶微弱电压放大100倍
// Vin(热电偶mV级) → LM358 ×100 → Vout(0-3.5V) → ADC
#define THERMO_PIN A1
#define GAIN 100.0
#define VREF 5.0
#define ADC_RES 1024.0
// K型热电偶近似线性系数 (μV/°C)
#define K_THERMO_SEEBECK 41.0 // μV/°C
void setup() {
Serial.begin(115200);
analogReference(DEFAULT);
}
float readThermocoupleTemp() {
int raw = analogRead(THERMO_PIN);
float vOut = (raw / ADC_RES) * VREF; // LM358输出电压(V)
float vIn = vOut / GAIN; // 热电偶原始电压(V)
float vIn_uV = vIn * 1000000.0; // 转换为μV
// 假定冷端为25°C,实际应用需冷端补偿
float temp = vIn_uV / K_THERMO_SEEBECK + 25.0;
return temp;
}
void loop() {
float temp = readThermocoupleTemp();
Serial.print("温度: "); Serial.print(temp, 1);
Serial.println(" °C");
delay(500);
}
三、LM358作为电压比较器 + GPIO中断(Arduino)
// LM358用作窗口比较器,监测电压是否超出阈值
// 同相端=参考电压(电位器分压),反相端=待测电压
// 输出接MCU GPIO中断
#define COMP_PIN 2 // LM358比较器输出接INT0(D2)
volatile bool overVoltage = false;
volatile uint32_t triggerCount = 0;
void IRAM_ATTR compISR() {
triggerCount++;
overVoltage = true;
}
void setup() {
Serial.begin(115200);
pinMode(COMP_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(COMP_PIN), compISR, FALLING);
Serial.println("LM358电压比较器监测启动");
Serial.println("阈值电压: ~2.5V (可通过电位器调节)");
}
void loop() {
if (overVoltage) {
overVoltage = false;
Serial.print("⚠ 过压报警! 触发次数: ");
Serial.println(triggerCount);
}
delay(10);
}
四、光敏传感器信号调理 + PWM输出(Arduino)
// LM358将光敏电阻分压信号缓冲后送ADC
// 根据光强自动调节LED亮度(PWM)
#define LDR_PIN A2 // LM358电压跟随器输出
#define LED_PIN 9 // PWM输出控制LED
void setup() {
Serial.begin(115200);
pinMode(LED_PIN, OUTPUT);
}
void loop() {
int raw = analogRead(LDR_PIN);
float voltage = (raw / 1024.0) * 5.0;
// 光敏电阻分压: 亮→电压低, 暗→电压高
// 映射为PWM: 暗时LED更亮
int brightness = map(raw, 0, 1023, 255, 0);
brightness = constrain(brightness, 0, 255);
analogWrite(LED_PIN, brightness);
Serial.print("光照ADC: "); Serial.print(raw);
Serial.print(" | PWM输出: "); Serial.println(brightness);
delay(100);
}
五、ESP-IDF ADC采集 + LM358信号调理
// ESP32通过ADC读取LM358调理后的传感器信号
#include "esp_adc/adc_oneshot.h"
#include "esp_adc/adc_cali.h"
#define ADC_CHANNEL ADC_CHANNEL_6 // GPIO34
#define GAIN 50.0f
static adc_oneshot_unit_handle_t adc_handle;
static adc_cali_handle_t cali_handle;
void app_main(void) {
// 初始化ADC
adc_oneshot_unit_init_cfg_t init_cfg = {
.unit_id = ADC_UNIT_1,
.ulp_mode = ADC_ULP_MODE_DISABLE,
};
adc_oneshot_new_unit(&init_cfg, &adc_handle);
adc_oneshot_chan_cfg_t chan_cfg = {
.atten = ADC_ATTEN_DB_11, // 0~3.6V量程
.bitwidth = ADC_BITWIDTH_12,
};
adc_oneshot_config_channel(adc_handle, ADC_CHANNEL, &chan_cfg);
// 校准
adc_cali_curve_fitting_config_t cali_cfg = {
.unit_id = ADC_UNIT_1,
.atten = ADC_ATTEN_DB_11,
.bitwidth = ADC_BITWIDTH_12,
};
adc_cali_create_scheme_curve_fitting(&cali_cfg, &cali_handle);
while (1) {
int raw = 0;
int voltage_mV = 0;
adc_oneshot_read(adc_handle, ADC_CHANNEL, &raw);
adc_cali_raw_to_voltage(cali_handle, raw, &voltage_mV);
float signal_mV = voltage_mV / GAIN; // 还原原始信号
printf("ADC Raw: %d | LM358 Out: %dmV | Signal: %.2fmV\n",
raw, voltage_mV, signal_mV);
vTaskDelay(pdMS_TO_TICKS(200));
}
}
六、常用LM358电路设计速查
| 应用场景 | 电路类型 | 增益公式 | 关键参数 |
|---|---|---|---|
| 电流检测 | 差分放大器 | Vout = (Rf/R1)×(V2-V1) | R1=R2, Rf=Rg (匹配电阻) |
| 温度传感 | 同相放大器 | Vout = Vin×(1+Rf/R1) | 增益50-200倍 |
| 电压跟随 | 缓冲器 | Vout = Vin | 输入阻抗>1MΩ |
| 电压比较 | 开环比较器 | 数字输出(0/VCC) | 加正反馈防抖 |
| 有源滤波 | Sallen-Key | 带通/低通/高通 | 截止频率<10kHz |
| 光电检测 | 跨阻放大器 | Vout = -Iin×Rf | Rf=10kΩ-1MΩ |