Я пытаюсь использовать Timer1 микроконтроллера Atmel AVR, либо AtMega328, который используется в Arduino, либо ATTiny85, для вывода двух тактовых сигналов, которые являются зеркальным отображением друг друга. Частота, которую я пытаюсь сгенерировать, - это переменная от 1 МГц до 2 МГц или более, которые слишком высоки, чтобы делать это с помощью кода для переключения выходных контактов, если я не хочу почти ничего делать в контроллере. Поэтому я хочу использовать выход таймера непосредственно на соответствующих выводах. Я использую GCC toolchain, поэтому он не ограничен библиотеками Arduino или языком.
Timer1 в Atmega328 имеет два контакта, связанных с ним, и я могу получить два идентичных сигнала от 1 МГц до 2 МГц из них. Несмотря на то, что таблица данных говорит, что я могу получить инвертированную форму волны, это сбивает меня с толку. Я также могу получить два сигнала с разными рабочими циклами на частоте 1 МГц, используя настройки ШИМ с таймером 1, но оба сигнала одновременно повышаются, а более низкий - раньше. Это не служит моему проекту. Мне даже не нужно изменение ширины импульса ШИМ, мне просто нужны два идентичных сигнала «тактового» типа противоположной фазы, вот и все.
Я не прошу, чтобы кто-нибудь написал код, чтобы я сделал это, мне просто нужно, чтобы кто-то сказал мне, какой режим / флаги таймера должен дать мне простой инвертированный сигнал на одном из двух контактов, связанных с таймером. Если возможно, я хочу избегать использования внешней инвертирующей цепи для одного из выходов, если только это не вариант.
Если это вообще возможно в ATTiny, это будет еще лучше. ATTiny также имеет 2 контакта, связанных с одним таймером, но я не уверен, что он имеет те же опции, что и ATMega.
У меня уже есть 20 МГц кристалл и конденсаторы, подключенные к печатной плате, а 20 МГц часы надежно работают на ATMega328. На плате ATTiny85 у меня кристалл 8 МГц, и он тоже работает надежно.
Пожалуйста помоги. Спасибо.
ОБНОВЛЕНИЕ : В ответах и комментариях есть некоторые неверные предположения, поэтому, возможно, я должен уточнить: Обратите внимание, что в своем первоначальном посте я заявил, что я использую тактовую частоту 20 МГц, а не 8 МГц , а также что мне не нужен ШИМ ,
Единственный режим, который дает достаточно высокую выходную частоту, кажется, режим CTC, потому что режимы ШИМ не работают для выхода 2 МГц. Есть ли способ инвертировать либо выход A таймера 1, либо выход B в режиме CTC?
Теперь я переключился на стандартную Arduino Uno (ATMega328, 16 МГц) вместо моей собственной платы на 20 МГц, чтобы проверить мой код, и это мой код для хороших устойчивых часов 2 МГц в режиме CTC с выводов 9 и 10, таймер 1 вывод выводов:
#define tick 9
#define tock 10
void setup() {
pinMode(tick, OUTPUT);
pinMode(tock, OUTPUT);
TCCR1A = _BV(COM1A0) | _BV(COM1B0) ; // activate both output pins
TCCR1B = _BV(WGM12)| 1; // set CTC mode, prescaler mode 1
// various frustrating attempts to invert OC1B failed. What do I put here?
OCR1A = 3; // set the counter max for 2 MHz
}
void loop() {
}
Следы осциллографа для обоих выводов идентичны и синхронно, как я могу получить один из двух инвертированных сигналов? Режим инвертирования в техническом описании ничего не делает в режиме CTC. Я неправильно читаю таблицу данных или мне все равно придется использовать более низкую частоту и режим ШИМ?
Чтобы добавить конкретный вопрос о «вознаграждении» в мой исходный запрос:
какие изменения мне нужно внести в мой код выше, чтобы он давал идеально инвертированные сигналы на контактах 9 и 11 на максимально возможной частоте для тактовой частоты 16 МГц , будь то это 2 МГц или нет?
Сейчас я буду придерживаться стандартного Arduino Uno, чтобы на моей панели homespun не было режима ошибок и чтобы любой, у кого есть arduino, мог попробовать мой код выше и подтвердить, что он работает так, как я упоминал, а не так, как я. необходимость!
Ответы:
Из таблицы ATtiny85:
Таблица 11-5 показывает, как установить режим.
Вам нужен режим Fast PWM (режим 3 или 7). Если вы хотите изменить рабочий цикл, и он звучит так, как вы, вам нужен режим 7 и изменить рабочий цикл, установив OCRA.
В таблице 11-3 показано, как установить выходной режим сравнения для режима быстрой ШИМ.
То есть вы можете установить выход OC0A на низкий уровень, когда значение таймера == OCR0A, и высокий уровень, когда значение таймера == 0x00, установив COM0A1: COM0A0 = 0b10. Или наоборот, установив COM0A1: COM0A0 = 0b11. И аналогично для OC0B, OCR0B, COM0B0, COM0B1.
Частота ШИМ определяется тактовой частотой входов / выходов (8 МГц, как вам кажется) и настройкой прескалера таймера. И уравнение задается как f_clk_IO / (N * 256) для режима быстрой ШИМ.
Таким образом, вы можете использовать OC0A для «нормальной» полярности и OC0B для «инвертированной» полярности, установив OCR0A и OCR0B на одно и то же значение и установив COM0A1: COM0A0 = 0b10 и COM0B1: COM0B0 на 0b11.
ОБНОВИТЬ
Если вы хотите максимально быстро переключить выход и используете Mega328, работающий с частотой 16 МГц, режим работы CTC позволит вам получить частоту переключения:
f_OCnA = f_clk_IO / (2 * N * [1 + OCRnA) = 16e6 / (2 * 1 * [1 + 1]) = 4 МГц
Режим Fast PWM позволит вам переключать контакт в:
f_OCnxPWM = f_clk_IO / (N * [1 + TOP]) = 16e6 / (1 * [1 + 1]) = 8 МГц
Поэтому я все еще думаю, что вы хотите быстрый режим ШИМ. В частности, режим 3 с OCR0A = OCR0B = 0x80 для рабочего цикла 50%. И установите биты COM0A на 0x3 и биты COM0B на 0x2, чтобы сделать две формы сигнала на инверсиях OC0A и OC0B друг друга.
Обновление # 2 Больше Mega328 Попробуйте этот код Arduino:
источник
Семейство ATtinyX5 имеет PLL внутри, используйте его большой мальчик.
Я использую внутренний PLL для питания тактовой частоты процессора тоже и 16 МГц без XTAL. Это очень ценно, так как у вас всего 5 пинов. (Я не считаю пин-код сброса). Также один PLL'-PWM (OCR1B) работает на выводах XTAL с дополнительным дополнительным выходом. Вам просто нужно настроить предохранители для 16 МГц Xtalless ATtiny ... Или просто позволить процессору работать на 8 МГц, но запустить ШИМ с тактовой частотой 64 МГц без замены предохранителей ..
Вы можете иметь тактовую частоту до 64 МГц (но с разрешением 1 бит). Или 125 кГц при разрешении 8 бит. Вы можете уменьшить разрешение ШИМ и увеличить скорость с помощью уменьшения регистра OCR1C.
Для 1 МГц вам нужно установить OCR1C на 63. Для 2 МГц вам нужно установить OCR1C на 31. Для 4 МГц вам нужно установить OCR1C на 15. ...
Просто включите PLL с этим кодом:
Теперь у вас есть тактовые частоты 64 МГц на ШИМ "OCR1B0 / OCR1A0".
Кроме того, вы можете настроить OCR1 [A / B] 0 и XOCR1 [A / B] 0 для зеркального вывода.
Вы должны знать, что Dead Time Generator съест PWM вне, если вы установите OCR1A = 1. Вам нужны более высокие значения, чем мертвое время.
С Уважением,
Erdem
источник