Split from: 16 bit PWM

18 posts / 0 new
Author
Message

Hi, I have a problem. I use atmega328p and need changeable pwm signal. (example 150Hz-500Hz) Therefore, I use 16 bit pwm and choose "phase&frequency correct mode". My code:

DDRB|=(1<<PB1);
TCCR1A|=((1<<COM1A1));
TCCR1B|=(1<<WGM13);
TCCR1B|=(1<<CS10);

ICR1=53333;
OCR1A=15000;

This is not 150 hz. This is 150,00094 Hz.
ICR1 must be 53333,333333333... for 150Hz(fpwm=fmcu/2.ICR1, fmcu=16MHz) but this is impossible. I have a machine run with duty cycle on 150Hz.
I have another machine run with duty cycle on 500Hz, so I have to use microcontroller but how can I do changeable without a fraction frequency.

Last Edited: Wed. Jun 9, 2021 - 12:18 PM

Hello, and Welcome to AVR Freaks!

It really does not help anyone to add on to the end of an 11 year old thread.

As for your specific problem, what are you using as system clock? If you  expect 150.00000000... Hz and get 150.00094Hz, that is an error of (about) 6ppm = .0006% (I think that is the correct number of zeros). That is well within the accuracy of most crystals! What error do you expect?

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

how can I do changeable without a fraction frequency.

It should be very obvious you can use 15MHz:

15 MHz--->150 is dividing by exactly 100000

15 MHz--->500  is dividing by by exactly 30000

It up to you to use the prescalers, dividers, etc to set these divisions.  Of course a 0.001% xtal will give you a 0.001% result.

need changeable pwm signal. (example 150Hz-500Hz)

Why?  Mostly, you are typically concerned with the duty cycle, rather than freq (at least in a broad sense).  You can dim an led at 1 KHz or 1.11 KHz , makes little difference.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Wed. Jun 9, 2021 - 12:55 AM

It is not clear from your question,  but to make the point. "Variable frequency" with a timer PWM output is NOT smoothly variable. It goes in steps. That is because the frequency is controlled by counting registers that only take on integer values. Depending on the 16-bit count that you use, the main CPU clock frequency, and the prescale value, the frequency steps might be quite small or quite large.

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

ka7ehk wrote:
Hello, and Welcome to AVR Freaks!
Thanks bro.

ka7ehk wrote:
It really does not help anyone to add on to the end of an 11 year old thread.
Why? I didn't see answer of question anywhere.

ka7ehk wrote:
As for your specific problem, what are you using as system clock?
I wrote fmcu=16MHz.

ka7ehk wrote:
What error do you expect?
Machine does not accept if not 150Hz, example 150,0009375058594 is not  true for machine.

avrcandies wrote:
It should be very obvious you can use 15MHz
It's not 'obvious'. Another machine run with duty cycle on 995Hz, can I change xtal again? I can't change xtal for each different value.

avrcandies wrote:
You can dim an led at 1 KHz or 1.11 KHz
Led? Really? Leds are very simple things. I work with complex machines.

ka7ehk wrote:
That is because the frequency is controlled by counting registers that only take on integer values.
That's what I'm talking about too. For example there are some pwm generator modules. They can return integer values. Can't we create a phase and frequency corrected pwm from another pwm pin instead of the OC1A pin? It can be 8 bits instead of 16 bits.

ka7ehk wrote:

It really does not help anyone to add on to the end of an 11 year old thread.

Atxxx07 wrote:
Why?

because your question has nothing to do with the original, 10-year-old question.

Top Tips:

1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...

Atxxx07 wrote:

Machine does not accept if not 150Hz, example 150,0009375058594 is not  true for machine.

Do you really have a machine that measure 150.00000Hz to << 6.25ppm and considers 6.25ppm an error ?  What ppm does it need for a pass ?!

If that is really true, you will need TCXO at both ends, a simple crystal will not keep 6.25ppm over time and temperature.

Atxxx07 wrote:

Machine does not accept if not 150Hz, example 150,0009375058594 is not  true for machine.

Then you miss the Forum, for this one is for normal AVRs, normal oscillators and everything.

For this request only, you can try on (geo)physic forum, or CERN forum, guess.

Yet, if you think the frequency may be fine-tuned /in order to be accepted by machine/, then, yes,

it can be done. You may consider VCXO-driven AVR for this.

awneil wrote:

ka7ehk wrote:

It really does not help anyone to add on to the end of an 11 year old thread.

Atxxx07 wrote:
Why?

because your question has nothing to do with the original, 10-year-old question.

Hımm, ok bro, I understand, sorry.

Who-me wrote:

Atxxx07 wrote:

Machine does not accept if not 150Hz, example 150,0009375058594 is not  true for machine.

Do you really have a machine that measure 150.00000Hz to << 6.25ppm and considers 6.25ppm an error ?  What ppm does it need for a pass ?!

If that is really true, you will need TCXO at both ends, a simple crystal will not keep 6.25ppm over time and temperature.

Really? I don't know really. I generate pwm on pwm module(150Hz) and its working, but I generate 150.0009375058594Hz on atmega328p its dont work. And I wrote ICR1=53334 its not working, I wrote ICR1=53332 its not working. I'll look into TCXO, thank you.
grohote wrote:
Bunun için VCXO güdümlü AVR'yi düşünebilirsiniz.
I'll look into VCXO, thank you.

Thanks for your help. If I have opened the question in the wrong place, it does not need to be prolonged. Thank you for your answers, it's enough for me.

Atxxx07 wrote:

And I wrote ICR1=53334 its not working, I wrote ICR1=53332 its not working.

If I have opened the question in the wrong place...

Smash your coffee beans in avan, cook in dzezva, pour to fildzan, serve with a lump of secer and halva or rahat-lokum and, bujrum. (Sarajevo memories)

But, stay here, anything can be solved, including this 53332/4 problem.

Last Edited: Wed. Jun 9, 2021 - 09:48 AM

It has already been explained, if you need to generate both 150 Hz & 500 Hz EXACTLY, you should use 15 MHz, then the dividers are exact.

Another machine run with duty cycle on 995Hz, can I change xtal again? I can't change xtal for each different value.

Duty cycle is a percentage, not a frequency---you seem very confused about that.

Do you know exactly what duty cycles you need to generate?

I generate pwm on pwm module(150Hz) and its working, but I generate 150.0009375058594Hz on atmega328p its dont work.

That's an extremely unlikely fantasy situation;  it is more likely that there is some mistake, maybe in the hookup, such as grounding.  How do you measure the exact frequency being generated?---what calibrated frequency counter are you using?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Wed. Jun 9, 2021 - 11:23 AM

avrcandies wrote:

Duty cycle is a percentage, not a frequency---you seem very confused about that.

Do you know exactly what duty cycles you need to generate?

You didnt understand me. Let's say 'I use 15MHz xtal, and I generate 150Hz and 500Hz pwm signal', ok, but When I use 15MHz xtal, if I need to generate a 995Hz signal, I cannot change the xtali again. I told you; "How can I generate 995Hz pwm with 15MHz xtal." Of course I know frequency and duty cycle.

avrcandies wrote:
That's an extremely unlikely fantasy situation;  it is more likely that there is some mistake, maybe in the hookup, such as grounding.
I tried this code, but again don't work.

DDRB|=(1<<PB1);
TCCR1A|=((1<<COM1A1));
TCCR1B|=(1<<WGM13);
TCCR1B|=(1<<CS10);

ICR1=53340;
OCR1A=35000;

_delay_ms(1000);

ICR1=53339;
OCR1A=35000;

_delay_ms(1000);

.

.

.

.

ICR1=53325;
OCR1A=35000;

_delay_ms(1000);

Yes, it's ridiculous, but that's how it is.

avrcandies wrote:
what calibrated frequency counter are you using?
I have a measuring device that can measure frequency, but it is not needed because I can calculate the frequency as in the datasheet. I wrote before; fpwm=fmcu(xtal)/2.ICR1

Last Edited: Wed. Jun 9, 2021 - 12:18 PM

I have a measuring device that can measure frequency, but it is not needed because I can calculate the frequency as in the datasheet

That seems farfetched---- if you say things are working at 123.456789 Hz , but they are failing at 123.456722 Hz....how could you know what freq you are really getting?   At this small difference, with no measuring (or detailed oscillator specs) , it is a stab in the dark.

I can calculate that someone owes me 23 million dollars...I've done it 10 times, getting the same answer each time, but can't find the money.  I did find 5 dollars and half a bag of pretzels.

Do you know what freqs you actually need?  Perhaps a DDS chip is in your future?

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Atxxx07 wrote:

You didnt understand me. Let's say 'I use 15MHz xtal, and I generate 150Hz and 500Hz pwm signal', ok, but When I use 15MHz xtal, if I need to generate a 995Hz signal, I cannot change the xtali again. I told you; "How can I generate 995Hz pwm with 15MHz xtal." Of course I know frequency and duty cycle.

There is a trade off when using a chip with a simple timer like the '328. The timer prescaler has quite coarse steps with 'power-of-2'  ratios. And then you have only a 16-bit counter.

If you start with the desired frequency range of the output it is possible to work backwards to the required crystal frequency. However, you will find that you often can't get the exact frequency yo want, and certainly not the resolution you need. You can easily model the whole thing in a spreadsheet.

We've had a few questions like this and the answer is often that a chip like the 328 is not the right chip for the application because the timers a quite simple.

You might get more joy by implementing an NCO in software. Again, the success of such a thing will depend on EXACTLY what range of frequencies and what accuracy and resolution you need.

[EDIT]

If 150Hz, 500Hz, and 995Hz are your desired outputs then a 4.776MHz crystal will do it!

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

Last Edited: Wed. Jun 9, 2021 - 01:29 PM

What you are discovering is that traditional dividers are not a good way to generate arbitrary frequencies. Consider an 8-bit timer...

Change the division ration by one step from 1 to 2 and the output frequency changes by 50%

Change the division ration by one step from 254 to 255 and the output frequency changes by 0.0016% (if my maths is right!)

So at the lower frequency outputs the resolution is the worst, which is opposite to what you want.

#1 Hardware Problem? https://www.avrfreaks.net/forum/...

#3 All grounds are not created equal

#4 Have you proved your chip is running at xxMHz?

#5 "If you think you need floating point to solve the problem then you don't understand the problem. If you really do need floating point then you have a problem you do not understand."

So at the lower frequency outputs the resolution is the worst, which is opposite to what you want.

well NO, low freq is actually best, since the divide values will then be the highest (say divide by 7895, vs 7896  compared to divide by 12 vs 13)

If you want exact division enter all the freqs you need and find the least common multiple...that will show what divides down exactly.

For 150, 500, 995 the LCM is 298500  ...any multiple of this freq will divide down exactly.   4.776 MHz is 16x this freq.   It is up to you to use the timers, scalers, etc to create the divide number.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Atxxx07 wrote:

I have a measuring device that can measure frequency, but it is not needed because I can calculate the frequency as in the datasheet. I wrote before; fpwm=fmcu(xtal)/2.ICR1

Never assume.  you should always measure this to confirm.

Atxxx07 wrote:

.... Let's say 'I use 15MHz xtal, and I generate 150Hz and 500Hz pwm signal', ok, but When I use 15MHz xtal, if I need to generate a 995Hz signal, I cannot change the xtali again. I told you; "How can I generate 995Hz pwm with 15MHz xtal." Of course I know frequency and duty cycle.

If you really need a range of high precision PWMs, tighter than AVR granularity, then you may need to add a Si5351A Clock synthesizer, (or similar)  which lets you adjust the AVR clock via i2c config tables.

avrcandies wrote:
That's an extremely unlikely fantasy situation;  it is more likely that there is some mistake, maybe in the hookup, such as grounding.

Yes, it would be a very, very, rare design that was 6.25ppm paranoid !!  Far more likely is a finger problem....