[Newbe Question] Questions about PWM (atmega32U4)

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone,

I am pretty new in this microcontroller topic, but I need it for my studies.
In the lectures we are just scratching on the surface, and we kind of need to find out on ourselves how things should be done.

Well I am struggeling with the PWM. I think i kind of know how to initialize it, and how to set the clock, and set the PWM in the right mode.

But there are a few things I did not really understand. I found some codesnippets on how to set up a simple PWM for the atmega32U4, but there are some open questions still, and I hope you folks may could help me out.

So first of all:
I saw that the OCR0A Register (which should be set to the value you want to compare the counter with) gets set on every loop iteration in the main function.
Why should I do that? Isn´t the OCR0A Register "memorizing" or so to say "saving" the value, to constantily compare it with the counter value?

The other thing is, i know that for example, if the counter (TCNT0) and the OCR0A values match, i can generate a waveform output on the OC0A.
(Which i guess just means that it is true and false for a certain amount of time, depending on the PWM configurations).
I saw some people setting the DDRB Register, Pin7 to 1, so that it´s marked as an output?
Why should I do that? Is this one somehow "mapped" with the OC0A?

And if so, do I need to set it as an Input again, when I want to read it´s value?
And how can I map this to for example a servomotor? Do i need it manually, by reading the Value of OC0A, and always writing it´s Value to the
Port where my servomotor is connected?

As you see, I am pretty sure my questions are quite obvious, but i really have no idea on this topic, on electronics, and on how to deal with that.
(Guess thats why i have chosen the name pretty_clueless)

So if anyone of you could bring some light in the dark, i would really appreciate.

Thanks!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

pretty_clueless wrote:
I saw that the OCR0A Register (which should be set to the value you want to compare the counter with) gets set on every loop iteration in the main function. Why should I do that? Isn´t the OCR0A Register "memorizing" or so to say "saving" the value, to constantily compare it with the counter value?

Yes, OCR0A "memorizes" its configuration. The reason I see to configure it in the main loop, is to change its value in each iteration (or through any type of communication: serial, SPI, I2C, etc.), to modify the PWM duty cycle.

pretty_clueless wrote:
I saw some people setting the DDRB Register, Pin7 to 1, so that it´s marked as an output? Why should I do that? Is this one somehow "mapped" with the OC0A?

Some people use DDR to enable/disable the timer-handled "automatic" pin toggling, though the timer continues counting in "background".

pretty_clueless wrote:
And if so, do I need to set it as an Input again, when I want to read it´s value?

Yes, but why would you like to read a pin that's toggling at a defined rate?

 

Last Edited: Fri. Nov 10, 2017 - 07:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

pretty_clueless wrote:
I found some codesnippets on how to set up a simple PWM for the atmega32U4, but there are some open questions still

If you want to discuss or ask about specific code then it will be much easier if we can also look at the very same code, so

EITHER show code in a post here (preferred),

OR post URL/link to code in another location/site (less preferred).

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

casanovg wrote:
Yes, but why would you like to read a pin that's toggling at a defined rate?

 No! you can always read the state of a port pin using the PIN register, it does not make any difference if it is an input or output pin in the DDR.

Although you must wait one clock cycle after a change of state for it to show up in the PIN register.

 

Jim

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And how can I map this to for example a servomotor? Do i need it manually, by reading the Value of OC0A, and always writing it´s Value to the
Port where my servomotor is connected?

Welcome to the Forum.

 

Time for the big picture, I think. 

 

Lets say, for example, that your servo's position depended on the width of a pulse, and that that pulse was to be updated at least once every 20 mSec.

 

If the pulse width is 1.5 mSec then the servo is in "neutral", (centered), position.

If the pulse wide decreases, towards 1 mSec, the servo turns left, (CCW), rotation.

At 1 mSec, the servo is at its full left position.

 

If the pulse width increases, greater than 1.5 mSec, towards 2 mSec, then the servo turns to the right, (CW rotation).

With a 2 mSec pulse the servo is fully right.

 

So, you send it a never ending series of pulses and the servo positions itself based upon the pulse width.

 

You could do that in software, within the Main Loop, using delays, and it would work fine.

But it would tie up the micro and make it hard to get other work done.

 

You could send the pulses from the software using Interrupts.

That would be a better solution, as the micro could then process other tasks when it wasn't changing the state of the output pin to the servo.

(If one wants to use a small micro to simultaneously control a whole bunch of servos, then that would be a very reasonable approach.)

 

Now, option #3, use the Timer/Counter hardware module within the micro and let it to all of the pulse generation for you.

You configure (set up) the T/C for PWM, and then it will just, forever, send the pulses to the I/O pin to control the servo.

All the Main Loop program has to do now is send the T/C PWM module a new data value, for the width of the pulse, when it wants to change servo's position.

The micro is now free to spend the majority of its time doing other tasks.

 

When you configure the T/C you have to pick a PWM mode, (the T/C has many possible modes of operation, it is a complex module within the micro).

You set the incoming clock rate via a pre-scaler, (typically), and you set the repetition rate; that is how often the overall output period is repeated, in our example 20 mSec.

You then set the PWM value, i.e. the "duty cycle" of the pulse, (which can be from 0 % to 100 % on, (or high).

In our example you will set the duty cycle for a pulse width of between 1 and 2 mSec high, occurring within that 20 mSec slot.

You likely will also define the I/O pin as an output pin, although some micros may do that for you when you configure the PWM.

 

Now sit back, you don't have to read anything, or copy any values to the I/O pin, it all happens for you, controlled by the T/C module in PWM mode.

The software now only needs to send a new duty cycle value to the hardware when it wants to change the servo's position.

Otherwise the hardware just holds the servo at the last value it was given.

 

The data sheet has a section in the front with the pin out for the micro, and the signals available for the different pins are shown there.

There is also a table of the ports, pins, and functions in the back of the data sheet.

As you read the T/C hardware module's section, you will see which signals it can control, and then you look at the chip's pin out, (or the table), to see which physical pin on the chip you need to connect the servo control signal to.

 

A simple servo test program would configure the T/C for outputting the control signal, the PWM signal, and have two push buttons, one to increase the PWM duty cycle, (from 1.5 to 2 ms, increment by increment), and one to decrease the duty cycle, from 1.5 mSec down towards 1 mSec.

The result is one button turns the servo to the right, the other turns it to the left.

 

If you know how to connect an LCD and push buttons to the micro, the you can display the current duty cycle, or position angle, etc., as you watch the servo follow your commands.

 

Know that the required data repetition rate, (20 mSec in the example above), and the characteristics of the pulse signal, (minimum and maximum for the full range of the servo), can vary from servo to servo.

 

Having even a cheap, ("toy"), O'scope to watch the PWM output signal makes it much easier to debug your code, and to "see" what is taking place.

 

Good luck with your current task!

 

JC

 

Edit: Typos

Last Edited: Sun. Nov 12, 2017 - 06:29 PM