Перейти к содержанию
    

van1

Новичок
  • Постов

    3
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный
  1. Кстати, спасибо, ШИМ действительно ровная получается. но это, к сожалению, все равно не ответ на вопрос, почему программная ШИМ не ровная. пока грешу на тактовую частоту.
  2. А тогда вопрос: почему analogWrite для Attiny шумит, а для UNO гораздо меньше? Не в тактовой частоте ли дело?
  3. Доброе время суток. Есть такая проблема. Сделал ПИД-регулятор на ардуино Уно: светодиод на ШИМ плюс фоторезистор. Управление таймером. Все ок, работает. Решил перейти на Attiny45. Всё перенес, и вижу, что работать-то работает, но сигнал нестабилен. Путем проб выяснил, что контроллер выдает плохую (нестабильную) ШИМ. Написал свою ШИМ по известному алгоритму (таймер плюс прямое управлени портами). И все бы хорошо, да все равно ШИМ плохая. Предположил, что я как-то не так программирую таймер - не выдает он у меня 256-8000000/1/8000000 = 255 на Timer1, а выдает гораздо меньше. Перешел на Attiny 84. А там еще хуже. Как ни бился, мне не удалось получить от таймеров (обоих) высокочастотное тактирование. И OVF и СOMPA пробовал. Вероятно, я что-то делаю не так. Само собой, даташиты курил. имена регистров пишу без ошибок. Но, походу, глобально что-то забываю/не понимаю, т.к. опыт имею не шибко большой. Возможно, какие-то биты не пишу из нужных, возможно, вообще задаю непрвильный режим работы таймера. Повторюсь, основная проблема в ом, что таймеры тактирубтся на более низких частотах. чем мне надо, т.е. светодиодик мигает не достаточно быстро для полноценной ШИМ. Может быть кто-то программировал таймеры на Attiny45/84 и поделится добрым советом или кусочком кода? И второй вопрос: как еще можно получить качественную ШИМ, без мелких биений вокруг level (аналог функции analogWrite(pin, level))? Пример для Attiny45 (OVF или COMPA на выбор): //Если можете ответить на вопросы выше без прочтения кода, то не забивайте им голову:) void initTimer0() { noInterrupts(); DDRB = (1 << PB4); TCCR0A = 0; TCCR0B = 0; timer0_counter = 255;//256-(int)(8000000/8/1000000); //Должен мигать на 1000000 Гц TCNT0 = timer0_counter; //OVF // TCNT0 = 0; //COMPA // OCR0A = timer0_counter; //COMPA TCCR0B |= (1<<CS01); // 8 prescaler // TCCR0B |= (1 << CS02);//256 //TCCR0B |= (1 << CS02) | (1 << CS00); //1024 TIMSK |= (1 << TOIE0); //OVF // TIMSK |= (1<< OCIE0A); //COMPA interrupts(); } ISR(TIMER0_OVF_vect) //ISR(TIMER0_COMPA_vect) { TCNT0 = timer0_counter; // OVF preload timer //digitalWrite(4, !digitalRead(4)); } void initTimer1() { timer1_counter = 255; //256-(int)(8000000/1024/7812); // Должен мигать на 7812 Гц noInterrupts(); // disable all interrupts DDRB = (1 << PB4); TCCR1 = 0; TCNT1=0; /// OCR1A=timer1_counter; OCR1A=timer1_counter; //timer_counter //TCCR1 |= (1 << CS13) | (1 << CS10); // 256 // TCCR1 |= (1 << CS12); //8 TCCR1 |= (1 << CS10); //1 // TCCR1 |= (1 << CS13) | (1 << CS11) | (1 << CS10); //1024 TIMSK |= (1 << OCIE1A); // TIMSK |= (1 << OCIE1B); interrupts(); } ISR(TIMER1_COMPA_vect) { if (counter == 0) { buf_lev_ch1 = lev_ch1; PORTB |=(1<<PB4); } if (counter == buf_lev_ch1) PORTB&=~(1<<PB4); counter++; if (counter == 10) counter = 0; } Для Attiny84: void initTimer1() { //sreg = SREG; noInterrupts(); DDRB = (1 << PB2); TCCR0A = 0; TCCR0B = 0; // TCCR1B |= (1<<WGM12);//COMPA timer1_counter = 65536-(int)(8000000/1/8000000); TCNT1 = timer1_counter; //OVF // TCNT1 = 0; //COMPA // OCR1A = timer1_counter; //COMPA TCCR1B |= (1 << CS02) ; //256 // TCCR1B |= (1<<CS10); // 1 prescaler TIMSK1 |= (1 << TOIE0); //OVF // TIMSK1 |= (1<< OCIE1A); //COMPA //SREG = sreg; interrupts(); } ISR(TIM1_OVF_vect) //ISR(TIM1_COMPA_vect) { TCNT1 = timer1_counter; // OVF preload timer digitalWrite(2, !digitalRead(2)); }
×
×
  • Создать...