简体   繁体   English

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

[英]How to set frequency and duty cycle of Timer1 in 16bit P&F correct PWM

I am using a 328P (Running on the internal 8mhz) to generate a Square wave at around 111K hz or 120K hz with and adjustable duty cycle. 我正在使用328P(在内部8mhz上运行)以大约111K hz或120K hz生成方波,并且占空比可调。

I'm fairly new to doing this level of hardware manipulation so please excuse my ignorance, I spent 3 days looking online and in the datasheet but I'm afraid my understanding of what the acronyms and abbreviations mean is still too limited. 我对进行这种级别的硬件操作还很陌生,所以请原谅我的无知,我花了3天的时间在网上和数据表中进行查找,但我对首字母缩写词和缩写的含义仍然了解有限。

So far I have come up with the following code after doing the research online and in the datasheet. 到目前为止,在网上和数据表中进行研究后,我已经提出了以下代码。 But I feel like I'm missing something, What register manipulates frequency and what register manipulates duty cycle in (Datasheet 20.12.5) Phase and Frequency Correct PWM Mode? 但是我感觉好像丢失了什么,在(Datasheet 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
}

What am I missing or what should I be doing differently here? 我想念什么,或者在这里应该做些什么? I tried to use the online AVR Timer Calc to help me get clock ticks needed for that frequency. 我试图使用在线AVR Timer Calc来帮助我获得该频率所需的时钟滴答。 It says a total of 72 Timer ticks with no prescaler and 16 bit timer would yield a 111Khz (approximate) Square wave. 它说总共72个没有预分频器的定时器滴答和16位定时器将产生111Khz(近似)方波。 Jumping to 73 or 71 jumps the frequency too much out of the desired range. 跳到73或71会使频率跳到期望范围之外。 is there any way to get that closer on an AVR? 有什么方法可以使AVR更接近吗?

In the title, you asked "ATMega328P How to set TIMER1 PWM Frequency". 在标题中,您询问“ ATMega328P如何设置TIMER1 PWM频率”。 You tune the frequency by setting the TOP value to what you want it to be. 您可以通过将TOP值设置为所需的值来调整频率。 A smaller TOP value means the counter reaches TOP sooner, so the frequency is higher. TOP值越小,意味着计数器越早到达TOP,因此频率越高。 The prescaler and clock source you use for the timer determines how fast it counts up, so that also affects the frequency, what ranges of frequencies are possible, and the resolution you get for setting the frequency. 用于计时器的预分频器和时钟源决定其递增计数的速度,因此也会影响频率,可能的频率范围以及设置频率的分辨率。 Your TOP value also determines how much resolution you have when setting the duty cycle, since the duty cycle should be an integer less than or equal to TOP. 您的TOP值还决定了设置占空比时的分辨率,因为占空比应为小于或等于TOP的整数。

Near the bottom of your post, you asked "is there any way to get that closer on an AVR?" 在帖子底部附近,您问“有什么方法可以使AVR更加接近?” Since your AVR is running at 8 MHz, every frequency you can generate with its timers will be of the form (8 MHz)/N, where N is some integer. 由于您的AVR以8 MHz运行,因此您可以使用其计时器生成的每个频率都将具有(8 MHz)/ N的形式,其中N是一个整数。 That's because the timers can't do anything or change anything between ticks of the clock source you are supplying to them. 这是因为计时器在您提供给它们的时钟源的滴答声之间无法执行任何操作或更改任何内容。 Timer 1 will get a clock tick 8 times per microsecond, and each time that clock tick happens it can advance its count and/or control a PWM pin and/or fire an interrupt. 计时器1每微秒将获得8次时钟滴答,并且每次发生时钟滴答时,它可以增加其计数和/或控制PWM引脚和/或触发中断。 I think you already figured this out using the online AVR timer calculator. 我想您已经使用在线AVR计时器计算器解决了这一问题。 Here are some of the achievable PWM frequencies you can get on an AVR running at 8 MHz: 以下是在8 MHz运行的AVR上可以获得的一些PWM频率:

  • 8000 kHz / 73 = 109.6 kHz 8000 kHz / 73 = 109.6 kHz
  • 8000 kHz / 72 = 111.1 kHz 8000 kHz / 72 = 111.1 kHz
  • 8000 kHz / 71 = 112.7 kHz 8000 kHz / 71 = 112.7 kHz

If you need more precise frequency tuning, you need to get a faster clock source in your system one way or another. 如果需要更精确的频率调谐,则需要以一种或另一种方式在系统中获得更快的时钟源。 You could get a faster microcontroller or maybe figure out how to supply a faster clock as an input to a timer on the microcontroller. 您可以获得更快的微控制器,或者弄清楚如何提供更快的时钟作为微控制器上定时器的输入。

After a lot of research along side a friend of mine who is also an EE and works with embedded systems we came to find the best solution for getting what I needed out of the 328p. 经过与我的一位朋友(也是一位EE,并且与嵌入式系统一起工作)的大量研究,我们找到了从328p中获得我所需要的最佳解决方案。 I will post the solution below for anyone who is interested and needs something similar. 我将在下面将解决方案发布给有兴趣并且需要类似东西的任何人。

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.
}

This code sets the registers for Timer 1 so it shouldn't interfere with millis or other timing functions in the Arduino libraries. 这段代码设置了定时器1的寄存器,因此它不会干扰Arduino库中的毫秒或其他计时功能。 I needed to manipulate a specific pin anyways and PB1 (OC1A) (or Arduino digital pin 9) is the pin that this will oscillate. 无论如何,我都需要操纵一个特定的引脚,而PB1(OC1A)(或Arduino数字引脚9)是将要振荡的引脚。

You can change ICR1 to any value you need based on some simple math, Your clock frequency divided by the value of the counter equals the approximate frequency produced. 您可以根据一些简单的数学运算将ICR1更改为所需的任何值。您的时钟频率除以计数器的值等于产生的近似频率。 OCR1A sets the duty cycle of the signal. OCR1A设置信号的占空比。

You are limited in the exact frequency but for my needs this worked out OK. 您的确切频率受到限制,但对于我的需求,可以解决。 I was still able to use it to drive the transducer I was using. 我仍然能够使用它来驱动我正在使用的传感器。

This was a quick answer to the initial problem and allows me to change the duty cycle as a bonus. 这是对最初问题的快速解答,使我可以改变工作周期作为奖励。 I don't remember the exact information on the registers we set, When I have time I will update this answer with the info from the data sheet pertaining to that. 我不记得我们设置的寄存器的确切信息,如果有时间,我将使用数据表中与之相关的信息来更新此答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM