16-битный ШИМ не достигает абсолютного 0 В

void setup() {
  Serial.begin(9600);
  setupPWM16();
}

uint16_t icr = 0xffff;

void loop() {
  analogWrite16(9, 0);
}
void setupPWM16() {
  DDRB  |= _BV(PB1) | _BV(PB2);       /* set pins as outputs */
  TCCR1A = _BV(COM1A1) | _BV(COM1B1)  /* non-inverting PWM */
        | _BV(WGM11);                 /* mode 14: fast PWM, TOP=ICR1 */
  TCCR1B = _BV(WGM13) | _BV(WGM12)
        | _BV(CS10);                  /* prescaler 1 */
  ICR1 = icr;                         /* TOP counter value (freeing OCR1A*/
}

/* 16-bit version of analogWrite(). Works only on pins 9 and 10. */
void analogWrite16(uint8_t pin, uint16_t val)
{
  switch (pin) {
    case  9: OCR1A = val; break;
    case 10: OCR1B = val; break;
  }
}

Используя приведенный выше код, я могу получить 16-битный ШИМ-сигнал, но при записи 0 в analogWrite16 получается ~33 мВ. Я знаю, что могу установить низкий уровень на выводе ШИМ, но снова он не выдает 0 В.

Я предполагаю, что помимо смещения ATMEGA, плата Arduino UNO, ее само заземление поднято либо из-за того, что он питается от USB, либо из-за сопротивления схемы платы и дорожек печатной платы. или оба?

потому что смещение ~33 мВ — это много, это нормально?

Как заставить Arduino начинать с 0 В или, по крайней мере, уменьшить это смещение 33 мВ до 1-2 мВ?

, 👍0


1 ответ


Лучший ответ:

1

У вас есть две возможности:

  1. Вы не можете полностью отключить режим "неинвертирующий ШИМ"
  2. Вы не можете полностью включить режим "инвертирующий ШИМ"

В ядре Arduino это решается отключением выхода ШИМ и установкой логических 0 или 1 для угловых значений.

И если вам нужно полное выключение, но вам не нужно полное включение, вы можете использовать инвертированный режим ШИМ.

,

Как использовать инвертированный режим? есть ли код, который я должен изменить?, @ElectronSurf

Вам просто нужно изменить значения COM1A/COM1B (это в таблице данных) и вычислить правильное значение для OCR1A/OCR1B (что-то вроде 0xFFFFU - val), @KIIV