我正在尝试使用 Atmel AVR 微控制器的 Timer1(Arduino 中使用的 AtMega328 或 ATTiny85)来输出两个相互镜像的时钟信号。我试图生成的频率是 1 MHz 到 2 MHz 或更高的变量,这太高了,无法使用代码来切换输出引脚,除非我几乎不想在控制器中做任何其他事情。所以我想直接在相关引脚上使用定时器输出。我正在使用 GCC 工具链,因此不受 arduino 库或语言的限制。
Atmega328 中的 Timer1 有两个与之关联的引脚,我可以从中得到两个相同的 1MHz 到 2MHz 信号。虽然数据表似乎说我可以得到一个倒置的波形,但这让我很困惑。使用 Timer1 的 PWM 设置,我还能够在 1 MHz 处获得两个占空比不同的信号,但两个信号同时变高,较短的信号变低。这不适合我的项目。我什至不需要 PWM 脉冲宽度变化,我只需要两个相同的“时钟”类型的反相信号,仅此而已。
我不是要求任何人为我编写代码来执行此操作,我只需要有人告诉我定时器的哪些模式/标志应该在与定时器相关的两个引脚之一上给我一个简单的反相波形。如果可能的话,我想避免对其中一个输出使用外部反相电路,除非那是唯一的选择。
如果这在 ATTiny 中完全可行,那就更好了。ATTiny 也有 2 个引脚与一个计时器相关联,但我不确定它是否具有与 ATMega 相同的选项。
我已经在 PCB 上连接了一个 20 MHz 晶体和电容器,并且 20 MHz 时钟在 ATMega328 上可靠地工作。在 ATtiny85 PCB 上,我有一个 8 MHz 晶体,它也可以可靠地工作。
请帮忙。谢谢你。
更新:到目前为止,答案和评论中有一些无效的假设,所以也许我应该澄清一下:请注意,在我原来的帖子中,我已经声明我使用的是 20 MHz 时钟,而不是 8 MHz,而且我不需要 PWM .
提供足够高输出频率的唯一模式似乎是CTC 模式,因为 PWM 模式不适用于 2 MHz 输出。有没有办法在 CTC 模式下反转定时器 1 输出 A 或输出 B?
我现在已经切换到标准的 Arduino Uno(ATMega328,16 MHz)而不是我自己的 20 MHz 板来检查我的代码,这是我的代码,用于在 CTC 模式下从引脚 9 和 10 获得稳定的 2 MHz 时钟,定时器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 模式下似乎没有任何作用。我是不是读错了数据表,还是我最终会被迫使用较低的频率和 PWM 模式?
要在我的原始查询中添加一个特定的“赏金”问题:
那么我需要对上面的代码进行哪些更改,以使其在16 MHz 时钟的最高频率下在引脚 9 和 11 上提供完美反相的信号,无论是那是2 MHz还是不是?
我现在将坚持使用标准的 Arduino Uno,这样我的土布板就不会引入错误模式,因此任何拥有 arduino 的人都可以尝试我上面的代码并确认它是否像我提到的那样工作,而不是像我说的那样工作需要!