gpt4 book ai didi

timer - 如何设置16位P&F校正PWM中Timer1的频率和占空比

转载 作者:行者123 更新时间:2023-12-02 20:30:21 27 4
gpt4 key购买 nike

我正在使用 328P(在内部 8mhz 上运行)来生成大约 111K hz 或 120K hz 的方波,并具有可调节的占空比。

我对这种级别的硬件操作相当陌生,所以请原谅我的无知,我花了 3 天在网上和数据表中查找,但恐怕我对首字母缩略词和缩写词含义的理解仍然太有限。

到目前为止,我在网上和数据表中进行研究后得出了以下代码。但我觉得我错过了一些东西,在(数据表 20.12.5)相位和频率校正 PWM 模式中,哪个寄存器操纵频率,哪个寄存器操纵占空比?

void setup(){
DDRB |= (1 << DDB1); //Set PB1 as output
OCR1A = (Unsure of what TOP should be here);
TCCR1A = (1 << WGM10) | (1 << COM1B0) | (1 << COM1A0);
TCCR1B = (1 << CS10) | (1 << WGM13);
}
void loop(){
//manipulate duty cycle with other code here
}

我错过了什么或者我应该在这里采取什么不同的做法?我尝试使用在线 AVR Timer Calc 来帮助我获取该频率所需的时钟滴答声。它表示,在没有预分频器和 16 位定时器的情况下,总共 72 个定时器滴答声将产生 111Khz(近似)方波。跳转到 73 或 71 会使频率超出所需范围。有什么办法可以让 AVR 更接近这个目标吗?

最佳答案

经过与我的一位同样是 EE 并从事嵌入式系统工作的 friend 一起进行大量研究后,我们找到了从 328p 中获得我所需的最佳解决方案。我将在下面为任何感兴趣并需要类似内容的人发布解决方案。

void setup() {
// put your setup code here, to run once:
//Set Timer1 for around 109Khz signal
cli();//stop interrupts
TCCR1A = 0;// set entire TCCR1A register to 0
TCCR1B = 0;// same for TCCR1B
TCNT1 = 0;//initialize counter value to 0
//Set register bits
TCCR1A = _BV(COM1A1) | _BV(WGM11);
TCCR1B = _BV(CS10) | _BV(WGM12) | _BV(WGM13);
ICR1 = 73; // frequency = 8000000/73 = 109.589 kHz
OCR1A = 0; //0% Duty Cycle or Full Off.
sei();//allow interrupts
}

void loop() {
// put your main code here, to run repeatedly:
OCR1A = 36; //50% Duty Cycle 73/2 = 36.5 Can be changed as needed.
}

此代码设置定时器 1 的寄存器,因此它不会干扰 Arduino 库中的毫秒或其他定时函数。无论如何,我需要操纵一个特定的引脚,PB1 (OC1A)(或 Arduino 数字引脚 9)是它会振荡的引脚。

您可以根据一些简单的数学将 ICR1 更改为您需要的任何值,您的时钟频率除以计数器的值等于产生的近似频率。 OCR1A 设置信号的占空比。

您的确切频率受到限制,但对于我的需求来说,这还可以。我仍然能够用它来驱动我正在使用的传感器。

这是对最初问题的快速回答,并允许我更改占空比作为奖励。我不记得我们设置的寄存器的确切信息,当我有时间时,我将使用数据表中的相关信息更新此答案。

关于timer - 如何设置16位P&F校正PWM中Timer1的频率和占空比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48961016/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com