ШИМ на аttiny13a. Не полностью выключается светодиод.

fid
Offline
Зарегистрирован: 20.12.2014

Хотел сделать плавное включение и выключение СД ленты на аttiny13a. Пока эксперементирую на макетной плате с одним маленким светодиодом. Предполагаю применить аппаратный шим. Но я заметил при OCR0A=0x00 СД полностью не выключается.

#define F_CPU 1200000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int i;

int main(void)
{
    DDRB=0b1;
    PORTB=0x00;   
   TCCR0A=0x83;
   TCCR0B=0x01;
   OCR0A=0x00;
    sei();

    while (1)  
{
   
   for (i=0;i<255;i++)
    {
       OCR0A=i;
_delay_ms(5);
   }

_delay_ms(1000);

   for (i=255;i>0;i--){
       OCR0A=i;
    _delay_ms(5);
   }

_delay_ms(1000);

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

правильно. при 255 выключается.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

fid, если вы посмотрите в ардуиновскую функцию analogWrite, то увидите что значение 0 функция не передаёт в регистр OCR, а перехватывает и просто записывает в порт лог.0.

fid
Offline
Зарегистрирован: 20.12.2014

dimax, спасибо! работает! Но только не очень понятно если разрешить прерывание по переполнению TCNTO( TIMSK0=0b10) шим не работает. Хотел изменить логику работы СД . Плавно включается ,поработал некоторое время, плавно выключался. Отсчет временени на прерывание по переполнению TCNTO. Или отсчет времени как то по другому делается?

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

fid, насчёт "если разрешить.." давайте весь скетч где это прописано, но неработает, там много вариантов накосячить, -гадать не буду.

fid
Offline
Зарегистрирован: 20.12.2014

Вот так будет правильно? 

#define F_CPU 1200000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
bool F_led=0;
volatile unsigned long time=0;

ISR(TIM0_OVF_vect)
{time++; }


int main(void)
{
    DDRB=0b1;
    PORTB=0x00;   
  // TCCR0A=0x83;//10000011
  //TCCR0A=0b10000011;
   TCCR0B=0x01;
   OCR0A=0x00;
TIMSK0=0b10;
    sei();

    while (1)  
{
 if (!F_led)
     {    TCCR0A=0b10000011;  
         for (int i=0;i<255;i++)
         {
             OCR0A=i;
             _delay_ms(5);
         }
    F_led=1;
    DDRB |=0b1;
     }
       

    if (time>20000)
    {     
        for (int i=255;i>0;i--)
        {
            OCR0A=i;
            _delay_ms(5);
        }
        DDRB |=0b0;
        TCCR0A=0;
        _delay_ms(2000);// для теста
        time=0;
        F_led=0; 
     
    }

  
}
}

 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

fid, ошибка в 44 строке.

fid
Offline
Зарегистрирован: 20.12.2014

Спасибо dimax! Нужно PORTB |= 0;

Моя ошибка была в том,что в примерах для начинающих обычно конфигурационные регистры устанавливаются один раз в начале и дальше в цикле не меняются. Вот я и ошибочно предполагал, что их часто не стоит перезаписывать как и EEPROM 

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

fid пишет:

Спасибо dimax! Нужно PORTB |= 0;

Нет, опять неправильно. Я могу конечно написать как надо, но лучше будет если вы самостоятельно поймёте в чём тут ошибка.