Главная » Микроконтроллеры » ATtiny13 — аппаратный ШИМ

ATtiny13 — аппаратный ШИМ

В этой статье расcкажем, как заставить ATtiny13 генерировать аппаратный сигнал ШИМ (широтно-импульсной модуляции).

В примере кода используется таймер в режиме Fast PWM (WGM02: 0 = 3, см. раздел 11.7.3 руководства). В этом режиме, устанавливая биты COM0A1:0 в единицу, блок сравнения позволяет генерировать сигналы ШИМ на выводе AC0A (PB0) с рабочим разрешением 0..255.

Представленный пример может работать на нескольких частотах: 4,687 кГц, 585 Гц, 73 Гц, 18 Гц, 4 Гц (@ 1,2 МГц). Если вам нужны более высокие частоты ШИМ, установите биты предохранителя для запуска ATtiny13 с источником тактовой частоты 9,6 МГц. Код примера находится на Github, щелкните здесь.

ШИМ на Attiny13 - осциллограмма

Требуемые детали

Принципиальная электрическая схемаПринципиальная электрическая схема ШИМ на Attiny13

Этот код написан на C и может быть скомпилирован с помощью avr-gcc. Вся информация о том, как скомпилировать этот проект AVR, находится здесь.

 #include <avr/io.h>
#include <util/delay.h>
 #define N_1    (_BV(CS00))
#define N_8    (_BV(CS01))
#define N_64   (_BV(CS01)|_BV(CS00))
#define N_256  (_BV(CS02))
#define N_1024 (_BV(CS02)|_BV(CS00))
 static void
pwm_init(void)
{
    DDRB |= _BV(PB0); // установите вывод PWM как ВЫХОД
    TCCR0A |= _BV(WGM01)|_BV(WGM00); // установить режим таймера на FAST PWM
    TCCR0A |= _BV(COM0A1); // подключить сигнал PWM к выводу (AC0A => PB0)
}
/ * Когда таймер установлен в режим Fast PWM, частота может быть рассчитана по формуле: F = F_CPU / (N * 256)
Возможные частоты (при 1,2 МГц):
  -> F (N_1) = 4,687 кГц
  -> F (N_8) = 585 Гц
  -> F (N_64) = 73 Гц
  -> F (N_256) = 18 Гц
  -> F (N_1024) = 4 Гц * /
  
static void
pwm_set_frequency(uint32_t N)
{
     TCCR0B = (TCCR0B & ~((1<<CS02)|(1<<CS01)|(1<<CS00))) | N; // sустановить предварительный делитель
}
 static void
pwm_set_duty(uint8_t duty)
{
     OCR0A = duty; // установить OCRnx
}
 static void
pwm_stop(void)
{
     TCCR0B &= ~((1<<CS02)|(1<<CS01)|(1<<CS00)); // остановить таймер
}
 int
main(void)
{
    uint8_t duty = 0;
     /* setup */
    pwm_init();
    pwm_set_frequency(N_1);
     /* loop */
    while (1) {
        pwm_set_duty(duty++);
        _delay_ms(100);
    }
}

Источник

Оставить комментарий

Ваш email нигде не будет показан. Обязательные для заполнения поля помечены *

*