我正在尝试使用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晶体和电容器,并且ATMega328上的20 MHz时钟工作可靠。在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模式?
在我的原始查询中添加一个特定的“赏金”问题:
因此,我需要对上面的代码进行哪些更改,以使其在引脚9和11处以16 MHz时钟的最高可能频率给出完全反相的信号,是否那是不是2 MHz?
我现在将继续使用标准的Arduino Uno,以便我的本地调试板不会引入任何错误模式,因此具有arduino的任何人都可以尝试上面的代码,并确认它可以像我之前提到的那样工作,而不是像我所说的那样工作。需要!