Я пытаюсь сделать пульт дистанционного управления RGB LED подсветкой с помощью ATtiny13A.
Я знаю, что ATtiny85 лучше подходит для этой цели, и я знаю, что в конечном итоге я не смогу уместить весь код, но сейчас моя главная задача - сгенерировать программный ШИМ с использованием прерываний в режиме CTC.
Я не могу работать в любом другом режиме (для быстрой ШИМ с исключением , OCR0A
как , TOP
так как код ИК - приемник Я использую потребности частоту 38 кГц , который он генерирует , используя КТК и который является в основном то же самое) OCR0A=122
.
Так что я пытаюсь (и я видел , как люди упоминают об этом в Интернете) использовать Output Compare A
и Output Compare B
прерывание для создания программного обеспечения PWM.
OCR0A
, который также используется ИК-кодом, определяет частоту, которая меня не волнует. И OCR0B
определяет рабочий цикл ШИМ, который я буду использовать для изменения цвета светодиодов.
Я ожидаю, что смогу получить ШИМ с рабочим циклом 0-100%, изменив OCR0B
значение с 0
на OCR0A
. Это мое понимание того, что должно произойти:
Но на самом деле происходит следующее (это из симуляции Proteus ISIS):
Как вы можете видеть ниже, я могу получить около 25% -75% рабочего цикла, но для ~ 0-25% и ~ 75-100% форма волны просто застревает и не меняется.
ЖЕЛТАЯ линия: Аппаратный ШИМ
RED line: программный ШИМ с фиксированным рабочим циклом
ЗЕЛЕНАЯ линия: Программное обеспечение ШИМ с переменным рабочим циклом
И вот мой код:
#ifndef F_CPU
#define F_CPU (9600000UL) // 9.6 MHz
#endif
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
int main(void)
{
cli();
TCCR0A = 0x00; // Init to zero
TCCR0B = 0x00;
TCCR0A |= (1<<WGM01); // CTC mode
TCCR0A |= (1<<COM0A0); // Toggle OC0A on compare match (50% PWM on PINB0)
// => YELLOW line on oscilloscope
TIMSK0 |= (1<<OCIE0A) | (1<<OCIE0B); // Compare match A and compare match B interrupt enabled
TCCR0B |= (1<<CS00); // Prescalar 1
sei();
DDRB = 0xFF; // All ports output
while (1)
{
OCR0A = 122; // This is the value I'll be using in my main program
for(int i=0; i<OCR0A; i++)
{
OCR0B = i; // Should change the duty cycle
_delay_ms(2);
}
}
}
ISR(TIM0_COMPA_vect){
PORTB ^= (1<<PINB3); // Toggle PINB3 on compare match (50% <SOFTWARE> PWM on PINB3)
// =>RED line on oscilloscope
PORTB &= ~(1<<PINB4); // PINB4 LOW
// =>GREEN line on oscilloscope
}
ISR(TIM0_COMPB_vect){
PORTB |= (1<<PINB4); // PINB4 HIGH
}
OCR0A
используется ИК-код, поэтому у меня есть только OCR0B
. Я пытаюсь использовать его для генерации программного ШИМ на 3 выводах без ШИМ.