Op-amp: so sánh, khuếch đại không đảo, mạch đệm và đo hệ số khuếch đại bằng ESP32
Op-amp là gì, hai quy tắc tính mạch, mạch so sánh với quang trở, mạch đệm, khuếch đại không đảo và đảo, giới hạn của LM358 ở 3,3 V và thí nghiệm đo hệ số khuếch đại, bão hòa bằng ESP32.
Tín hiệu của nhiều cảm biến chỉ vài mV, quá nhỏ để ADC của ESP32 đọc chính xác; một quang trở cần báo "trời tối" khi vượt một ngưỡng; một cầu phân áp điện trở lớn bị ADC kéo lệch khi đọc. Cả ba việc này đều giải bằng cùng một linh kiện: op-amp (operational amplifier, khuếch đại thuật toán). Bài viết giải thích op-amp làm gì, hai quy tắc để tính mọi mạch op-amp cơ bản, mạch so sánh, ba mạch khuếch đại có hồi tiếp âm, những giới hạn của op-amp thật (nhất là LM358 khi chạy 3,3 V), rồi làm thí nghiệm với ESP32: quét điện áp vào bằng DAC, đo điện áp ra, tính hệ số khuếch đại và thấy op-amp bão hòa.
1. Op-amp là gì


Op-amp là một IC khuếch đại có hai đầu vào và một đầu ra. Nó khuếch đại hiệu điện áp giữa hai đầu vào với hệ số rất lớn:
U ra = A × (U+ − U−), với A (hệ số khuếch đại vòng hở) cỡ 100 000 lần.
- U+ là đầu vào không đảo: tăng U+ thì U ra tăng. U− là đầu vào đảo: tăng U− thì U ra giảm.
- Op-amp cần nguồn nuôi (V+ và V−; với mạch một nguồn, V− là GND). U ra không bao giờ vượt ra ngoài dải nguồn này.
- Vì A quá lớn, chỉ cần U+ chênh U− vài chục µV là ngõ ra đã chạm trần hoặc chạm sàn. Dùng op-amp "trần" như vậy là mạch so sánh. Muốn khuếch đại có kiểm soát, phải đưa một phần ngõ ra quay về đầu U−: đó là hồi tiếp âm.
LM358 chứa hai op-amp trong một vỏ 8 chân, rẻ và rất phổ biến; nguồn nuôi từ 3 V đến 32 V. Bên trong mỗi op-amp có khoảng mười mấy transistor ghép thành tầng vào vi sai, tầng khuếch đại và tầng ra (transistor ở bài 18, 21).
Hai quy tắc sau đủ để tính mọi mạch op-amp cơ bản có hồi tiếp âm:
- Đầu vào gần như không lấy dòng (cỡ nA). Có thể nối op-amp vào một cầu phân áp điện trở lớn mà không làm lệch điện áp.
- Khi có hồi tiếp âm, op-amp tự chỉnh U ra sao cho U+ ≈ U−. Nếu U− thấp hơn U+ một chút, U ra tăng, qua mạch hồi tiếp kéo U− lên, cho tới khi hai đầu vào bằng nhau.
2. Op-amp làm mạch so sánh

Không có hồi tiếp, op-amp chỉ trả lời câu hỏi "U+ có lớn hơn U− không": có thì ngõ ra lên cao, không thì xuống thấp. Trong ví dụ, quang trở và điện trở 10 kΩ tạo điện áp thay đổi theo ánh sáng ở đầu U+, biến trở đặt ngưỡng ở đầu U−. Đây đúng là cấu trúc của các module cảm biến ánh sáng, độ ẩm đất có chân DO: thường dùng IC so sánh LM393 (cùng sơ đồ chân với LM358, ngõ ra cực thu hở cần điện trở kéo lên). Quang trở và cầu phân áp có trong bài cảm biến ánh sáng: quang trở, photodiode, BH1750.
Khi ánh sáng thay đổi chậm quanh ngưỡng, nhiễu nhỏ cũng làm ngõ ra lật qua lật lại liên tục. Cách chữa là thêm trễ (hysteresis): một điện trở hồi tiếp dương từ ngõ ra về đầu U+ làm ngưỡng bật và ngưỡng tắt cách nhau một khoảng (mạch Schmitt trigger). Với vi điều khiển, trễ thường làm bằng phần mềm; bài 30 dùng đúng cách này cho đèn tự bật khi trời tối.
3. Ba mạch op-amp có hồi tiếp âm

- Mạch đệm (voltage follower): ngõ ra nối thẳng về U−, nên U ra = U+. Không khuếch đại, nhưng đầu vào không lấy dòng còn ngõ ra cấp được dòng: dùng để đọc một cầu phân áp điện trở lớn, một cảm biến trở kháng cao mà không làm lệch nó.
- Khuếch đại không đảo: cầu phân áp Rf, Rg đưa một phần U ra về U−: U− = U ra × Rg / (Rf + Rg). Theo quy tắc 2, U− = U+, suy ra U ra = U+ × (1 + Rf / Rg). Với Rf = 100 kΩ, Rg = 10 kΩ, hệ số là 11. Hệ số chỉ phụ thuộc hai điện trở, không phụ thuộc A của op-amp: đó là cái lợi của hồi tiếp âm.
- Khuếch đại đảo: U+ nối đất nên U− cũng giữ ở 0 V (gọi là "đất ảo"); dòng qua Rin bằng dòng qua Rf, suy ra U ra = −U vào × Rf / Rin. Ngõ ra ngược dấu, nên với nguồn đơn phải nâng U+ lên điểm giữa nguồn (ví dụ 1,65 V) thay vì nối đất.
4. Giới hạn của op-amp thật

- Dải điện áp vào: LM358 chỉ làm việc đúng khi điện áp vào nằm trong khoảng 0 đến VCC − 1,5 V. Nuôi 3,3 V thì chỉ tới khoảng 1,8 V.
- Dải điện áp ra: LM358 xuống sát 0 V được nhưng không lên sát nguồn dương; nuôi 3,3 V thì ra tối đa khoảng 1,8 V. Op-amp loại rail-to-rail (như MCP6002, TLV2372) vào và ra được gần hết dải nguồn, hợp với hệ 3,3 V hơn.
- Băng thông: tích hệ số khuếch đại × băng thông (GBW) gần như không đổi, khoảng 0,7 MHz với LM358. Khuếch đại 11 lần thì tín hiệu trên khoảng 64 kHz bắt đầu bị giảm.
- Offset: hai đầu vào không cân bằng tuyệt đối, sai lệch tối đa khoảng 7 mV với LM358 (thường 2–3 mV). Sai lệch này cũng bị nhân theo hệ số khuếch đại.
LM358 nuôi 5 V thì ngõ ra lên được tới khoảng 3,5 V, có thể vượt mức chịu đựng của chân ESP32. Thí nghiệm dưới đây nuôi LM358 bằng 3,3 V để ngõ ra không bao giờ vượt quá 3,3 V.
5. Thí nghiệm: đo hệ số khuếch đại của LM358 bằng ESP32
ESP32 tạo điện áp vào bằng DAC (GPIO25), đi qua cầu chia 11 lần vào chân + của op-amp khuếch đại không đảo hệ số 11. Như vậy nếu op-amp lý tưởng, điện áp ra đúng bằng điện áp DAC; mọi chỗ lệch là do giới hạn của op-amp thật.
Chuẩn bị
- ESP32 DevKit V1, breadboard, dây cắm.
- Một IC LM358 vỏ DIP-8; điện trở 100 kΩ, hai điện trở 10 kΩ, một điện trở 1 kΩ; tụ gốm 100 nF.
Sơ đồ nối

- Cầu chia 10 kΩ / 1 kΩ làm điện áp ở chân + chỉ còn 1/11 điện áp DAC (0 đến khoảng 0,3 V), để sau khi khuếch đại 11 lần, ngõ ra quay về cùng dải với DAC.
- GPIO35 đo điện áp DAC trước cầu chia, rồi chương trình chia 11 để biết U+. Đo thẳng U+ (vài chục mV) thì ADC của ESP32 sai số lớn ở vùng điện áp thấp.
- Op-amp B không dùng phải nối thành mạch đệm với đầu + xuống GND; để hở, nó có thể tự dao động và gây nhiễu cho op-amp A.
Chương trình
/*
PYWORLD.VN - Op-amp LM358 khuếch đại không đảo với ESP32: quét DAC, đo điện áp ra, tính hệ số khuếch đại và thấy bão hòa
LM358 nuôi 3,3 V. GPIO25 (DAC) qua cầu 10 kΩ / 1 kΩ vào chân 3 (+); hồi tiếp 100 kΩ từ chân 1 về chân 2, 10 kΩ từ chân 2 xuống GND
GPIO35 đo điện áp DAC trước cầu chia, GPIO34 đo điện áp ra ở chân 1
*/
#define CHAN_DAC 25
#define CHAN_DO_DAC 35
#define CHAN_DO_RA 34
const float HE_SO_CHIA = 11.0; // Cầu 10 kΩ / 1 kΩ: U+ = U DAC / 11
const float HE_SO_LY_THUYET = 11.0; // Khuếch đại không đảo: 1 + 100 kΩ / 10 kΩ
const int BUOC_DAC = 15; // 0, 15, 30 ... 255
const int SO_LAN_DOC = 32;
uint32_t docMv(int chan) {
uint32_t tong = 0;
for (int i = 0; i < SO_LAN_DOC; i++) tong += analogReadMilliVolts(chan);
return tong / SO_LAN_DOC;
}
void setup() {
Serial.begin(115200);
analogReadResolution(12);
dacWrite(CHAN_DAC, 0);
delay(500);
Serial.println("LM358 khuech dai khong dao, he so ly thuyet 11");
}
void loop() {
Serial.println("DAC | U DAC (mV) | U+ (mV) | U ra (mV) | he so do");
for (int muc = 0; muc <= 255; muc += BUOC_DAC) {
dacWrite(CHAN_DAC, muc);
delay(30); // Chờ op-amp và điện áp ổn định
uint32_t uDac = docMv(CHAN_DO_DAC);
uint32_t uRa = docMv(CHAN_DO_RA);
float uCong = uDac / HE_SO_CHIA; // Điện áp ở chân + của op-amp
Serial.printf("%3d | %4u | %6.1f | %4u", muc, (unsigned)uDac, uCong, (unsigned)uRa);
if (uCong < 10.0) { // Tín hiệu quá nhỏ, ADC đọc không đủ chính xác để chia
Serial.println(" | ---");
} else {
float heSo = uRa / uCong; // Hệ số khuếch đại đo được = U ra / U+
Serial.printf(" | %5.2f%s\n", heSo, heSo < 0.9 * HE_SO_LY_THUYET ? " <- bao hoa" : "");
}
delay(300);
}
dacWrite(CHAN_DAC, 0);
Serial.println();
delay(5000);
}
- Chương trình tăng giá trị DAC từ 0 tới 255, mỗi bước 15. Mỗi bước đo 32 lần điện áp DAC và điện áp ra rồi lấy trung bình.
- Hệ số đo được = U ra / U+. Khi hệ số tụt dưới 90 % của 11, chương trình đánh dấu "bao hoa".
- Khi U+ dưới 10 mV (DAC gần 0), phép chia không còn ý nghĩa nên chương trình in "---".
Kết quả mong đợi


- Vùng tuyến tính (DAC tới khoảng 135): U ra gần bằng U DAC, hệ số đo được quanh 11. Ở tín hiệu nhỏ, hệ số có thể lớn hơn 11 một chút vì offset của op-amp (vài mV nhân 11) và sai số ADC cộng thêm vào U ra.
- Vùng bão hòa: khi U ra chạm khoảng 1,8 V, op-amp không lên được nữa dù U+ tiếp tục tăng; hệ số đo được giảm dần. Đây chính là giới hạn "VCC − 1,5 V" đọc được trong datasheet (bài 23).
- Thử đổi điện trở 10 kΩ ở chân 2 thành 22 kΩ: hệ số lý thuyết còn 1 + 100/22 ≈ 5,5, ngõ ra chỉ bằng khoảng một nửa U DAC và vùng tuyến tính kéo dài hơn. Nhớ sửa hằng số
HE_SO_LY_THUYETcho khớp.
6. Xử lý lỗi thường gặp
| Hiện tượng | Nguyên nhân thường gặp | Cách xử lý |
|---|---|---|
| U ra luôn khoảng 1,8 V | Nhầm chân 2 và 3 (hồi tiếp thành dương), hoặc thiếu điện trở 10 kΩ xuống GND ở chân 2 | Kiểm tra lại: hồi tiếp phải về chân 2 (−), tín hiệu vào chân 3 (+) |
| U ra luôn gần 0 V | Chưa cấp nguồn chân 8, hoặc DAC không chạy (sai chân) | Đo chân 8 có 3,3 V; đo GPIO25 bằng đồng hồ khi chương trình quét |
| Hệ số đo được lệch nhiều so với 11 | Điện trở sai giá trị (đọc nhầm vòng màu), hoặc nhầm 1 kΩ với 10 kΩ ở cầu chia | Đo từng điện trở bằng đồng hồ trước khi cắm |
| Kết quả nhảy lung tung | Op-amp B để hở tự dao động; thiếu tụ 100 nF ở nguồn | Nối op-amp B thành mạch đệm; thêm tụ sát chân 8 và 4 |
| Bão hòa sớm hơn 1,8 V | Nguồn 3,3 V thực tế thấp hơn, hoặc tải nặng ở ngõ ra | Đo nguồn; ngõ ra chỉ nối vào chân ADC |
7. Xem thêm
- Cảm biến ánh sáng: quang trở, photodiode, BH1750: nơi mạch so sánh và mạch khuếch đại photodiode được dùng.
- Các bài liên quan trong loạt điện tử căn bản: mạch khuếch đại E chung (bài 21), đọc datasheet (bài 23), dự án đèn tự động (bài 30).
- Bài tiếp theo của loạt: cổng logic và IC 74HC.
Xem thêm