Вопрос таймера: фазовая корректировка ШИМ на определенной частоте
Я пытаюсь создать синусоидальную волну, сегментированную в 64 кадрах, каждый из которых имеет рабочий цикл, точно изменяющийся от 0x00 до 0xff. Это для Arduino Nano.
Мне трудно понять следующее:
- Какой режим генератора волн и какие совпадения вызовут прерывание при постоянном кадре, а также помогут выполнить корректную по фазе/быструю ШИМ для изменяющегося рабочего цикла? ли>
- Как определить, какой пин использовать? Я предполагаю, что OC0B означает Pin5 в соответствии с сопоставлением контактов, но я не уверен, что правильно понимаю.
Это то, что у меня есть на данный момент.
const byte waveFrame = 126;
const byte wave[] = {
0x80,0x98,/*a total of 64 values*/,0x67
};
byte frame = 0;
void setup(){
pinMode(3,OUTPUT);
noInterrupts();
TCCR0A = (1<< WGM00) // ШИМ с корректной фазой с вершиной как OCR0A
| (1<<COM0A0) // Переключить OC0A при совпадении
| (1<<COM0B1); // Очистить/установить OC0B при сравнении совпадений при счете вверх/вниз.
TCCR0B = (1<< CS01); // Предварительный делитель 8 (16 МГц/8 = 2 МГц)
TCNT0 = 0; // Счетчик перезапущен
OCR0A = waveFrame; // Постоянная частота/64 для каждого кадра
OCR0B = 0; // Рабочий цикл
interrupts();
}
ISR(TIMER2_COMPA_vect){
OCR0B = wave[frame & 0x3f]; // Катается
frame++;
}
Спасибо! Я потерял немного волос из-за этого.
@B7th, 👍2
Обсуждение1 ответ
Лучший ответ:
pinMode(3,ВЫВОД);
Контакт 3 на Nano — OC2B
. Его ШИМ контролируется Таймером 2. Вы
хотите использовать контакт 5 (OC0B
), поскольку вы используете таймер 0. Или
переключиться на Таймер 2.
ШИМ с правильной фазой и вершиной как OCR0A
Обратите внимание, что это описание режима 5. Если вам нужен этот режим,
необходимо установить оба бита WGM00
в TCCR0A
(что вы и сделали)
и бит WGM02
в TCCR0B
(чего вы не сделали). Здесь вы установили
режим 1: корректная по фазе ШИМ с вершиной = 0xff.
Не уверен, почему я не подтвердил это тогда. Спасибо! Это помогло изрядно!, @B7th
- генерировать два сдвинутых по фазе ШИМ-импульса, запускаемых внешним сигналом с частотным разделением, с помощью Arduino uno?
- ATmega328P - проблема с использованием таймера 2 для генерации тона
- Мега: присоединение Interrupt на выводе 18/19/20/21 не работает
- Прерывание таймера срабатывает слишком часто
- Генерация комплементарного ШИМ с внешним триггером с помощью Arduino Due
- Использование millis() и micros() внутри процедуры прерывания
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
Вы уверены, что ваш Attiny работает на частоте 16 МГц? Выходной контакт — это контакт OC0B, который является контактом 6 на ATTiny45. Не уверен, почему вы используете сопоставление выводов ATMega644P. Пожалуйста, сообщите нам, какой процессор вы на самом деле используете, потому что упоминается три., @Gerben
Спасибо, Гербен, я удалил комментарий относительно ATTiny, поскольку он не имел отношения к описанной здесь проблеме. Я действительно использую ATMega Arduino Nano., @B7th
OC0B находится на контакте 5 Arduino. Похоже, ваш код также включает вывод на OC0A, который является контактом 6 Arduino, что дает вам фиксированные 50% -ные рабочие циклы. Что очень полезно, когда вы отлаживаете что-то и подключаете его к осциллографу или логическому анализатору. РЕДАКТИРОВАТЬ Не обращайте внимания на эту последнюю часть, если вы действительно хотите использовать режим формы волны 1., @Gerben
Вам нужен режим генерации сигнала 5. Это ШИМ, Фаза Правильно, но с TOP, являющимся значением OCR0A вместо 255. Для режима 5 вам необходимо установить оба бита WGM00 и WGM02. Обратите внимание, что бит WGM02 находится в регистре TCCR0B., @Gerben